Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions patches/api/0426-Add-EntityExtinguishEvent.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aurora <aurora@relanet.eu>
Date: Sat, 20 Mar 2021 18:14:24 +0100
Subject: [PATCH] Add EntityExtinguishEvent


diff --git a/src/main/java/io/papermc/paper/event/entity/EntityExtinguishEvent.java b/src/main/java/io/papermc/paper/event/entity/EntityExtinguishEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..7fd4a5be843f76a362f7df8a14d7796936cb6bed
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/entity/EntityExtinguishEvent.java
@@ -0,0 +1,83 @@
+package io.papermc.paper.event.entity;
+
+import org.bukkit.entity.Entity;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Called when a burning {@link Entity} is extinguished.
+ */
+public class EntityExtinguishEvent extends EntityEvent implements Cancellable {
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+ private final Cause cause;
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public EntityExtinguishEvent(final @NotNull Entity entity, final @NotNull Cause cause) {
+ super(entity);
+ this.cause = cause;
+ }
+
+ @NotNull
+ public Cause getCause() {
+ return cause;
+ }
+
+ @Override
+ public void setCancelled(boolean cancelled) {
+ this.cancelled = cancelled;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return this.cancelled;
+ }
+
+ public enum Cause {
+ /**
+ * Extinguish caused by entity standing in water.
+ */
+ WATER,
+ /**
+ * Extinguish caused by entity standing in the rain.
+ */
+ RAIN,
+ /**
+ * Extinguish caused by entity standing in a bubble column.
+ */
+ BUBBLE_COLUMN,
+ /**
+ * Extinguish caused by entity standing in a cauldron with water.
+ */
+ CAULDRON,
+ /**
+ * Extinguish caused by entity dying.
+ */
+ DEATH,
+ /**
+ * Extinguish caused by fire ticks running out.
+ */
+ TIME,
+ /**
+ * Extinguish caused by standing in powdered snow.
+ */
+ POWDER_SNOW,
+ /**
+ * Extinguish caused by being splashed with a water bottle.
+ */
+ WATER_BOTTLE
+ }
+
+ @Override
+ @NotNull
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}
172 changes: 172 additions & 0 deletions patches/server/1005-Add-EntityExtinguishEvent.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aurora <aurora@relanet.eu>
Date: Sat, 20 Mar 2021 18:14:43 +0100
Subject: [PATCH] Add EntityExtinguishEvent

Adds a new EntityExtinguishEvent and fixes two extinguish related vanilla bugs

https://bugs.mojang.com/browse/MC-245603: Powder snow can not put out the fire on arrows
https://bugs.mojang.com/browse/MC-214647: Burning arrows do not make a sound when extinguished

== AT ==
public net/minecraft/world/entity/Entity playEntityOnFireExtinguishedSound()V

Co-authored-by: Warrior <50800980+Warriorrrr@users.noreply.github.com>

diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index dc5fda83a66afbfeb7897fc20b4742899d8aca08..060c0036829d3b419216ad122e88c4d93223b6f1 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -1034,6 +1034,7 @@ public class ServerPlayer extends Player {
this.awardStat(Stats.DEATHS);
this.resetStat(Stats.CUSTOM.get(Stats.TIME_SINCE_DEATH));
this.resetStat(Stats.CUSTOM.get(Stats.TIME_SINCE_REST));
+ if (this.getRemainingFireTicks() > 0) new io.papermc.paper.event.entity.EntityExtinguishEvent(this.getBukkitEntity(), io.papermc.paper.event.entity.EntityExtinguishEvent.Cause.DEATH).callEvent(); // Paper - add EntityExtinguishEvent
this.clearFire();
this.setTicksFrozen(0);
this.setSharedFlagOnFire(false);
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 2edab21bb271405f200de5a19e9c748bb14aba7d..9fac6e96aa314f9011f5b3dd22458a81e70ec64e 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -846,7 +846,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
this.hurt(this.damageSources().onFire(), 1.0F);
}

+ // Paper start - add EntityExtinguishEvent
+ if (getRemainingFireTicks() - 1 == 0 && !new io.papermc.paper.event.entity.EntityExtinguishEvent(this.getBukkitEntity(), io.papermc.paper.event.entity.EntityExtinguishEvent.Cause.TIME).callEvent()) {
+ setRemainingFireTicks(20);
+ } else {
this.setRemainingFireTicks(this.remainingFireTicks - 1);
+ }
+ // Paper end
}

if (this.getTicksFrozen() > 0 && !freezeLocked) { // Paper - Freeze Tick Lock API
@@ -1274,6 +1280,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
}

if (this.isOnFire() && (this.isInPowderSnow || this.isInWaterRainOrBubble())) {
+ if (this.callExtinguishEvent(iblockdata)) // Paper - add EntityExtinguishEvent
this.setRemainingFireTicks(-this.getFireImmuneTicks());
}

@@ -1855,7 +1862,14 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {

this.resetFallDistance();
this.wasTouchingWater = true;
- this.clearFire();
+ // Paper start - add EntityExtinguishEvent and fix MC-214647
+ if (this.getRemainingFireTicks() <= 0 || new io.papermc.paper.event.entity.EntityExtinguishEvent(this.getBukkitEntity(), io.papermc.paper.event.entity.EntityExtinguishEvent.Cause.WATER).callEvent()) {
+ if (this.getRemainingFireTicks() > 0 && this instanceof net.minecraft.world.entity.projectile.AbstractArrow)
+ this.playEntityOnFireExtinguishedSound();
+
+ this.clearFire();
+ }
+ // Paper end
} else {
this.wasTouchingWater = false;
}
@@ -4793,4 +4807,25 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
return ((net.minecraft.server.level.ServerChunkCache) level.getChunkSource()).isPositionTicking(this);
}
// Paper end
+ // Paper start
+ public boolean callExtinguishEvent(@Nullable BlockState state) {
+ final io.papermc.paper.event.entity.EntityExtinguishEvent.Cause cause;
+ final boolean onFire = getRemainingFireTicks() > 0;
+ if (!onFire) {
+ cause = null;
+ } else if (this.isInPowderSnow || (state != null && state.is(Blocks.POWDER_SNOW))) {
+ cause = io.papermc.paper.event.entity.EntityExtinguishEvent.Cause.POWDER_SNOW;
+ } else if (this.isInWater()) {
+ cause = io.papermc.paper.event.entity.EntityExtinguishEvent.Cause.WATER;
+ } else if (this.isInRain()) {
+ cause = io.papermc.paper.event.entity.EntityExtinguishEvent.Cause.RAIN;
+ } else if (this.isInBubbleColumn()) {
+ cause = io.papermc.paper.event.entity.EntityExtinguishEvent.Cause.BUBBLE_COLUMN;
+ } else {
+ cause = null;
+ }
+
+ return cause == null || new io.papermc.paper.event.entity.EntityExtinguishEvent(this.getBukkitEntity(), cause).callEvent();
+ }
+ // Paper end
}
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index e11d7283662834047b2ff81a2fd25a4263792deb..c98f3a14cb844318573176fe1f8f1e6fc31fa479 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -468,6 +468,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
}

if (this.isAlive() && (this.isInWaterRainOrBubble() || this.isInPowderSnow)) {
+ if (callExtinguishEvent(null)) // Paper - add EntityExtinguishEvent
this.extinguishFire();
}

@@ -1719,6 +1720,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
entity.killedEntity((ServerLevel) this.level(), this);
}
this.gameEvent(GameEvent.ENTITY_DIE);
+ if (this.getRemainingFireTicks() > 0) new io.papermc.paper.event.entity.EntityExtinguishEvent(this.getBukkitEntity(), io.papermc.paper.event.entity.EntityExtinguishEvent.Cause.DEATH).callEvent(); // Paper - add EntityExtinguishEvent
} else {
this.dead = false;
this.setHealth((float) deathEvent.getReviveHealth());
diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
index 7226be19248a1ffb8ff2c89b55882529d33a6c0c..530888d95165a8d7ee918c16aebd18a4b1f8c217 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
@@ -188,6 +188,7 @@ public abstract class AbstractArrow extends Projectile {
}

if (this.isInWaterOrRain() || iblockdata.is(Blocks.POWDER_SNOW)) {
+ if (this.callExtinguishEvent(iblockdata)) // Paper - add EntityExtinguishEvent
this.clearFire();
}

diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
index 29ea746b6df87e996081149000c6db0b562f7e97..2795c9757756262528ec969521925bc5e4d09c92 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
@@ -166,6 +166,7 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
((CraftLivingEntity) affectedEntity).getHandle().hurt(this.damageSources().indirectMagic(this, this.getOwner()), 1.0F);
}
for (LivingEntity toExtinguish : event.getToExtinguish()) {
+ if (new io.papermc.paper.event.entity.EntityExtinguishEvent(toExtinguish, io.papermc.paper.event.entity.EntityExtinguishEvent.Cause.WATER_BOTTLE).callEvent()) // Paper - add EntityExtinguishEvent
((CraftLivingEntity) toExtinguish).getHandle().extinguishFire();
}
for (LivingEntity toRehydrate : event.getToRehydrate()) {
diff --git a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
index e11eced0bf15dfecaf64f5e1c28e973c38746095..d2905a0ccb6813a9421b547b6d58dfcc43828ee9 100644
--- a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
@@ -68,6 +68,7 @@ public class LayeredCauldronBlock extends AbstractCauldronBlock {
return;
}
}
+ if (new io.papermc.paper.event.entity.EntityExtinguishEvent(entity.getBukkitEntity(), io.papermc.paper.event.entity.EntityExtinguishEvent.Cause.CAULDRON).callEvent()) // Paper - add EntityExtinguishEvent
entity.clearFire();
// CraftBukkit end
}
diff --git a/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java b/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java
index 7e04ecba2a14be0f0d47c917368abd2a2bd64a05..79c733c5ebc983416e57adb347a7f3bdc55e449f 100644
--- a/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java
@@ -76,6 +76,16 @@ public class PowderSnowBlock extends Block implements BucketPickup {
return;
}
// CraftBukkit end
+ // Paper start - add EntityExtinguishEvent and fix MC-245603
+ if (entity instanceof net.minecraft.world.entity.projectile.AbstractArrow) {
+ if (!new io.papermc.paper.event.entity.EntityExtinguishEvent(entity.getBukkitEntity(), io.papermc.paper.event.entity.EntityExtinguishEvent.Cause.POWDER_SNOW).callEvent()) {
+ return;
+ }
+
+ entity.playEntityOnFireExtinguishedSound(); // wasOnFire is false, so play sound manually
+ entity.clearFire();
+ }
+ // Paper end
world.destroyBlock(pos, false);
}