From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Fri, 22 Oct 2021 16:25:07 -0700 Subject: [PATCH] Add exploded block state to BlockExplodeEvent and EntityDamageByBlockEvent diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSource.java b/src/main/java/net/minecraft/world/damagesource/DamageSource.java index ec52c7a75d9988475fbb4fe12ef7f4489ef3d894..a78fd4f9ce97ebece45979908382de8f5fc14c1b 100644 --- a/src/main/java/net/minecraft/world/damagesource/DamageSource.java +++ b/src/main/java/net/minecraft/world/damagesource/DamageSource.java @@ -21,6 +21,7 @@ public class DamageSource { private final Entity directEntity; @Nullable private final Vec3 damageSourcePosition; + public org.bukkit.block.BlockState explodedBlockState; // Paper - add exploded state // CraftBukkit start @Nullable private org.bukkit.block.Block directBlock; // The block that caused the damage. damageSourcePosition is not used for all block damages @@ -94,6 +95,7 @@ public class DamageSource { private DamageSource cloneInstance() { DamageSource damageSource = new DamageSource(this.type, this.directEntity, this.causingEntity, this.damageSourcePosition); + damageSource.explodedBlockState = this.explodedBlockState; // Paper - Include explodedBlockState when clone this instance of DamageSource damageSource.directBlock = this.getDirectBlock(); damageSource.withSweep = this.isSweep(); damageSource.poison = this.isPoison(); diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSources.java b/src/main/java/net/minecraft/world/damagesource/DamageSources.java index 2f5591aa232b834bb9b69a2a349ce93d1a9c63fa..8ba60de95845f4d56f299c5f1b2b5163461ba38d 100644 --- a/src/main/java/net/minecraft/world/damagesource/DamageSources.java +++ b/src/main/java/net/minecraft/world/damagesource/DamageSources.java @@ -265,8 +265,17 @@ public class DamageSources { return this.source(DamageTypes.SONIC_BOOM, attacker); } + @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - add exploded state public DamageSource badRespawnPointExplosion(Vec3 position) { - return new DamageSource(this.damageTypes.getHolderOrThrow(DamageTypes.BAD_RESPAWN_POINT), position); + // Paper start - add exploded state + return this.badRespawnPointExplosion(position, null); + } + + public DamageSource badRespawnPointExplosion(Vec3 position, @Nullable org.bukkit.block.BlockState explodedBlockState) { + DamageSource source = new DamageSource(this.damageTypes.getHolderOrThrow(DamageTypes.BAD_RESPAWN_POINT), position); + source.explodedBlockState = explodedBlockState; + return source; + // Paper end - add exploded state } public DamageSource outOfBorder() { diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java index aa81144975fa66bcdb3d107e2a461b6d62d8e59e..fbd1f4f3a8c94a4842f91b7cc6c21f0cf7edd7ac 100644 --- a/src/main/java/net/minecraft/world/level/Explosion.java +++ b/src/main/java/net/minecraft/world/level/Explosion.java @@ -386,7 +386,7 @@ public class Explosion { bukkitBlocks = event.blockList(); this.yield = event.getYield(); } else { - BlockExplodeEvent event = new BlockExplodeEvent(location.getBlock(), blockList, this.yield); + BlockExplodeEvent event = new BlockExplodeEvent(location.getBlock(), blockList, this.yield, this.damageSource.explodedBlockState); // Paper - add exploded state this.level.getCraftServer().getPluginManager().callEvent(event); this.wasCanceled = event.isCancelled(); bukkitBlocks = event.blockList(); diff --git a/src/main/java/net/minecraft/world/level/block/BedBlock.java b/src/main/java/net/minecraft/world/level/block/BedBlock.java index 03035ed3df2f32e14a8eb9bc3d536ef64b5d87ba..872bec4c366c86177334452315cc4a8097dae3c0 100644 --- a/src/main/java/net/minecraft/world/level/block/BedBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BedBlock.java @@ -95,6 +95,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock // CraftBukkit - moved world and biome check into EntityHuman if (false && !BedBlock.canSetSpawn(world)) { + final org.bukkit.block.BlockState explodedBlockState = org.bukkit.craftbukkit.block.CraftBlockStates.getUnplacedBlockState(world, pos, state); // Paper - add exploded state (this won't be called due to the false, but it's good for reference) world.removeBlock(pos, false); BlockPos blockposition1 = pos.relative(((Direction) state.getValue(BedBlock.FACING)).getOpposite()); @@ -104,7 +105,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock Vec3 vec3d = pos.getCenter(); - world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); + world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // Paper - add exploded state return InteractionResult.SUCCESS; } else if ((Boolean) state.getValue(BedBlock.OCCUPIED)) { if (!this.kickVillagerOutOfBed(world, pos)) { @@ -146,6 +147,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock private InteractionResult explodeBed(BlockState iblockdata, Level world, BlockPos blockposition) { { { + final org.bukkit.block.BlockState explodedBlockState = org.bukkit.craftbukkit.block.CraftBlockStates.getUnplacedBlockState(world, blockposition, iblockdata); // Paper - add exploded state world.removeBlock(blockposition, false); BlockPos blockposition1 = blockposition.relative(((Direction) iblockdata.getValue(BedBlock.FACING)).getOpposite()); @@ -155,7 +157,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock Vec3 vec3d = blockposition.getCenter(); - world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); + world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // Paper - add exploded state return InteractionResult.SUCCESS; } } diff --git a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java index a4a90df0b500fb440226b07462faaa87594b12a5..c389e2f891655bd8c9f307057dc1ad62dfcbc79e 100644 --- a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java +++ b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java @@ -133,6 +133,7 @@ public class RespawnAnchorBlock extends Block { } private void explode(BlockState state, Level world, final BlockPos explodedPos) { + final org.bukkit.block.BlockState explodedBlockState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(explodedPos, state, null); // Paper - add exploded state world.removeBlock(explodedPos, false); Stream stream = Direction.Plane.HORIZONTAL.stream(); // CraftBukkit - decompile error @@ -149,7 +150,7 @@ public class RespawnAnchorBlock extends Block { }; Vec3 vec3d = explodedPos.getCenter(); - world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d), explosiondamagecalculator, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); + world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), explosiondamagecalculator, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // Paper - add exploded state } public static boolean canSetSpawn(Level world) { diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java index 411c2de93c71e480f95229c882cdf43b8801edc8..489c17d002a5c3580637fda1c51f1bd63814bfa0 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java @@ -291,6 +291,12 @@ public final class CraftBlockStates { BlockEntity tileEntity = (blockEntityTag == null) ? null : BlockEntity.loadStatic(blockPosition, blockData, blockEntityTag, registry); return CraftBlockStates.getBlockState(null, blockPosition, blockData, tileEntity); } + // Paper start - add exploded state + public static BlockState getUnplacedBlockState(net.minecraft.world.level.BlockGetter levelAccessor, BlockPos blockPos, net.minecraft.world.level.block.state.BlockState blockData) { + BlockEntity tileEntity = levelAccessor.getBlockEntity(blockPos); + return CraftBlockStates.getBlockState(null, blockPos, blockData, tileEntity); + } + // Paper end - add exploded state // See BlockStateFactory#createBlockState(World, BlockPosition, IBlockData, TileEntity) private static CraftBlockState getBlockState(World world, BlockPos blockPosition, net.minecraft.world.level.block.state.BlockState blockData, BlockEntity tileEntity) { diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index c52cb55cd1da988ec646e4e1484ec1a72513291d..a226b7cdc9c63ef09d7d48269c287af1ab6dbdc4 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -1070,7 +1070,7 @@ public class CraftEventFactory { Entity damager = (bukkitDamageSource.isIndirect() && source.getDirectEntity() != null) ? source.getDirectEntity() : source.getCausingEntity(); if (source.is(DamageTypeTags.IS_EXPLOSION)) { if (damager == null) { - return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled); + return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.explodedBlockState); // Paper - Include BlockState for damage } DamageCause damageCause = (damager.getBukkitEntity() instanceof org.bukkit.entity.TNTPrimed) ? DamageCause.BLOCK_EXPLOSION : DamageCause.ENTITY_EXPLOSION; return CraftEventFactory.callEntityDamageEvent(damager, entity, damageCause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.isCritical()); // Paper - add critical damage API @@ -1117,7 +1117,7 @@ public class CraftEventFactory { } else { throw new IllegalStateException(String.format("Unhandled damage of %s by %s from %s", entity, source.getDirectBlock(), source.getMsgId())); } - return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled); + return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.explodedBlockState); // Paper - Include BlockState for damage } DamageCause cause; @@ -1170,8 +1170,13 @@ public class CraftEventFactory { return CraftEventFactory.callEntityDamageEvent(event, damagee, cancelled); } - private static EntityDamageEvent callEntityDamageEvent(Block damager, Entity damagee, DamageCause cause, org.bukkit.damage.DamageSource bukkitDamageSource, Map modifiers, Map> modifierFunctions, boolean cancelled) { - EntityDamageByBlockEvent event = new EntityDamageByBlockEvent(damager, damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions); + // Paper start + private static EntityDamageEvent callEntityDamageEvent(Block damager, Entity damagee, DamageCause cause, org.bukkit.damage.DamageSource bukkitDamageSource, Map modifiers, Map> modifierFunctions, boolean cancelled) { // Paper + return callEntityDamageEvent(damager, damagee, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, null); + } + private static EntityDamageEvent callEntityDamageEvent(Block damager, Entity damagee, DamageCause cause, org.bukkit.damage.DamageSource bukkitDamageSource, Map modifiers, Map> modifierFunctions, boolean cancelled, @Nullable org.bukkit.block.BlockState explodedBlockState) { + EntityDamageByBlockEvent event = new EntityDamageByBlockEvent(damager, damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions, explodedBlockState); + // Paper end return CraftEventFactory.callEntityDamageEvent(event, damagee, cancelled); }