#1390: Improve internal handling of damage sources

By: Doc <nachito94@msn.com>
This commit is contained in:
CraftBukkit/Spigot 2024-05-04 08:15:51 +10:00
parent f01e218606
commit 066665a979
12 changed files with 72 additions and 48 deletions

View file

@ -1,6 +1,6 @@
--- a/net/minecraft/world/damagesource/DamageSource.java --- a/net/minecraft/world/damagesource/DamageSource.java
+++ b/net/minecraft/world/damagesource/DamageSource.java +++ b/net/minecraft/world/damagesource/DamageSource.java
@@ -21,6 +21,88 @@ @@ -21,6 +21,103 @@
private final Entity directEntity; private final Entity directEntity;
@Nullable @Nullable
private final Vec3D damageSourcePosition; private final Vec3D damageSourcePosition;
@ -8,19 +8,19 @@
+ @Nullable + @Nullable
+ private org.bukkit.block.Block directBlock; // The block that caused the damage. damageSourcePosition is not used for all block damages + private org.bukkit.block.Block directBlock; // The block that caused the damage. damageSourcePosition is not used for all block damages
+ @Nullable + @Nullable
+ public org.bukkit.block.BlockState blockState; // The block state of the block relevant to this damage source + private org.bukkit.block.BlockState directBlockState; // The block state of the block relevant to this damage source
+ private boolean withSweep = false; + private boolean sweep = false;
+ private boolean melting = false; + private boolean melting = false;
+ private boolean poison = false; + private boolean poison = false;
+ private Entity customCausingEntity = null; // This field is a helper for when causing entity damage is not set by vanilla + private Entity customEntityDamager = null; // This field is a helper for when causing entity damage is not set by vanilla
+ +
+ public DamageSource sweep() { + public DamageSource sweep() {
+ this.withSweep = true; + this.sweep = true;
+ return this; + return this;
+ } + }
+ +
+ public boolean isSweep() { + public boolean isSweep() {
+ return this.withSweep; + return this.sweep;
+ } + }
+ +
+ public DamageSource melting() { + public DamageSource melting() {
@ -41,18 +41,18 @@
+ return this.poison; + return this.poison;
+ } + }
+ +
+ public Entity getCausingEntity() { + public Entity getDamager() {
+ return (this.customCausingEntity != null) ? this.customCausingEntity : this.causingEntity; + return (this.customEntityDamager != null) ? this.customEntityDamager : this.directEntity;
+ } + }
+ +
+ public DamageSource customCausingEntity(Entity entity) { + public DamageSource customEntityDamager(Entity entity) {
+ // This method is not intended for change the causing entity if is already set + // This method is not intended for change the causing entity if is already set
+ // also is only necessary if the entity passed is not the direct entity or different from the current causingEntity + // also is only necessary if the entity passed is not the direct entity or different from the current causingEntity
+ if (this.customCausingEntity != null || this.directEntity == entity || this.causingEntity == entity) { + if (this.customEntityDamager != null || this.directEntity == entity || this.causingEntity == entity) {
+ return this; + return this;
+ } + }
+ DamageSource damageSource = this.cloneInstance(); + DamageSource damageSource = this.cloneInstance();
+ damageSource.customCausingEntity = entity; + damageSource.customEntityDamager = entity;
+ return damageSource; + return damageSource;
+ } + }
+ +
@ -77,10 +77,25 @@
+ return damageSource; + return damageSource;
+ } + }
+ +
+ public org.bukkit.block.BlockState getDirectBlockState() {
+ return this.directBlockState;
+ }
+
+ public DamageSource directBlockState(org.bukkit.block.BlockState blockState) {
+ if (blockState == null) {
+ return this;
+ }
+ // Cloning the instance lets us return unique instances of DamageSource without affecting constants defined in DamageSources
+ DamageSource damageSource = this.cloneInstance();
+ damageSource.directBlockState = directBlockState;
+ return damageSource;
+ }
+
+ private DamageSource cloneInstance() { + private DamageSource cloneInstance() {
+ DamageSource damageSource = new DamageSource(this.type, this.directEntity, this.causingEntity, this.damageSourcePosition); + DamageSource damageSource = new DamageSource(this.type, this.directEntity, this.causingEntity, this.damageSourcePosition);
+ damageSource.directBlock = this.getDirectBlock(); + damageSource.directBlock = this.getDirectBlock();
+ damageSource.withSweep = this.isSweep(); + damageSource.directBlockState = this.getDirectBlockState();
+ damageSource.sweep = this.isSweep();
+ damageSource.poison = this.isPoison(); + damageSource.poison = this.isPoison();
+ damageSource.melting = this.isMelting(); + damageSource.melting = this.isMelting();
+ return damageSource; + return damageSource;

View file

@ -33,21 +33,32 @@
public DamageSource inFire() { public DamageSource inFire() {
return this.inFire; return this.inFire;
} }
@@ -250,7 +266,17 @@ @@ -242,7 +258,13 @@
}
public DamageSource explosion(@Nullable Entity entity, @Nullable Entity entity1) {
- return this.source(entity1 != null && entity != null ? DamageTypes.PLAYER_EXPLOSION : DamageTypes.EXPLOSION, entity, entity1);
+ // CraftBukkit start
+ return this.explosion(entity, entity1, entity1 != null && entity != null ? DamageTypes.PLAYER_EXPLOSION : DamageTypes.EXPLOSION);
+ }
+
+ public DamageSource explosion(@Nullable Entity entity, @Nullable Entity entity1, ResourceKey<DamageType> resourceKey) {
+ return this.source(resourceKey, entity, entity1);
+ // CraftBukkit end
}
public DamageSource sonicBoom(Entity entity) {
@@ -250,7 +272,13 @@
} }
public DamageSource badRespawnPointExplosion(Vec3D vec3d) { public DamageSource badRespawnPointExplosion(Vec3D vec3d) {
- return new DamageSource(this.damageTypes.getHolderOrThrow(DamageTypes.BAD_RESPAWN_POINT), vec3d); - return new DamageSource(this.damageTypes.getHolderOrThrow(DamageTypes.BAD_RESPAWN_POINT), vec3d);
+ // CraftBukkit start + // CraftBukkit start
+ return badRespawnPointExplosion(vec3d, null, null, null); + return badRespawnPointExplosion(vec3d, null);
+ } + }
+ +
+ public DamageSource badRespawnPointExplosion(Vec3D vec3d, net.minecraft.world.level.World world, net.minecraft.world.level.block.state.IBlockData blockData, net.minecraft.core.BlockPosition position) { + public DamageSource badRespawnPointExplosion(Vec3D vec3d, org.bukkit.block.BlockState blockState) {
+ DamageSource damageSource = new DamageSource(this.damageTypes.getHolderOrThrow(DamageTypes.BAD_RESPAWN_POINT), vec3d); + return new DamageSource(this.damageTypes.getHolderOrThrow(DamageTypes.BAD_RESPAWN_POINT), vec3d).directBlockState(blockState);
+ if (world != null && blockData != null && position != null) {
+ damageSource.blockState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(world, position, blockData, null);
+ }
+ return damageSource;
+ // CraftBukkit end + // CraftBukkit end
} }

View file

@ -776,7 +776,7 @@
+ return; + return;
+ } + }
+ +
+ if (!this.hurt(this.damageSources().lightningBolt().customCausingEntity(entitylightning), 5.0F)) { + if (!this.hurt(this.damageSources().lightningBolt().customEntityDamager(entitylightning), 5.0F)) {
+ return; + return;
+ } + }
+ // CraftBukkit end + // CraftBukkit end

View file

@ -15,7 +15,7 @@
@Override @Override
public void thunderHit(WorldServer worldserver, EntityLightning entitylightning) { public void thunderHit(WorldServer worldserver, EntityLightning entitylightning) {
- this.hurt(this.damageSources().lightningBolt(), Float.MAX_VALUE); - this.hurt(this.damageSources().lightningBolt(), Float.MAX_VALUE);
+ this.hurt(this.damageSources().lightningBolt().customCausingEntity(entitylightning), Float.MAX_VALUE); // CraftBukkit + this.hurt(this.damageSources().lightningBolt().customEntityDamager(entitylightning), Float.MAX_VALUE); // CraftBukkit
} }
@Override @Override

View file

@ -65,7 +65,7 @@
this.dead = true; this.dead = true;
- this.level().explode(this, this.getX(), this.getY(), this.getZ(), (float) this.explosionRadius * f, World.a.MOB); - this.level().explode(this, this.getX(), this.getY(), this.getZ(), (float) this.explosionRadius * f, World.a.MOB);
- this.discard(); - this.discard();
+ this.level().explode(this, net.minecraft.world.level.Explosion.getDefaultDamageSource(this.level(), this).customCausingEntity(this.entityIgniter), null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), World.a.MOB); // CraftBukkit + this.level().explode(this, this.level().damageSources().explosion(this, this.entityIgniter, net.minecraft.world.damagesource.DamageTypes.EXPLOSION), null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), World.a.MOB); // CraftBukkit
+ this.discard(EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause + this.discard(EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause
this.spawnLingeringCloud(); this.spawnLingeringCloud();
+ // CraftBukkit start + // CraftBukkit start

View file

@ -1,12 +1,11 @@
--- a/net/minecraft/world/entity/projectile/EntityEnderPearl.java --- a/net/minecraft/world/entity/projectile/EntityEnderPearl.java
+++ b/net/minecraft/world/entity/projectile/EntityEnderPearl.java +++ b/net/minecraft/world/entity/projectile/EntityEnderPearl.java
@@ -18,6 +18,14 @@ @@ -18,6 +18,13 @@
import net.minecraft.world.phys.MovingObjectPosition; import net.minecraft.world.phys.MovingObjectPosition;
import net.minecraft.world.phys.MovingObjectPositionEntity; import net.minecraft.world.phys.MovingObjectPositionEntity;
+// CraftBukkit start +// CraftBukkit start
+import org.bukkit.Bukkit; +import org.bukkit.Bukkit;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.entity.EntityRemoveEvent;
+import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.event.player.PlayerTeleportEvent;
@ -15,7 +14,7 @@
public class EntityEnderPearl extends EntityProjectileThrowable { public class EntityEnderPearl extends EntityProjectileThrowable {
public EntityEnderPearl(EntityTypes<? extends EntityEnderPearl> entitytypes, World world) { public EntityEnderPearl(EntityTypes<? extends EntityEnderPearl> entitytypes, World world) {
@@ -54,23 +62,34 @@ @@ -54,23 +61,34 @@
EntityPlayer entityplayer = (EntityPlayer) entity; EntityPlayer entityplayer = (EntityPlayer) entity;
if (entityplayer.connection.isAcceptingMessages() && entityplayer.level() == this.level() && !entityplayer.isSleeping()) { if (entityplayer.connection.isAcceptingMessages() && entityplayer.level() == this.level() && !entityplayer.isSleeping()) {
@ -57,13 +56,13 @@
- entity.hurt(this.damageSources().fall(), 5.0F); - entity.hurt(this.damageSources().fall(), 5.0F);
+ entityplayer.connection.teleport(teleEvent.getTo()); + entityplayer.connection.teleport(teleEvent.getTo());
+ entity.resetFallDistance(); + entity.resetFallDistance();
+ entity.hurt(this.damageSources().fall().customCausingEntity(this), 5.0F); // CraftBukkit + entity.hurt(this.damageSources().fall().customEntityDamager(this), 5.0F); // CraftBukkit
+ } + }
+ // CraftBukkit end + // CraftBukkit end
this.level().playSound((EntityHuman) null, this.getX(), this.getY(), this.getZ(), SoundEffects.PLAYER_TELEPORT, SoundCategory.PLAYERS); this.level().playSound((EntityHuman) null, this.getX(), this.getY(), this.getZ(), SoundEffects.PLAYER_TELEPORT, SoundCategory.PLAYERS);
} }
} else if (entity != null) { } else if (entity != null) {
@@ -78,7 +97,7 @@ @@ -78,7 +96,7 @@
entity.resetFallDistance(); entity.resetFallDistance();
} }
@ -72,7 +71,7 @@
} }
} }
@@ -88,7 +107,7 @@ @@ -88,7 +106,7 @@
Entity entity = this.getOwner(); Entity entity = this.getOwner();
if (entity instanceof EntityPlayer && !entity.isAlive() && this.level().getGameRules().getBoolean(GameRules.RULE_ENDER_PEARLS_VANISH_ON_DEATH)) { if (entity instanceof EntityPlayer && !entity.isAlive() && this.level().getGameRules().getBoolean(GameRules.RULE_ENDER_PEARLS_VANISH_ON_DEATH)) {
@ -81,7 +80,7 @@
} else { } else {
super.tick(); super.tick();
} }
@@ -100,7 +119,7 @@ @@ -100,7 +118,7 @@
public Entity changeDimension(WorldServer worldserver) { public Entity changeDimension(WorldServer worldserver) {
Entity entity = this.getOwner(); Entity entity = this.getOwner();

View file

@ -25,7 +25,7 @@
if (entityliving.isAlive() && !entityliving.isInvulnerable() && entityliving != entityliving1) { if (entityliving.isAlive() && !entityliving.isInvulnerable() && entityliving != entityliving1) {
if (entityliving1 == null) { if (entityliving1 == null) {
- entityliving.hurt(this.damageSources().magic(), 6.0F); - entityliving.hurt(this.damageSources().magic(), 6.0F);
+ entityliving.hurt(this.damageSources().magic().customCausingEntity(this), 6.0F); // CraftBukkit + entityliving.hurt(this.damageSources().magic().customEntityDamager(this), 6.0F); // CraftBukkit
} else { } else {
if (entityliving1.isAlliedTo((Entity) entityliving)) { if (entityliving1.isAlliedTo((Entity) entityliving)) {
return; return;

View file

@ -28,7 +28,7 @@
public static DamageSource getDefaultDamageSource(World world, @Nullable Entity entity) { public static DamageSource getDefaultDamageSource(World world, @Nullable Entity entity) {
return world.damageSources().explosion(entity, getIndirectSourceEntityInternal(entity)); return world.damageSources().explosion(entity, getIndirectSourceEntityInternal(entity));
@@ -86,17 +100,18 @@ @@ -86,7 +100,7 @@
this.hitPlayers = Maps.newHashMap(); this.hitPlayers = Maps.newHashMap();
this.level = world; this.level = world;
this.source = entity; this.source = entity;
@ -37,11 +37,7 @@
this.x = d0; this.x = d0;
this.y = d1; this.y = d1;
this.z = d2; this.z = d2;
this.fire = flag; @@ -97,6 +111,7 @@
this.blockInteraction = explosion_effect;
- this.damageSource = damagesource == null ? world.damageSources().explosion(this) : damagesource;
+ this.damageSource = damagesource == null ? world.damageSources().explosion(this).customCausingEntity(entity) : damagesource.customCausingEntity(entity); // CraftBukkit - handle source entity
this.damageCalculator = explosiondamagecalculator == null ? this.makeDamageCalculator(entity) : explosiondamagecalculator;
this.smallExplosionParticles = particleparam; this.smallExplosionParticles = particleparam;
this.largeExplosionParticles = particleparam1; this.largeExplosionParticles = particleparam1;
this.explosionSound = holder; this.explosionSound = holder;
@ -144,7 +140,7 @@
+ this.yield = event.getYield(); + this.yield = event.getYield();
+ } else { + } else {
+ org.bukkit.block.Block block = location.getBlock(); + org.bukkit.block.Block block = location.getBlock();
+ org.bukkit.block.BlockState blockState = (damageSource.blockState != null) ? damageSource.blockState : block.getState(); + org.bukkit.block.BlockState blockState = (damageSource.getDirectBlockState() != null) ? damageSource.getDirectBlockState() : block.getState();
+ BlockExplodeEvent event = new BlockExplodeEvent(block, blockState, blockList, this.yield); + BlockExplodeEvent event = new BlockExplodeEvent(block, blockState, blockList, this.yield);
+ this.level.getCraftServer().getPluginManager().callEvent(event); + this.level.getCraftServer().getPluginManager().callEvent(event);
+ this.wasCanceled = event.isCancelled(); + this.wasCanceled = event.isCancelled();

View file

@ -27,7 +27,7 @@
if (entityhuman_enumbedresult.getMessage() != null) { if (entityhuman_enumbedresult.getMessage() != null) {
entityhuman.displayClientMessage(entityhuman_enumbedresult.getMessage(), true); entityhuman.displayClientMessage(entityhuman_enumbedresult.getMessage(), true);
} }
@@ -123,8 +133,29 @@ @@ -123,8 +133,30 @@
} }
} }
@ -35,6 +35,7 @@
+ private EnumInteractionResult explodeBed(IBlockData iblockdata, World world, BlockPosition blockposition) { + private EnumInteractionResult explodeBed(IBlockData iblockdata, World world, BlockPosition blockposition) {
+ { + {
+ { + {
+ org.bukkit.block.BlockState blockState = org.bukkit.craftbukkit.block.CraftBlock.at(world, blockposition).getState(); // CraftBukkit - capture BlockState before remove block
+ world.removeBlock(blockposition, false); + world.removeBlock(blockposition, false);
+ BlockPosition blockposition1 = blockposition.relative(((EnumDirection) iblockdata.getValue(BlockBed.FACING)).getOpposite()); + BlockPosition blockposition1 = blockposition.relative(((EnumDirection) iblockdata.getValue(BlockBed.FACING)).getOpposite());
+ +
@ -44,7 +45,7 @@
+ +
+ Vec3D vec3d = blockposition.getCenter(); + Vec3D vec3d = blockposition.getCenter();
+ +
+ world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, world, iblockdata, blockposition), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, World.a.BLOCK); // CraftBukkit - add state + world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, blockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, World.a.BLOCK); // CraftBukkit - add state
+ return EnumInteractionResult.SUCCESS; + return EnumInteractionResult.SUCCESS;
+ } + }
+ } + }
@ -58,7 +59,7 @@
} }
private boolean kickVillagerOutOfBed(World world, BlockPosition blockposition) { private boolean kickVillagerOutOfBed(World world, BlockPosition blockposition) {
@@ -323,6 +354,11 @@ @@ -323,6 +355,11 @@
BlockPosition blockposition1 = blockposition.relative((EnumDirection) iblockdata.getValue(BlockBed.FACING)); BlockPosition blockposition1 = blockposition.relative((EnumDirection) iblockdata.getValue(BlockBed.FACING));
world.setBlock(blockposition1, (IBlockData) iblockdata.setValue(BlockBed.PART, BlockPropertyBedPart.HEAD), 3); world.setBlock(blockposition1, (IBlockData) iblockdata.setValue(BlockBed.PART, BlockPropertyBedPart.HEAD), 3);

View file

@ -9,9 +9,11 @@
world.playSound((EntityHuman) null, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, SoundEffects.RESPAWN_ANCHOR_SET_SPAWN, SoundCategory.BLOCKS, 1.0F, 1.0F); world.playSound((EntityHuman) null, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, SoundEffects.RESPAWN_ANCHOR_SET_SPAWN, SoundCategory.BLOCKS, 1.0F, 1.0F);
return EnumInteractionResult.SUCCESS; return EnumInteractionResult.SUCCESS;
} }
@@ -129,14 +129,14 @@ @@ -128,15 +128,16 @@
}
private void explode(IBlockData iblockdata, World world, final BlockPosition blockposition) { private void explode(IBlockData iblockdata, World world, final BlockPosition blockposition) {
+ org.bukkit.block.BlockState blockState = org.bukkit.craftbukkit.block.CraftBlock.at(world, blockposition).getState(); // CraftBukkit - capture BlockState before remove block
world.removeBlock(blockposition, false); world.removeBlock(blockposition, false);
- Stream stream = EnumDirection.EnumDirectionLimit.HORIZONTAL.stream(); - Stream stream = EnumDirection.EnumDirectionLimit.HORIZONTAL.stream();
+ Stream<EnumDirection> stream = EnumDirection.EnumDirectionLimit.HORIZONTAL.stream(); // CraftBukkit - decompile error + Stream<EnumDirection> stream = EnumDirection.EnumDirectionLimit.HORIZONTAL.stream(); // CraftBukkit - decompile error
@ -26,12 +28,12 @@
@Override @Override
public Optional<Float> getBlockExplosionResistance(Explosion explosion, IBlockAccess iblockaccess, BlockPosition blockposition1, IBlockData iblockdata1, Fluid fluid) { public Optional<Float> getBlockExplosionResistance(Explosion explosion, IBlockAccess iblockaccess, BlockPosition blockposition1, IBlockData iblockdata1, Fluid fluid) {
return blockposition1.equals(blockposition) && flag1 ? Optional.of(Blocks.WATER.getExplosionResistance()) : super.getBlockExplosionResistance(explosion, iblockaccess, blockposition1, iblockdata1, fluid); return blockposition1.equals(blockposition) && flag1 ? Optional.of(Blocks.WATER.getExplosionResistance()) : super.getBlockExplosionResistance(explosion, iblockaccess, blockposition1, iblockdata1, fluid);
@@ -144,7 +144,7 @@ @@ -144,7 +145,7 @@
}; };
Vec3D vec3d = blockposition.getCenter(); Vec3D vec3d = blockposition.getCenter();
- world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d), explosiondamagecalculator, vec3d, 5.0F, true, World.a.BLOCK); - world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d), explosiondamagecalculator, vec3d, 5.0F, true, World.a.BLOCK);
+ world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, world, iblockdata, blockposition), explosiondamagecalculator, vec3d, 5.0F, true, World.a.BLOCK); // CraftBukkit - add state + world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, blockState), explosiondamagecalculator, vec3d, 5.0F, true, World.a.BLOCK); // CraftBukkit - add state
} }
public static boolean canSetSpawn(World world) { public static boolean canSetSpawn(World world) {

View file

@ -41,13 +41,13 @@ public class CraftDamageSource implements DamageSource {
@Override @Override
public org.bukkit.entity.Entity getCausingEntity() { public org.bukkit.entity.Entity getCausingEntity() {
net.minecraft.world.entity.Entity entity = this.getHandle().getCausingEntity(); net.minecraft.world.entity.Entity entity = this.getHandle().getEntity();
return (entity != null) ? entity.getBukkitEntity() : null; return (entity != null) ? entity.getBukkitEntity() : null;
} }
@Override @Override
public org.bukkit.entity.Entity getDirectEntity() { public org.bukkit.entity.Entity getDirectEntity() {
net.minecraft.world.entity.Entity entity = this.getHandle().getDirectEntity(); net.minecraft.world.entity.Entity entity = this.getHandle().getDamager();
return (entity != null) ? entity.getBukkitEntity() : null; return (entity != null) ? entity.getBukkitEntity() : null;
} }
@ -65,7 +65,7 @@ public class CraftDamageSource implements DamageSource {
@Override @Override
public boolean isIndirect() { public boolean isIndirect() {
return this.getHandle().getCausingEntity() != this.getHandle().getDirectEntity(); return this.getHandle().getEntity() != this.getHandle().getDamager();
} }
@Override @Override

View file

@ -939,7 +939,7 @@ public class CraftEventFactory {
private static EntityDamageEvent handleEntityDamageEvent(Entity entity, DamageSource source, Map<DamageModifier, Double> modifiers, Map<DamageModifier, Function<? super Double, Double>> modifierFunctions, boolean cancelled) { private static EntityDamageEvent handleEntityDamageEvent(Entity entity, DamageSource source, Map<DamageModifier, Double> modifiers, Map<DamageModifier, Function<? super Double, Double>> modifierFunctions, boolean cancelled) {
CraftDamageSource bukkitDamageSource = new CraftDamageSource(source); CraftDamageSource bukkitDamageSource = new CraftDamageSource(source);
Entity damager = (bukkitDamageSource.isIndirect() && source.getDirectEntity() != null) ? source.getDirectEntity() : source.getCausingEntity(); Entity damager = (source.getDamager() != null) ? source.getDamager() : source.getEntity();
if (source.is(DamageTypeTags.IS_EXPLOSION)) { if (source.is(DamageTypeTags.IS_EXPLOSION)) {
if (damager == null) { if (damager == null) {
return callEntityDamageEvent(source.getDirectBlock(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled); return callEntityDamageEvent(source.getDirectBlock(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled);