Skip to content

Commit

Permalink
Add API for explosions to damage the explosion cause (#11180)
Browse files Browse the repository at this point in the history
This intends to give plugin developers more control over explosions created using the World#createExplosion method, specifically by adding the option for explosions to damage the explosion cause (not the default behavior, and previously impossible to do, as far as I know). This is done by overloading existing methods with an extra `excludeSourceFromDamage` parameter.

Co-authored-by: Bjarne Koll <[email protected]>
  • Loading branch information
EsotericEnderman and lynxplay authored Sep 28, 2024
1 parent 7b03141 commit 355b1cb
Show file tree
Hide file tree
Showing 37 changed files with 233 additions and 122 deletions.
25 changes: 22 additions & 3 deletions patches/api/0112-Expand-Explosions-API.patch
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ Subject: [PATCH] Expand Explosions API

Add Entity as a Source capability, and add more API choices, and on Location.

Co-authored-by: Slqmy <[email protected]>
Co-authored-by: Bjarne Koll <[email protected]>

diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java
index 3161eae2fa5f03b7d3a5e9945ab659c15cf568c6..af737017ee397f80c44ee02c6cc60cefa07f59c1 100644
--- a/src/main/java/org/bukkit/Location.java
Expand Down Expand Up @@ -108,10 +111,10 @@ index 3161eae2fa5f03b7d3a5e9945ab659c15cf568c6..af737017ee397f80c44ee02c6cc60cef
/**
* Returns a list of entities within a bounding box centered around a Location.
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
index 44a74f15bea60ecd8380520e8faaea41a6c261c5..50c1e4957f66826feb0a2eb04293dbd6b5595700 100644
index 44a74f15bea60ecd8380520e8faaea41a6c261c5..c2b5fdaace13c8bd46c073ac6d427fe411d96367 100644
--- a/src/main/java/org/bukkit/World.java
+++ b/src/main/java/org/bukkit/World.java
@@ -1424,6 +1424,88 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
@@ -1424,6 +1424,104 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
*/
public boolean createExplosion(@NotNull Location loc, float power, boolean setFire);

Expand All @@ -125,9 +128,25 @@ index 44a74f15bea60ecd8380520e8faaea41a6c261c5..50c1e4957f66826feb0a2eb04293dbd6
+ * @param power The power of explosion, where 4F is TNT
+ * @param setFire Whether or not to set blocks on fire
+ * @param breakBlocks Whether or not to have blocks be destroyed
+ * @param excludeSourceFromDamage whether the explosion should exclude the passed source from taking damage like vanilla explosions do.
+ * @return false if explosion was canceled, otherwise true
+ */
+ public boolean createExplosion(@Nullable Entity source, @NotNull Location loc, float power, boolean setFire, boolean breakBlocks, boolean excludeSourceFromDamage);
+
+ /**
+ * Creates explosion at given location with given power and optionally
+ * setting blocks on fire, with the specified entity as the source.
+ *
+ * @param source The source entity of the explosion
+ * @param loc Location to blow up
+ * @param power The power of explosion, where 4F is TNT
+ * @param setFire Whether or not to set blocks on fire
+ * @param breakBlocks Whether or not to have blocks be destroyed
+ * @return false if explosion was canceled, otherwise true
+ */
+ public boolean createExplosion(@Nullable Entity source, @NotNull Location loc, float power, boolean setFire, boolean breakBlocks);
+ default boolean createExplosion(@Nullable Entity source, @NotNull Location loc, float power, boolean setFire, boolean breakBlocks) {
+ return createExplosion(source, loc, power, setFire, breakBlocks, true);
+ }
+
+ /**
+ * Creates explosion at given location with given power and optionally
Expand Down
10 changes: 5 additions & 5 deletions patches/api/0166-Fix-Spigot-annotation-mistakes.patch
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ index e455eb21abf121dc6ff10ff8a13dd06f67096a8f..bbc01e7c192ae6689c301670047ff114
return origin;
}
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
index fcdc5d83621acff5f9210585455be1ea50abb77c..216995288f6b8b407ef8240411b5ed4713379a7a 100644
index 7dbc2e4883feb5b0b1a20cf36cda01ef3795a262..e4471e86e1b0993425087d8331e7c3d9896b3908 100644
--- a/src/main/java/org/bukkit/World.java
+++ b/src/main/java/org/bukkit/World.java
@@ -418,9 +418,8 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
Expand All @@ -632,15 +632,15 @@ index fcdc5d83621acff5f9210585455be1ea50abb77c..216995288f6b8b407ef8240411b5ed47
public boolean refreshChunk(int x, int z);

/**
@@ -3797,6 +3796,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
@@ -3813,6 +3812,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
StructureSearchResult locateNearestStructure(@NotNull Location origin, @NotNull Structure structure, int radius, boolean findUnexplored);

// Spigot start
+ @Deprecated(forRemoval = true) // Paper
public class Spigot {

/**
@@ -3830,7 +3830,11 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
@@ -3846,7 +3846,11 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
}
}

Expand All @@ -652,7 +652,7 @@ index fcdc5d83621acff5f9210585455be1ea50abb77c..216995288f6b8b407ef8240411b5ed47
Spigot spigot();
// Spigot end

@@ -4048,9 +4052,9 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
@@ -4064,9 +4068,9 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
* Gets the dimension ID of this environment
*
* @return dimension ID
Expand All @@ -664,7 +664,7 @@ index fcdc5d83621acff5f9210585455be1ea50abb77c..216995288f6b8b407ef8240411b5ed47
public int getId() {
return id;
}
@@ -4060,9 +4064,9 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
@@ -4076,9 +4080,9 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
*
* @param id The ID of the environment
* @return The environment
Expand Down
4 changes: 2 additions & 2 deletions patches/api/0260-More-World-API.patch
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ Subject: [PATCH] More World API


diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
index 216995288f6b8b407ef8240411b5ed4713379a7a..d3fc033aba36c5fd99846e9200ed0071fddd6045 100644
index e4471e86e1b0993425087d8331e7c3d9896b3908..ce1f3ffbab6a8dc8395e3a5b74a7874bb6b38aa9 100644
--- a/src/main/java/org/bukkit/World.java
+++ b/src/main/java/org/bukkit/World.java
@@ -3795,6 +3795,72 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
@@ -3811,6 +3811,72 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
@Nullable
StructureSearchResult locateNearestStructure(@NotNull Location origin, @NotNull Structure structure, int radius, boolean findUnexplored);

Expand Down
8 changes: 4 additions & 4 deletions patches/api/0348-Expand-FallingBlock-API.patch
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ Subject: [PATCH] Expand FallingBlock API
Co-authored-by: Lukas Planz <[email protected]>

diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
index 8e9ab00503167799c6c929d00e48c07cb328848c..907906e15c9250fea385e49f10d3c248236fd004 100644
index 2720f290a632dd32fd9e70a40e73db9d1d161e94..f037f46a9c6ce894f24af14c20fb514a58a8aee9 100644
--- a/src/main/java/org/bukkit/World.java
+++ b/src/main/java/org/bukkit/World.java
@@ -2228,8 +2228,10 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
@@ -2244,8 +2244,10 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
* @return The spawned {@link FallingBlock} instance
* @throws IllegalArgumentException if {@link Location} or {@link
* MaterialData} are null or {@link Material} of the {@link MaterialData} is not a block
Expand All @@ -24,7 +24,7 @@ index 8e9ab00503167799c6c929d00e48c07cb328848c..907906e15c9250fea385e49f10d3c248
public FallingBlock spawnFallingBlock(@NotNull Location location, @NotNull MaterialData data) throws IllegalArgumentException;

/**
@@ -2242,8 +2244,10 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
@@ -2258,8 +2260,10 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
* @return The spawned {@link FallingBlock} instance
* @throws IllegalArgumentException if {@link Location} or {@link
* BlockData} are null
Expand All @@ -35,7 +35,7 @@ index 8e9ab00503167799c6c929d00e48c07cb328848c..907906e15c9250fea385e49f10d3c248
public FallingBlock spawnFallingBlock(@NotNull Location location, @NotNull BlockData data) throws IllegalArgumentException;

/**
@@ -2260,7 +2264,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
@@ -2276,7 +2280,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
* @return The spawned {@link FallingBlock} instance
* @throws IllegalArgumentException if {@link Location} or {@link
* Material} are null or {@link Material} is not a block
Expand Down
4 changes: 2 additions & 2 deletions patches/api/0456-More-Raid-API.patch
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ index 983a8c20a06d2b509602b27f49c090598b8ecc42..fa98599e3eee37bf68f0e9813497c718
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
index ecc2d486cfec79cce27a947dfeed4853575a594d..d8a23aa0d898ca3360757721e38ddb97387f7d21 100644
index 16570c3c7ed5e7ad25f20c1034f7b966d6e694da..adcd8161846b06fd1a7895750f98b629204a8406 100644
--- a/src/main/java/org/bukkit/World.java
+++ b/src/main/java/org/bukkit/World.java
@@ -4111,6 +4111,17 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
@@ -4127,6 +4127,17 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
@Nullable
public Raid locateNearestRaid(@NotNull Location location, int radius);

Expand Down
100 changes: 96 additions & 4 deletions patches/server/0203-Expand-Explosions-API.patch
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,110 @@ Subject: [PATCH] Expand Explosions API

Add Entity as a Source capability, and add more API choices, and on Location.

Co-authored-by: Slqmy <[email protected]>
Co-authored-by: Bjarne Koll <[email protected]>

diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 1fac100819e59d00f50e530d3a4157b56d966dba..f2e75b36cbceb9cfa0755bd045f23073712d0e8a 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1424,8 +1424,10 @@ public class ServerLevel extends Level implements WorldGenLevel {
}

@Override
- public Explosion explode(@Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, double x, double y, double z, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType, ParticleOptions particle, ParticleOptions emitterParticle, Holder<SoundEvent> soundEvent) {
- Explosion explosion = this.explode(entity, damageSource, behavior, x, y, z, power, createFire, explosionSourceType, false, particle, emitterParticle, soundEvent);
+ // Paper start - Allow explosions to damage source
+ public Explosion explode(@Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, double x, double y, double z, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType, ParticleOptions particle, ParticleOptions emitterParticle, Holder<SoundEvent> soundEvent, java.util.function.Consumer<Explosion> configurator) {
+ Explosion explosion = this.explode(entity, damageSource, behavior, x, y, z, power, createFire, explosionSourceType, false, particle, emitterParticle, soundEvent, configurator);
+ // Paper end - Allow explosions to damage source
// CraftBukkit start
if (explosion.wasCanceled) {
return explosion;
diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
index b216140a8be65e210250358af8daf49344850f20..ce8ac06b47e81161ad5ff6cc865ad6d3d59807c1 100644
--- a/src/main/java/net/minecraft/world/level/Explosion.java
+++ b/src/main/java/net/minecraft/world/level/Explosion.java
@@ -74,6 +74,7 @@ public class Explosion {
public boolean wasCanceled = false;
public float yield;
// CraftBukkit end
+ public boolean excludeSourceFromDamage = true; // Paper - Allow explosions to damage source

public static DamageSource getDefaultDamageSource(Level world, @Nullable Entity source) {
return world.damageSources().explosion(source, Explosion.getIndirectSourceEntityInternal(source));
@@ -227,7 +228,7 @@ public class Explosion {
int i1 = Mth.floor(this.y + (double) f2 + 1.0D);
int j1 = Mth.floor(this.z - (double) f2 - 1.0D);
int k1 = Mth.floor(this.z + (double) f2 + 1.0D);
- List<Entity> list = this.level.getEntities(this.source, new AABB((double) i, (double) l, (double) j1, (double) j, (double) i1, (double) k1), (com.google.common.base.Predicate<Entity>) entity -> entity.isAlive() && !entity.isSpectator()); // Paper - Fix lag from explosions processing dead entities
+ List<Entity> list = this.level.getEntities(excludeSourceFromDamage ? this.source : null, new AABB((double) i, (double) l, (double) j1, (double) j, (double) i1, (double) k1), (com.google.common.base.Predicate<Entity>) entity -> entity.isAlive() && !entity.isSpectator()); // Paper - Fix lag from explosions processing dead entities, Allow explosions to damage source
Vec3 vec3d = new Vec3(this.x, this.y, this.z);
Iterator iterator = list.iterator();

diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 6944c0b0cfcde9fa4dd78742aee3e3b87d679abf..7138fb36062eceaf92ae8513f9b8aef3d1238656 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -782,7 +782,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
}

public Explosion explode(@Nullable Entity entity, double x, double y, double z, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType) {
- return this.explode(entity, Explosion.getDefaultDamageSource(this, entity), (ExplosionDamageCalculator) null, x, y, z, power, createFire, explosionSourceType, ParticleTypes.EXPLOSION, ParticleTypes.EXPLOSION_EMITTER, SoundEvents.GENERIC_EXPLODE);
+ // Paper start - Allow explosions to damage source
+ return this.explode(entity, x, y, z, power, createFire, explosionSourceType, null);
+ }
+ public Explosion explode(@Nullable Entity entity, double x, double y, double z, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType, @Nullable Consumer<Explosion> configurator) {
+ return this.explode(entity, Explosion.getDefaultDamageSource(this, entity), (ExplosionDamageCalculator) null, x, y, z, power, createFire, explosionSourceType, ParticleTypes.EXPLOSION, ParticleTypes.EXPLOSION_EMITTER, SoundEvents.GENERIC_EXPLODE, configurator);
+ // Paper end - Allow explosions to damage source
}

public Explosion explode(@Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, Vec3 pos, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType) {
@@ -794,10 +799,21 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
}

public Explosion explode(@Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, double x, double y, double z, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType, ParticleOptions particle, ParticleOptions emitterParticle, Holder<SoundEvent> soundEvent) {
- return this.explode(entity, damageSource, behavior, x, y, z, power, createFire, explosionSourceType, true, particle, emitterParticle, soundEvent);
+ // Paper start - Allow explosions to damage source
+ return this.explode(entity, damageSource, behavior, x, y, z, power, createFire, explosionSourceType, particle, emitterParticle, soundEvent, null);
+ }
+
+ public Explosion explode(@Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, double x, double y, double z, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType, ParticleOptions particle, ParticleOptions emitterParticle, Holder<SoundEvent> soundEvent, @Nullable Consumer<Explosion> configurator) {
+ return this.explode(entity, damageSource, behavior, x, y, z, power, createFire, explosionSourceType, true, particle, emitterParticle, soundEvent, configurator);
+ // Paper end - Allow explosions to damage source
}

public Explosion explode(@Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, double x, double y, double z, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType, boolean particles, ParticleOptions particle, ParticleOptions emitterParticle, Holder<SoundEvent> soundEvent) {
+ // Paper start - Allow explosions to damage source
+ return this.explode(entity, damageSource, behavior, x, y, z, power, createFire, explosionSourceType, particle, emitterParticle, soundEvent, null);
+ }
+ public Explosion explode(@Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, double x, double y, double z, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType, boolean particles, ParticleOptions particle, ParticleOptions emitterParticle, Holder<SoundEvent> soundEvent, @Nullable Consumer<Explosion> configurator) {
+ // Paper end - Allow explosions to damage source
Explosion.BlockInteraction explosion_effect;

switch (explosionSourceType.ordinal()) {
@@ -827,6 +843,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {

Explosion.BlockInteraction explosion_effect1 = explosion_effect;
Explosion explosion = new Explosion(this, entity, damageSource, behavior, x, y, z, power, createFire, explosion_effect1, particle, emitterParticle, soundEvent);
+ if (configurator != null) configurator.accept(explosion); // Paper - Allow explosions to damage source

explosion.explode();
explosion.finalizeExplosion(particles);
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 3c00eaf52ab04d1396f226cc074d9dd013c57027..b2a1f7e6576757d02a0369c42d4526ca3ac3d775 100644
index 3c00eaf52ab04d1396f226cc074d9dd013c57027..2c13ece6592700126365a155f104d6971aab4ede 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -789,6 +789,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@@ -789,6 +789,14 @@ public class CraftWorld extends CraftRegionAccessor implements World {

return !this.world.explode(source == null ? null : ((CraftEntity) source).getHandle(), x, y, z, power, setFire, explosionType).wasCanceled;
}
+ // Paper start
+ @Override
+ public boolean createExplosion(Entity source, Location loc, float power, boolean setFire, boolean breakBlocks) {
+ return !world.explode(source != null ? ((org.bukkit.craftbukkit.entity.CraftEntity) source).getHandle() : null, loc.getX(), loc.getY(), loc.getZ(), power, setFire, breakBlocks ? net.minecraft.world.level.Level.ExplosionInteraction.MOB : net.minecraft.world.level.Level.ExplosionInteraction.NONE).wasCanceled;
+ public boolean createExplosion(Entity source, Location loc, float power, boolean setFire, boolean breakBlocks, boolean excludeSourceFromDamage) {
+ return !world.explode(source != null ? ((org.bukkit.craftbukkit.entity.CraftEntity) source).getHandle() : null, loc.getX(), loc.getY(), loc.getZ(), power, setFire, breakBlocks ? net.minecraft.world.level.Level.ExplosionInteraction.MOB : net.minecraft.world.level.Level.ExplosionInteraction.NONE, explosion -> {
+ explosion.excludeSourceFromDamage = excludeSourceFromDamage;
+ }).wasCanceled;
+ }
+ // Paper end

Expand Down
Loading

0 comments on commit 355b1cb

Please sign in to comment.