Paper/patches/server/0554-Fix-potions-splash-events.patch

182 lines
11 KiB
Diff
Raw Normal View History

2021-06-11 14:02:28 +02:00
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Thu, 20 May 2021 20:40:53 -0700
Subject: [PATCH] Fix potions splash events
2021-06-11 14:02:28 +02:00
Fix PotionSplashEvent for water splash potions
2021-06-11 14:02:28 +02:00
Fixes SPIGOT-6221: https://hub.spigotmc.org/jira/projects/SPIGOT/issues/SPIGOT-6221
Fix splash events cancellation that still show particles/sound
2021-06-11 14:02:28 +02:00
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
2024-06-14 01:32:45 +02:00
index be787a5b52e90796d4f06e17e564f4324807c3e6..cb34cc9443da56c0497c7a0192c8b8363c3426fe 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
2024-06-14 01:32:45 +02:00
@@ -106,55 +106,76 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
2024-04-24 16:29:12 +02:00
ItemStack itemstack = this.getItem();
PotionContents potioncontents = (PotionContents) itemstack.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY);
2024-04-24 16:29:12 +02:00
+ boolean showParticles = true; // Paper - Fix potions splash events
if (potioncontents.is(Potions.WATER)) {
- this.applyWater();
+ showParticles = this.applyWater(hitResult); // Paper - Fix potions splash events
2024-04-24 16:29:12 +02:00
} else if (true || potioncontents.hasEffects()) { // CraftBukkit - Call event even if no effects to apply
if (this.isLingering()) {
2024-04-24 16:29:12 +02:00
- this.makeAreaOfEffectCloud(potioncontents, hitResult); // CraftBukkit - Pass MovingObjectPosition
2024-04-25 01:25:57 +02:00
+ showParticles = this.makeAreaOfEffectCloud(potioncontents, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper
} else {
2024-04-24 16:29:12 +02:00
- this.applySplash(potioncontents.getAllEffects(), hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null, hitResult); // CraftBukkit - Pass MovingObjectPosition
2024-04-25 01:25:57 +02:00
+ showParticles = this.applySplash(potioncontents.getAllEffects(), hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper
}
}
+ if (showParticles) { // Paper - Fix potions splash events
2024-04-24 16:29:12 +02:00
int i = potioncontents.potion().isPresent() && ((Potion) ((Holder) potioncontents.potion().get()).value()).hasInstantEffects() ? 2007 : 2002;
2024-04-24 16:29:12 +02:00
this.level().levelEvent(i, this.blockPosition(), potioncontents.getColor());
+ } // Paper - Fix potions splash events
this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
}
}
- private void applyWater() {
+ private static final Predicate<net.minecraft.world.entity.LivingEntity> APPLY_WATER_GET_ENTITIES_PREDICATE = ThrownPotion.WATER_SENSITIVE_OR_ON_FIRE.or(Axolotl.class::isInstance); // Paper - Fix potions splash events
+ private boolean applyWater(@Nullable HitResult hitResult) { // Paper - Fix potions splash events
2021-06-11 14:02:28 +02:00
AABB axisalignedbb = this.getBoundingBox().inflate(4.0D, 2.0D, 4.0D);
2023-06-08 04:04:01 +02:00
- List<net.minecraft.world.entity.LivingEntity> list = this.level().getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb, ThrownPotion.WATER_SENSITIVE_OR_ON_FIRE);
+ // Paper start - Fix potions splash events
2023-06-08 04:04:01 +02:00
+ List<net.minecraft.world.entity.LivingEntity> list = this.level().getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb, ThrownPotion.APPLY_WATER_GET_ENTITIES_PREDICATE);
+ Map<LivingEntity, Double> affected = new HashMap<>();
+ java.util.Set<LivingEntity> rehydrate = new java.util.HashSet<>();
+ java.util.Set<LivingEntity> extinguish = new java.util.HashSet<>();
2022-12-07 21:16:54 +01:00
Iterator iterator = list.iterator();
2021-06-11 14:02:28 +02:00
2022-12-07 21:16:54 +01:00
while (iterator.hasNext()) {
net.minecraft.world.entity.LivingEntity entityliving = (net.minecraft.world.entity.LivingEntity) iterator.next();
+ if (entityliving instanceof Axolotl axolotl) {
+ rehydrate.add(((org.bukkit.entity.Axolotl) axolotl.getBukkitEntity()));
2022-12-07 21:16:54 +01:00
+ }
double d0 = this.distanceToSqr((Entity) entityliving);
2021-06-11 14:02:28 +02:00
2022-12-07 21:16:54 +01:00
if (d0 < 16.0D) {
if (entityliving.isSensitiveToWater()) {
2023-03-14 21:25:13 +01:00
- entityliving.hurt(this.damageSources().indirectMagic(this, this.getOwner()), 1.0F);
+ affected.put(entityliving.getBukkitLivingEntity(), 1.0);
2021-06-11 14:02:28 +02:00
}
2022-12-07 21:16:54 +01:00
if (entityliving.isOnFire() && entityliving.isAlive()) {
- entityliving.extinguishFire();
+ extinguish.add(entityliving.getBukkitLivingEntity());
}
2021-06-11 14:02:28 +02:00
}
}
2023-06-08 04:04:01 +02:00
- List<Axolotl> list1 = this.level().getEntitiesOfClass(Axolotl.class, axisalignedbb);
- Iterator iterator1 = list1.iterator();
-
- while (iterator1.hasNext()) {
- Axolotl axolotl = (Axolotl) iterator1.next();
-
- axolotl.rehydrate();
+ io.papermc.paper.event.entity.WaterBottleSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callWaterBottleSplashEvent(
+ this, hitResult, affected, rehydrate, extinguish
+ );
+ if (!event.isCancelled()) {
+ for (LivingEntity affectedEntity : event.getToDamage()) {
2023-03-14 21:25:13 +01:00
+ ((CraftLivingEntity) affectedEntity).getHandle().hurt(this.damageSources().indirectMagic(this, this.getOwner()), 1.0F);
+ }
+ for (LivingEntity toExtinguish : event.getToExtinguish()) {
+ ((CraftLivingEntity) toExtinguish).getHandle().extinguishFire();
+ }
+ for (LivingEntity toRehydrate : event.getToRehydrate()) {
+ if (((CraftLivingEntity) toRehydrate).getHandle() instanceof Axolotl axolotl) {
+ axolotl.rehydrate();
+ }
2021-06-11 14:02:28 +02:00
+ }
+ // Paper end - Fix potions splash events
}
+ return !event.isCancelled(); // Paper - Fix potions splash events
2021-06-11 14:02:28 +02:00
}
2024-04-24 16:29:12 +02:00
- private void applySplash(Iterable<MobEffectInstance> iterable, @Nullable Entity entity, HitResult position) { // CraftBukkit - Pass MovingObjectPosition
+ private boolean applySplash(Iterable<MobEffectInstance> iterable, @Nullable Entity entity, HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - Fix potions splash events
AABB axisalignedbb = this.getBoundingBox().inflate(4.0D, 2.0D, 4.0D);
2024-04-24 16:29:12 +02:00
List<net.minecraft.world.entity.LivingEntity> list = this.level().getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb);
Map<LivingEntity, Double> affected = new HashMap<LivingEntity, Double>(); // CraftBukkit
2024-06-14 01:32:45 +02:00
@@ -172,6 +193,7 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
2021-06-11 14:02:28 +02:00
if (d0 < 16.0D) {
2023-03-14 21:25:13 +01:00
double d1;
2021-06-11 14:02:28 +02:00
2023-03-14 21:25:13 +01:00
+ // Paper - diff on change, used when calling the splash event for water splash potions
2021-06-11 14:02:28 +02:00
if (entityliving == entity) {
2023-03-14 21:25:13 +01:00
d1 = 1.0D;
} else {
2024-06-14 01:32:45 +02:00
@@ -227,10 +249,11 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
}
}
}
+ return !event.isCancelled(); // Paper - Fix potions splash events
}
2024-04-24 16:29:12 +02:00
- private void makeAreaOfEffectCloud(PotionContents potioncontents, HitResult position) { // CraftBukkit - Pass MovingObjectPosition
+ private boolean makeAreaOfEffectCloud(PotionContents potioncontents, HitResult position) { // CraftBukkit - Pass MovingObjectPosition
2023-06-08 04:04:01 +02:00
AreaEffectCloud entityareaeffectcloud = new AreaEffectCloud(this.level(), this.getX(), this.getY(), this.getZ());
Entity entity = this.getOwner();
2024-06-14 01:32:45 +02:00
@@ -243,14 +266,16 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
2024-04-24 16:29:12 +02:00
entityareaeffectcloud.setWaitTime(10);
entityareaeffectcloud.setRadiusPerTick(-entityareaeffectcloud.getRadius() / (float) entityareaeffectcloud.getDuration());
entityareaeffectcloud.setPotionContents(potioncontents);
+ boolean noEffects = potioncontents.hasEffects(); // Paper - Fix potions splash events
// CraftBukkit start
org.bukkit.event.entity.LingeringPotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callLingeringPotionSplashEvent(this, position, entityareaeffectcloud);
- if (!(event.isCancelled() || entityareaeffectcloud.isRemoved())) {
2024-04-24 16:29:12 +02:00
+ if (!(event.isCancelled() || entityareaeffectcloud.isRemoved() || (noEffects && !entityareaeffectcloud.potionContents.hasEffects()))) { // Paper - don't spawn area effect cloud if the effects were empty and not changed during the event handling
2023-06-08 04:04:01 +02:00
this.level().addFreshEntity(entityareaeffectcloud);
} else {
entityareaeffectcloud.discard(null); // CraftBukkit - add Bukkit remove cause
}
// CraftBukkit end
+ return !event.isCancelled(); // Paper - Fix potions splash events
}
public boolean isLingering() {
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
Updated Upstream (Bukkit/CraftBukkit/Spigot) (#11405) Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 1fc1020a PR-1049: Add MenuType API 8ae2e3be PR-1055: Expand riptiding API cac68bfb SPIGOT-7890: AttributeModifier#getUniqueId() doesn't match the UUID passed to its constructor 7004fcf2 SPIGOT-7886: Fix mistake in AttributeModifier UUID shim 1ac7f950 PR-1054: Add FireworkMeta#hasPower 4cfb565f SPIGOT-7873: Add powered state for skulls CraftBukkit Changes: bbb30e7a8 SPIGOT-7894: NPE when sending tile entity update ba21e9472 SPIGOT-7895: PlayerItemBreakEvent not firing 0fb24bbe0 SPIGOT-7875: Fix PlayerItemConsumeEvent cancellation causing client-side desync 815066449 SPIGOT-7891: Can't remove second ingredient of MerchantRecipe 45c206f2c PR-1458: Add MenuType API 19c8ef9ae SPIGOT-7867: Merchant instanceof AbstractVillager always returns false 4e006d28f PR-1468: Expand riptiding API bd8aded7d Ignore checks in CraftPlayerProfile for ResolvableProfile used in profile components 8679620b5 SPIGOT-7889: Fix tool component deserialisation without speed and/or correct-for-drops 8d5222691 SPIGOT-7882, PR-1467: Fix conversion of name in Profile Component to empty if it is missing 63f91669a SPIGOT-7887: Remove duplicate ProjectileHitEvent for fireballs 7070de8c8 SPIGOT-7878: Server#getLootTable does not return null on invalid loot table 060ee6cae SPIGOT-7876: Can't kick player or disconnect player in PlayerLoginEvent when checking for cookies 7ccb86cc0 PR-1465: Add FireworkMeta#hasPower 804ad6491 SPIGOT-7873: Add powered state for skulls f9610cdcb Improve minecart movement Spigot Changes: a759b629 Rebuild patches Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
2024-09-15 21:39:53 +02:00
index 36adcab02e97cae2d087bae74cc4ceaf3052a9f8..b93fa1ea73f0b218e6c6bed8bd36694e26544ab0 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -886,6 +886,32 @@ public class CraftEventFactory {
return event;
}
+ // Paper start - Fix potions splash events
+ public static io.papermc.paper.event.entity.WaterBottleSplashEvent callWaterBottleSplashEvent(net.minecraft.world.entity.projectile.ThrownPotion potion, @Nullable HitResult hitResult, Map<LivingEntity, Double> affectedEntities, java.util.Set<LivingEntity> rehydrate, java.util.Set<LivingEntity> extinguish) {
+ ThrownPotion thrownPotion = (ThrownPotion) potion.getBukkitEntity();
+
+ Block hitBlock = null;
+ BlockFace hitFace = null;
+ org.bukkit.entity.Entity hitEntity = null;
+
+ if (hitResult != null) {
+ if (hitResult.getType() == HitResult.Type.BLOCK) {
+ BlockHitResult blockHitResult = (BlockHitResult) hitResult;
+ hitBlock = CraftBlock.at(potion.level(), blockHitResult.getBlockPos());
+ hitFace = CraftBlock.notchToBlockFace(blockHitResult.getDirection());
+ } else if (hitResult.getType() == HitResult.Type.ENTITY) {
+ hitEntity = ((EntityHitResult) hitResult).getEntity().getBukkitEntity();
+ }
+ }
+
+ io.papermc.paper.event.entity.WaterBottleSplashEvent event = new io.papermc.paper.event.entity.WaterBottleSplashEvent(
+ thrownPotion, hitEntity, hitBlock, hitFace, affectedEntities, rehydrate, extinguish
+ );
+ event.callEvent();
+ return event;
+ }
+ // Paper end - Fix potions splash events
+
/**
* BlockFadeEvent
*/