SPIGOT-7967, #887: Call explode events for EXPLODE effect (enchantments) and non block changes (mobGriefing false)
This commit is contained in:
parent
03a8c14939
commit
c16b696e41
@ -0,0 +1,11 @@
|
|||||||
|
--- a/net/minecraft/world/item/enchantment/effects/ExplodeEffect.java
|
||||||
|
+++ b/net/minecraft/world/item/enchantment/effects/ExplodeEffect.java
|
||||||
|
@@ -40,7 +40,7 @@
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private DamageSource getDamageSource(Entity entity, Vec3D vec3d) {
|
||||||
|
- return this.damageType.isEmpty() ? null : (this.attributeToUser ? new DamageSource((Holder) this.damageType.get(), entity) : new DamageSource((Holder) this.damageType.get(), vec3d));
|
||||||
|
+ return this.damageType.isEmpty() ? (entity == null ? null : entity.level().damageSources().explosion(null).customCausingEntityDamager(entity)) : (this.attributeToUser ? new DamageSource((Holder) this.damageType.get(), entity) : new DamageSource((Holder) this.damageType.get(), vec3d)); // CraftBukkit - copy from explosion default damagesource to allow tracking entity behind the effect
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
@ -1,6 +1,6 @@
|
|||||||
--- a/net/minecraft/world/level/ServerExplosion.java
|
--- a/net/minecraft/world/level/ServerExplosion.java
|
||||||
+++ b/net/minecraft/world/level/ServerExplosion.java
|
+++ b/net/minecraft/world/level/ServerExplosion.java
|
||||||
@@ -35,6 +35,17 @@
|
@@ -35,6 +35,13 @@
|
||||||
import net.minecraft.world.phys.MovingObjectPosition;
|
import net.minecraft.world.phys.MovingObjectPosition;
|
||||||
import net.minecraft.world.phys.Vec3D;
|
import net.minecraft.world.phys.Vec3D;
|
||||||
|
|
||||||
@ -9,16 +9,12 @@
|
|||||||
+import net.minecraft.world.entity.boss.enderdragon.EntityEnderDragon;
|
+import net.minecraft.world.entity.boss.enderdragon.EntityEnderDragon;
|
||||||
+import net.minecraft.world.level.block.Blocks;
|
+import net.minecraft.world.level.block.Blocks;
|
||||||
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||||
+import org.bukkit.craftbukkit.util.CraftLocation;
|
|
||||||
+import org.bukkit.event.entity.EntityExplodeEvent;
|
|
||||||
+import org.bukkit.Location;
|
|
||||||
+import org.bukkit.event.block.BlockExplodeEvent;
|
|
||||||
+// CraftBukkit end
|
+// CraftBukkit end
|
||||||
+
|
+
|
||||||
public class ServerExplosion implements Explosion {
|
public class ServerExplosion implements Explosion {
|
||||||
|
|
||||||
private static final ExplosionDamageCalculator EXPLOSION_DAMAGE_CALCULATOR = new ExplosionDamageCalculator();
|
private static final ExplosionDamageCalculator EXPLOSION_DAMAGE_CALCULATOR = new ExplosionDamageCalculator();
|
||||||
@@ -50,16 +61,21 @@
|
@@ -50,16 +57,21 @@
|
||||||
private final DamageSource damageSource;
|
private final DamageSource damageSource;
|
||||||
private final ExplosionDamageCalculator damageCalculator;
|
private final ExplosionDamageCalculator damageCalculator;
|
||||||
private final Map<EntityHuman, Vec3D> hitPlayers = new HashMap();
|
private final Map<EntityHuman, Vec3D> hitPlayers = new HashMap();
|
||||||
@ -41,7 +37,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ExplosionDamageCalculator makeDamageCalculator(@Nullable Entity entity) {
|
private ExplosionDamageCalculator makeDamageCalculator(@Nullable Entity entity) {
|
||||||
@@ -195,7 +211,35 @@
|
@@ -195,7 +207,35 @@
|
||||||
float f2 = !flag && f1 == 0.0F ? 0.0F : getSeenPercent(this.center, entity);
|
float f2 = !flag && f1 == 0.0F ? 0.0F : getSeenPercent(this.center, entity);
|
||||||
|
|
||||||
if (flag) {
|
if (flag) {
|
||||||
@ -78,7 +74,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
double d5 = (1.0D - d0) * (double) f2 * (double) f1;
|
double d5 = (1.0D - d0) * (double) f2 * (double) f1;
|
||||||
@@ -214,6 +258,17 @@
|
@@ -214,6 +254,17 @@
|
||||||
d3 *= d6;
|
d3 *= d6;
|
||||||
Vec3D vec3d = new Vec3D(d1, d2, d3);
|
Vec3D vec3d = new Vec3D(d1, d2, d3);
|
||||||
|
|
||||||
@ -96,45 +92,15 @@
|
|||||||
entity.push(vec3d);
|
entity.push(vec3d);
|
||||||
if (entity instanceof EntityHuman) {
|
if (entity instanceof EntityHuman) {
|
||||||
EntityHuman entityhuman = (EntityHuman) entity;
|
EntityHuman entityhuman = (EntityHuman) entity;
|
||||||
@@ -235,10 +290,62 @@
|
@@ -235,10 +286,31 @@
|
||||||
List<ServerExplosion.a> list1 = new ArrayList();
|
List<ServerExplosion.a> list1 = new ArrayList();
|
||||||
|
|
||||||
SystemUtils.shuffle(list, this.level.random);
|
SystemUtils.shuffle(list, this.level.random);
|
||||||
+ // CraftBukkit start
|
+ // CraftBukkit start
|
||||||
+ org.bukkit.World bworld = this.level.getWorld();
|
+ List<org.bukkit.block.Block> bukkitBlocks = CraftEventFactory.handleExplodeEvent(this, list);
|
||||||
+ Location location = CraftLocation.toBukkit(this.center, bworld);
|
|
||||||
+
|
|
||||||
+ List<org.bukkit.block.Block> blockList = new ObjectArrayList<>();
|
|
||||||
+ for (int i1 = list.size() - 1; i1 >= 0; i1--) {
|
|
||||||
+ BlockPosition cpos = list.get(i1);
|
|
||||||
+ org.bukkit.block.Block bblock = bworld.getBlockAt(cpos.getX(), cpos.getY(), cpos.getZ());
|
|
||||||
+ if (!bblock.getType().isAir()) {
|
|
||||||
+ blockList.add(bblock);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ List<org.bukkit.block.Block> bukkitBlocks;
|
|
||||||
+
|
|
||||||
+ if (this.source != null) {
|
|
||||||
+ EntityExplodeEvent event = CraftEventFactory.callEntityExplodeEvent(this.source, blockList, this.yield, getBlockInteraction());
|
|
||||||
+ this.wasCanceled = event.isCancelled();
|
|
||||||
+ bukkitBlocks = event.blockList();
|
|
||||||
+ this.yield = event.getYield();
|
|
||||||
+ } else {
|
|
||||||
+ org.bukkit.block.Block block = location.getBlock();
|
|
||||||
+ org.bukkit.block.BlockState blockState = (damageSource.getDirectBlockState() != null) ? damageSource.getDirectBlockState() : block.getState();
|
|
||||||
+ BlockExplodeEvent event = CraftEventFactory.callBlockExplodeEvent(block, blockState, blockList, this.yield, getBlockInteraction());
|
|
||||||
+ this.wasCanceled = event.isCancelled();
|
|
||||||
+ bukkitBlocks = event.blockList();
|
|
||||||
+ this.yield = event.getYield();
|
|
||||||
+ }
|
|
||||||
+
|
+
|
||||||
+ list.clear();
|
+ list.clear();
|
||||||
+
|
+ list.addAll(bukkitBlocks.stream().map(bblock -> new BlockPosition(bblock.getX(), bblock.getY(), bblock.getZ())).toList());
|
||||||
+ for (org.bukkit.block.Block bblock : bukkitBlocks) {
|
|
||||||
+ BlockPosition coords = new BlockPosition(bblock.getX(), bblock.getY(), bblock.getZ());
|
|
||||||
+ list.add(coords);
|
|
||||||
+ }
|
|
||||||
+
|
+
|
||||||
+ if (this.wasCanceled) {
|
+ if (this.wasCanceled) {
|
||||||
+ return;
|
+ return;
|
||||||
@ -148,9 +114,8 @@
|
|||||||
+ IBlockData iblockdata = this.level.getBlockState(blockposition);
|
+ IBlockData iblockdata = this.level.getBlockState(blockposition);
|
||||||
+ Block block = iblockdata.getBlock();
|
+ Block block = iblockdata.getBlock();
|
||||||
+ if (block instanceof net.minecraft.world.level.block.BlockTNT) {
|
+ if (block instanceof net.minecraft.world.level.block.BlockTNT) {
|
||||||
+ Entity sourceEntity = source == null ? null : source;
|
+ BlockPosition sourceBlock = source == null ? BlockPosition.containing(this.center) : null;
|
||||||
+ BlockPosition sourceBlock = sourceEntity == null ? BlockPosition.containing(this.center) : null;
|
+ if (!CraftEventFactory.callTNTPrimeEvent(this.level, blockposition, org.bukkit.event.block.TNTPrimeEvent.PrimeCause.EXPLOSION, source, sourceBlock)) {
|
||||||
+ if (!CraftEventFactory.callTNTPrimeEvent(this.level, blockposition, org.bukkit.event.block.TNTPrimeEvent.PrimeCause.EXPLOSION, sourceEntity, sourceBlock)) {
|
|
||||||
+ this.level.sendBlockUpdated(blockposition, Blocks.AIR.defaultBlockState(), iblockdata, 3); // Update the block on the client
|
+ this.level.sendBlockUpdated(blockposition, Blocks.AIR.defaultBlockState(), iblockdata, 3); // Update the block on the client
|
||||||
+ continue;
|
+ continue;
|
||||||
+ }
|
+ }
|
||||||
@ -159,7 +124,7 @@
|
|||||||
|
|
||||||
this.level.getBlockState(blockposition).onExplosionHit(this.level, blockposition, this, (itemstack, blockposition1) -> {
|
this.level.getBlockState(blockposition).onExplosionHit(this.level, blockposition, this, (itemstack, blockposition1) -> {
|
||||||
addOrAppendStack(list1, itemstack, blockposition1);
|
addOrAppendStack(list1, itemstack, blockposition1);
|
||||||
@@ -262,13 +369,22 @@
|
@@ -262,13 +334,22 @@
|
||||||
BlockPosition blockposition = (BlockPosition) iterator.next();
|
BlockPosition blockposition = (BlockPosition) iterator.next();
|
||||||
|
|
||||||
if (this.level.random.nextInt(3) == 0 && this.level.getBlockState(blockposition).isAir() && this.level.getBlockState(blockposition.below()).isSolidRender()) {
|
if (this.level.random.nextInt(3) == 0 && this.level.getBlockState(blockposition).isAir() && this.level.getBlockState(blockposition.below()).isSolidRender()) {
|
||||||
@ -183,7 +148,23 @@
|
|||||||
this.level.gameEvent(this.source, (Holder) GameEvent.EXPLODE, this.center);
|
this.level.gameEvent(this.source, (Holder) GameEvent.EXPLODE, this.center);
|
||||||
List<BlockPosition> list = this.calculateExplodedPositions();
|
List<BlockPosition> list = this.calculateExplodedPositions();
|
||||||
|
|
||||||
@@ -288,6 +404,7 @@
|
@@ -279,7 +360,15 @@
|
||||||
|
gameprofilerfiller.push("explosion_blocks");
|
||||||
|
this.interactWithBlocks(list);
|
||||||
|
gameprofilerfiller.pop();
|
||||||
|
+ // CraftBukkit start - handle KEEP effect
|
||||||
|
+ } else {
|
||||||
|
+ SystemUtils.shuffle(list, this.level.random); // CraftBukkit - Copy from calculateExplodedPositions
|
||||||
|
+ List<org.bukkit.block.Block> bukkitBlocks = CraftEventFactory.handleExplodeEvent(this, list);
|
||||||
|
+
|
||||||
|
+ list.clear();
|
||||||
|
+ list.addAll(bukkitBlocks.stream().map(bblock -> new BlockPosition(bblock.getX(), bblock.getY(), bblock.getZ())).toList());
|
||||||
|
}
|
||||||
|
+ // CraftBukkit end
|
||||||
|
|
||||||
|
if (this.fire) {
|
||||||
|
this.createFire(list);
|
||||||
|
@@ -288,6 +377,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void addOrAppendStack(List<ServerExplosion.a> list, ItemStack itemstack, BlockPosition blockposition) {
|
private static void addOrAppendStack(List<ServerExplosion.a> list, ItemStack itemstack, BlockPosition blockposition) {
|
||||||
|
@ -5,6 +5,7 @@ import com.google.common.base.Functions;
|
|||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.mojang.datafixers.util.Either;
|
import com.mojang.datafixers.util.Either;
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -66,6 +67,7 @@ import net.minecraft.world.item.crafting.RecipeHolder;
|
|||||||
import net.minecraft.world.level.ChunkCoordIntPair;
|
import net.minecraft.world.level.ChunkCoordIntPair;
|
||||||
import net.minecraft.world.level.Explosion;
|
import net.minecraft.world.level.Explosion;
|
||||||
import net.minecraft.world.level.GeneratorAccess;
|
import net.minecraft.world.level.GeneratorAccess;
|
||||||
|
import net.minecraft.world.level.ServerExplosion;
|
||||||
import net.minecraft.world.level.World;
|
import net.minecraft.world.level.World;
|
||||||
import net.minecraft.world.level.block.entity.TileEntitySign;
|
import net.minecraft.world.level.block.entity.TileEntitySign;
|
||||||
import net.minecraft.world.level.block.state.IBlockData;
|
import net.minecraft.world.level.block.state.IBlockData;
|
||||||
@ -108,6 +110,7 @@ import org.bukkit.craftbukkit.inventory.CraftInventoryCrafting;
|
|||||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||||
import org.bukkit.craftbukkit.inventory.CraftItemType;
|
import org.bukkit.craftbukkit.inventory.CraftItemType;
|
||||||
import org.bukkit.craftbukkit.potion.CraftPotionUtil;
|
import org.bukkit.craftbukkit.potion.CraftPotionUtil;
|
||||||
|
import org.bukkit.craftbukkit.util.CraftLocation;
|
||||||
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||||
import org.bukkit.craftbukkit.util.CraftVector;
|
import org.bukkit.craftbukkit.util.CraftVector;
|
||||||
import org.bukkit.entity.AbstractHorse;
|
import org.bukkit.entity.AbstractHorse;
|
||||||
@ -1877,6 +1880,38 @@ public class CraftEventFactory {
|
|||||||
return !event.isCancelled();
|
return !event.isCancelled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<org.bukkit.block.Block> handleExplodeEvent(ServerExplosion serverExplosion, List<BlockPosition> blockPositions) {
|
||||||
|
// First convert the blockPositionList related to the explosion to Bukkit objects
|
||||||
|
org.bukkit.World bworld = serverExplosion.level().getWorld();
|
||||||
|
|
||||||
|
List<org.bukkit.block.Block> blockList = new ObjectArrayList<>();
|
||||||
|
for (int i1 = blockPositions.size() - 1; i1 >= 0; i1--) {
|
||||||
|
BlockPosition cpos = blockPositions.get(i1);
|
||||||
|
org.bukkit.block.Block bblock = bworld.getBlockAt(cpos.getX(), cpos.getY(), cpos.getZ());
|
||||||
|
if (!bblock.getType().isAir()) {
|
||||||
|
blockList.add(bblock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle based on explosion or damage source whether we need to call EntityExplodeEvent
|
||||||
|
if (serverExplosion.getDirectSourceEntity() != null || serverExplosion.getDamageSource().getCausingDamager() != null) {
|
||||||
|
EntityExplodeEvent event = CraftEventFactory.callEntityExplodeEvent((serverExplosion.getDirectSourceEntity() != null) ? serverExplosion.getDirectSourceEntity() : serverExplosion.getDamageSource().getCausingDamager(), blockList, serverExplosion.yield, serverExplosion.getBlockInteraction());
|
||||||
|
serverExplosion.wasCanceled = event.isCancelled();
|
||||||
|
serverExplosion.yield = event.getYield();
|
||||||
|
return event.blockList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Else BlockExplodeEvent when entity not found in previous if statement
|
||||||
|
Location location = CraftLocation.toBukkit(serverExplosion.center(), bworld);
|
||||||
|
org.bukkit.block.Block block = location.getBlock();
|
||||||
|
org.bukkit.block.BlockState blockState = (serverExplosion.getDamageSource().getDirectBlockState() != null) ? serverExplosion.getDamageSource().getDirectBlockState() : block.getState();
|
||||||
|
BlockExplodeEvent event = CraftEventFactory.callBlockExplodeEvent(block, blockState, blockList, serverExplosion.yield, serverExplosion.getBlockInteraction());
|
||||||
|
serverExplosion.wasCanceled = event.isCancelled();
|
||||||
|
serverExplosion.yield = event.getYield();
|
||||||
|
|
||||||
|
return event.blockList();
|
||||||
|
}
|
||||||
|
|
||||||
public static EntityExplodeEvent callEntityExplodeEvent(Entity entity, List<Block> blocks, float yield, Explosion.Effect effect) {
|
public static EntityExplodeEvent callEntityExplodeEvent(Entity entity, List<Block> blocks, float yield, Explosion.Effect effect) {
|
||||||
EntityExplodeEvent event = new EntityExplodeEvent(entity.getBukkitEntity(), entity.getBukkitEntity().getLocation(), blocks, yield, CraftExplosionResult.toBukkit(effect));
|
EntityExplodeEvent event = new EntityExplodeEvent(entity.getBukkitEntity(), entity.getBukkitEntity().getLocation(), blocks, yield, CraftExplosionResult.toBukkit(effect));
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user