diff --git a/patches/api/0419-Improved-AreaEffectCloud-API.patch b/patches/api/0419-Improved-AreaEffectCloud-API.patch new file mode 100644 index 0000000000..4f243718f5 --- /dev/null +++ b/patches/api/0419-Improved-AreaEffectCloud-API.patch @@ -0,0 +1,76 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sat, 17 Jun 2023 22:20:47 -0700 +Subject: [PATCH] Improved AreaEffectCloud API + + +diff --git a/src/main/java/org/bukkit/entity/AreaEffectCloud.java b/src/main/java/org/bukkit/entity/AreaEffectCloud.java +index c2096b5344d48d855d031538ec32e0154bd9054d..0642c64b075a1b7b241805ef0f7099f9be66f2c4 100644 +--- a/src/main/java/org/bukkit/entity/AreaEffectCloud.java ++++ b/src/main/java/org/bukkit/entity/AreaEffectCloud.java +@@ -239,4 +239,23 @@ public interface AreaEffectCloud extends Entity { + * @param source the {@link ProjectileSource} that threw the LingeringPotion + */ + public void setSource(@Nullable ProjectileSource source); ++ ++ // Paper start - force apply effect API ++ /** ++ * Empty area effect clouds, those without any effects, ++ * do not calculate which players to apply effects to. This ++ * provides a way to force those to still happen, and therefor ++ * still fire the {@link org.bukkit.event.entity.AreaEffectCloudApplyEvent}. ++ * ++ * @param force true to force calculating the affected players ++ */ ++ void forceApplyEffects(boolean force); ++ ++ /** ++ * Gets if this cloud will force calculating the affected players. ++ * ++ * @return true if forcing is enabled ++ * @see #forceApplyEffects(boolean) ++ */ ++ boolean willForceApplyEffects(); + } +diff --git a/src/main/java/org/bukkit/event/entity/AreaEffectCloudApplyEvent.java b/src/main/java/org/bukkit/event/entity/AreaEffectCloudApplyEvent.java +index 9cee218b9ee14688356f16b1f58512186286e7e9..126691393ddddcbb0a567f64b5923a65c4f416ac 100644 +--- a/src/main/java/org/bukkit/event/entity/AreaEffectCloudApplyEvent.java ++++ b/src/main/java/org/bukkit/event/entity/AreaEffectCloudApplyEvent.java +@@ -15,6 +15,7 @@ public class AreaEffectCloudApplyEvent extends EntityEvent implements Cancellabl + private static final HandlerList handlers = new HandlerList(); + private final List affectedEntities; + private boolean cancelled = false; ++ private java.util.function.Predicate wasUsedOverride = null; // Paper + + public AreaEffectCloudApplyEvent(@NotNull final AreaEffectCloud entity, @NotNull final List affectedEntities) { + super(entity); +@@ -52,6 +53,29 @@ public class AreaEffectCloudApplyEvent extends EntityEvent implements Cancellabl + return affectedEntities; + } + ++ // Paper start - was used override ++ /** ++ * Gets the optional predicate used to override whether the cloud effect ++ * was "used" or not. Useful for having finer control over {@link AreaEffectCloud#getRadiusOnUse()} ++ * after an application of the effects. ++ * ++ * @return the living entity predicate ++ */ ++ public java.util.function.@org.jetbrains.annotations.Nullable Predicate getWasUsedOverride() { ++ return this.wasUsedOverride; ++ } ++ ++ /** ++ * Sets the predicate used to override the "use" tracker for the area effect cloud. ++ * ++ * @param wasUsedOverride the predicate or null to clear ++ * @see #getWasUsedOverride() ++ */ ++ public void setWasUsedOverride(final java.util.function.@org.jetbrains.annotations.Nullable Predicate wasUsedOverride) { ++ this.wasUsedOverride = wasUsedOverride; ++ } ++ // Paper end ++ + @NotNull + @Override + public HandlerList getHandlers() { diff --git a/patches/server/0977-Improved-AreaEffectCloud-API.patch b/patches/server/0977-Improved-AreaEffectCloud-API.patch new file mode 100644 index 0000000000..064d9511aa --- /dev/null +++ b/patches/server/0977-Improved-AreaEffectCloud-API.patch @@ -0,0 +1,90 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sat, 17 Jun 2023 22:20:44 -0700 +Subject: [PATCH] Improved AreaEffectCloud API + + +diff --git a/src/main/java/net/minecraft/world/entity/AreaEffectCloud.java b/src/main/java/net/minecraft/world/entity/AreaEffectCloud.java +index 91e0328f847a2464a1cf65134520244a4cec705f..bc090ae6d3da98457fd7068124a9e52eb641d725 100644 +--- a/src/main/java/net/minecraft/world/entity/AreaEffectCloud.java ++++ b/src/main/java/net/minecraft/world/entity/AreaEffectCloud.java +@@ -62,6 +62,7 @@ public class AreaEffectCloud extends Entity implements TraceableEntity { + private net.minecraft.world.entity.LivingEntity owner; + @Nullable + private UUID ownerUUID; ++ public boolean forceApplyEffects = false; // Paper + + public AreaEffectCloud(EntityType type, Level world) { + super(type, world); +@@ -287,7 +288,7 @@ public class AreaEffectCloud extends Entity implements TraceableEntity { + } + + list.addAll(this.effects); +- if (list.isEmpty()) { ++ if (list.isEmpty() && !this.forceApplyEffects) { // Paper + this.victims.clear(); + } else { + List list1 = this.level().getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, this.getBoundingBox()); +@@ -313,7 +314,7 @@ public class AreaEffectCloud extends Entity implements TraceableEntity { + org.bukkit.event.entity.AreaEffectCloudApplyEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callAreaEffectCloudApplyEvent(this, entities); + if (!event.isCancelled()) { + for (LivingEntity entity : event.getAffectedEntities()) { +- if (entity instanceof CraftLivingEntity) { ++ if (entity instanceof CraftLivingEntity craftLivingEntity) { // Paper + net.minecraft.world.entity.LivingEntity entityliving = ((CraftLivingEntity) entity).getHandle(); + // CraftBukkit end + this.victims.put(entityliving, this.tickCount + this.reapplicationDelay); +@@ -329,7 +330,7 @@ public class AreaEffectCloud extends Entity implements TraceableEntity { + } + } + +- if (this.radiusOnUse != 0.0F) { ++ if (this.radiusOnUse != 0.0F && (event.getWasUsedOverride() == null || event.getWasUsedOverride().test(craftLivingEntity))) { // Paper - was used override + f += this.radiusOnUse; + if (f < 0.5F) { + this.discard(); +@@ -407,6 +408,7 @@ public class AreaEffectCloud extends Entity implements TraceableEntity { + return this.owner; + } + ++ private static final String PAPER_FORCE_APPLY_EFFECTS_KEY = "Paper.forceApplyEffects"; // Paper + @Override + protected void readAdditionalSaveData(CompoundTag nbt) { + this.tickCount = nbt.getInt("Age"); +@@ -451,6 +453,7 @@ public class AreaEffectCloud extends Entity implements TraceableEntity { + } + } + ++ this.forceApplyEffects = nbt.getBoolean(PAPER_FORCE_APPLY_EFFECTS_KEY); // Paper + } + + @Override +@@ -488,6 +491,7 @@ public class AreaEffectCloud extends Entity implements TraceableEntity { + + nbt.put("Effects", nbttaglist); + } ++ nbt.putBoolean(PAPER_FORCE_APPLY_EFFECTS_KEY, this.forceApplyEffects); // Paper + + } + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java +index 0f9e1d7aaee8ae870acd41934d52964c4d1aaff3..5e540c79ca0e0815198ce84e10b275627fdd0ede 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java +@@ -226,4 +226,16 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud + this.getHandle().setOwner(null); + } + } ++ ++ // Paper start - force apply effect API ++ @Override ++ public void forceApplyEffects(final boolean force) { ++ this.getHandle().forceApplyEffects = force; ++ } ++ ++ @Override ++ public boolean willForceApplyEffects() { ++ return this.getHandle().forceApplyEffects; ++ } ++ // Paper end + }