Skip to content

Commit

Permalink
patch: fire-related events
Browse files Browse the repository at this point in the history
  • Loading branch information
roccodev committed Feb 3, 2021
1 parent 1ac3015 commit 5447230
Show file tree
Hide file tree
Showing 5 changed files with 313 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
language: java
jdk:
- oraclejdk8
- openjdk8
before_install:
- git config --global user.email "travis-ci@destroystokyo.com"
- git config --global user.name "Travis CI"
Expand Down
39 changes: 39 additions & 0 deletions Spigot-API-Patches/0040-Add-EntityExtinguishEvent.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
From 73e6622f2d7dd70017bfbc6ab874cb48d6e209d9 Mon Sep 17 00:00:00 2001
From: RoccoDev <hey@rocco.dev>
Date: Wed, 3 Feb 2021 14:07:48 +0100
Subject: [PATCH] Add EntityExtinguishEvent


diff --git a/src/main/java/org/bukkit/event/entity/EntityExtinguishEvent.java b/src/main/java/org/bukkit/event/entity/EntityExtinguishEvent.java
new file mode 100644
index 00000000..299644c5
--- /dev/null
+++ b/src/main/java/org/bukkit/event/entity/EntityExtinguishEvent.java
@@ -0,0 +1,24 @@
+package org.bukkit.event.entity;
+
+import org.bukkit.entity.Entity;
+import org.bukkit.event.HandlerList;
+
+/**
+ * Called when an entity is about to be extinguished.
+ */
+public class EntityExtinguishEvent extends EntityEvent {
+ private static final HandlerList handlers = new HandlerList();
+
+ public EntityExtinguishEvent(Entity toExtinguish) {
+ super(toExtinguish);
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}
--
2.28.0

45 changes: 45 additions & 0 deletions Spigot-Server-Patches/0132-Add-EntityExtinguishEvent.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
From e77f704b3d018d822cc1f03291d97ca5b379edaf Mon Sep 17 00:00:00 2001
From: RoccoDev <hey@rocco.dev>
Date: Wed, 3 Feb 2021 14:07:45 +0100
Subject: [PATCH] Add EntityExtinguishEvent


diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 219e73729..db66228e7 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -19,6 +19,7 @@ import org.bukkit.entity.Vehicle;
import co.aikar.timings.SpigotTimings; // Spigot
import co.aikar.timings.Timing; // Spigot
import org.bukkit.event.entity.EntityCombustByEntityEvent;
+import org.bukkit.event.entity.EntityExtinguishEvent;
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.painting.PaintingBreakByEntityEvent;
import org.bukkit.event.vehicle.VehicleBlockCollisionEvent;
@@ -147,6 +148,10 @@ public abstract class Entity implements ICommandListener {
* EntityDismountEvent
*/
public boolean ejectingFromBukkit;
+ /**
+ * Used to detect whether the entity was on fire when fire ticks run out
+ */
+ private boolean wasOnFire;
// KigPaper end

public int getId() {
@@ -770,8 +775,12 @@ public abstract class Entity implements ICommandListener {
}

if (flag2 && this.fireTicks > 0) {
+ this.wasOnFire = true; // KigPaper
this.makeSound("random.fizz", 0.7F, 1.6F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F);
this.fireTicks = -this.maxFireTicks;
+ } else if(this.wasOnFire && this.fireTicks <= 0) { // KigPaper
+ this.wasOnFire = false;
+ this.world.getServer().getPluginManager().callEvent(new EntityExtinguishEvent(this.getBukkitEntity()));
}

this.world.methodProfiler.b();
--
2.28.0

194 changes: 194 additions & 0 deletions Spigot-Server-Patches/0133-Fix-EntityCombustByBlockEvent.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
From 11d7cff836634fa5ad05829cbe20b12c6b342cea Mon Sep 17 00:00:00 2001
From: RoccoDev <hey@rocco.dev>
Date: Wed, 3 Feb 2021 15:35:37 +0100
Subject: [PATCH] Fix EntityCombustByBlockEvent


diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index db66228e7..0880142f3 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -18,8 +18,7 @@ import org.bukkit.entity.Painting;
import org.bukkit.entity.Vehicle;
import co.aikar.timings.SpigotTimings; // Spigot
import co.aikar.timings.Timing; // Spigot
-import org.bukkit.event.entity.EntityCombustByEntityEvent;
-import org.bukkit.event.entity.EntityExtinguishEvent;
+import org.bukkit.event.entity.*;
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.painting.PaintingBreakByEntityEvent;
import org.bukkit.event.vehicle.VehicleBlockCollisionEvent;
@@ -29,8 +28,6 @@ import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.entity.CraftEntity;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.craftbukkit.event.CraftEventFactory;
-import org.bukkit.event.entity.EntityCombustEvent;
-import org.bukkit.event.entity.EntityPortalEvent;
import org.bukkit.plugin.PluginManager;
// CraftBukkit end

@@ -377,11 +374,21 @@ public abstract class Entity implements ICommandListener {

protected void burnFromLava() {
if (!this.fireProof) {
- this.damageEntity(DamageSource.LAVA, 4.0F);
+ //this.damageEntity(DamageSource.LAVA, 4.0F); // KigPaper

// CraftBukkit start - Fallen in lava TODO: this event spams!
+ // KigPaper start - https://github.com/Electroid/SportPaper/blob/5ab471494b36601a9c04f2d55efdfde9cc2d5484/patches/server/0035-Fix-combustion-events.patch
+ Vec3D lavaPos = this.world.getLargestBlockIntersection(this.boundingBox.shrink(0.001D, 0.001D, 0.001D), Material.LAVA);
+ org.bukkit.block.Block lavaBlock = lavaPos == null ? null : this.world.getWorld().getBlockAt((int) lavaPos.a, (int) lavaPos.b, (int) lavaPos.c);
+ try {
+ CraftEventFactory.blockDamage = lavaBlock;
+ this.damageEntity(DamageSource.LAVA, 4F);
+ } finally {
+ CraftEventFactory.blockDamage = null;
+ }
+ // KigPaper end
if (this instanceof EntityLiving) {
- if (fireTicks <= 0) {
+ /*if (fireTicks <= 0) {
// not on fire yet
// TODO: shouldn't be sending null for the block
org.bukkit.block.Block damager = null; // ((WorldServer) this.l).getWorld().getBlockAt(i, j, k);
@@ -395,8 +402,17 @@ public abstract class Entity implements ICommandListener {
} else {
// This will be called every single tick the entity is in lava, so don't throw an event
this.setOnFire(15);
+ }*/ // KigPaper start
+ // Note that in order for cancelling or custom duration to work properly,
+ // this event must be fired every tick, thus we cannot avoid "spamming" it.
+ org.bukkit.entity.Entity damagee = this.getBukkitEntity();
+ EntityCombustEvent combustEvent = new org.bukkit.event.entity.EntityCombustByBlockEvent(lavaBlock, damagee, 15);
+ this.world.getServer().getPluginManager().callEvent(combustEvent);
+ if (!combustEvent.isCancelled()) {
+ this.setOnFire(combustEvent.getDuration());
}
return;
+ // KigPaper end
}
// CraftBukkit end - we also don't throw an event unless the object in lava is living, to save on some event calls
this.setOnFire(15);
@@ -752,10 +768,17 @@ public abstract class Entity implements ICommandListener {
// CraftBukkit end

boolean flag2 = this.U();
-
- if (this.world.e(this.getBoundingBox().shrink(0.001D, 0.001D, 0.001D))) {
- this.burn(1);
- if (!flag2) {
+ // KigPaper start - https://github.com/Electroid/SportPaper/blob/5ab471494b36601a9c04f2d55efdfde9cc2d5484/patches/server/0035-Fix-combustion-events.patch
+ Vec3D firePos = this.world.getLargestBlockIntersection(this.boundingBox.shrink(0.001D, 0.001D, 0.001D), Material.FIRE);
+ if (firePos != null) {
+ org.bukkit.block.Block fireBlock = this.bukkitEntity.getWorld().getBlockAt((int) firePos.a, (int) firePos.b, (int) firePos.c);
+ try {
+ CraftEventFactory.blockDamage = fireBlock;
+ this.burn(1);
+ } finally {
+ CraftEventFactory.blockDamage = null;
+ }
+ if (!flag2) {/*
++this.fireTicks;
// CraftBukkit start - Not on fire yet
if (this.fireTicks <= 0) { // Only throw events on the first combust, otherwise it spams
@@ -768,8 +791,22 @@ public abstract class Entity implements ICommandListener {
} else {
// CraftBukkit end
this.setOnFire(8);
+ }*/
+ EntityCombustByBlockEvent event = new EntityCombustByBlockEvent(fireBlock, this.getBukkitEntity(), 8);
+ this.world.getServer().getPluginManager().callEvent(event);
+ if (!event.isCancelled()) {
+ // Note carefully how this works: when fireTicks is negative, the entity is
+ // "heating up" but not on fire yet. When fireTicks reaches 0, the entity
+ // "ignites" and fireTicks jumps to 160. It will then stay at that value as
+ // long as the player remains in fire (because the ++ below will cancel out
+ // the -- in the entity tick). For the event cancelling to work, it has to
+ // be fired every tick, thus we cannot avoid "spamming" it.
+ ++this.fireTicks;
+ if (this.fireTicks == 0) {
+ this.setOnFire(event.getDuration());
+ }
}
- }
+ } // KigPaper end
} else if (this.fireTicks <= 0) {
this.fireTicks = -this.maxFireTicks;
}
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 8f3511f80..12e6f607a 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -3269,4 +3269,33 @@ public abstract class World implements IBlockAccess {

return k >= -short0 && k <= short0 && l >= -short0 && l <= short0 && this.keepSpawnInMemory; // CraftBukkit - Added 'this.keepSpawnInMemory'
}
+
+ // KigPaper start - https://github.com/Electroid/SportPaper/blob/5ab471494b36601a9c04f2d55efdfde9cc2d5484/patches/server/0035-Fix-combustion-events.patch
+ public Vec3D getLargestBlockIntersection(AxisAlignedBB aabb, Material material) {
+ int xMin = MathHelper.floor(aabb.a);
+ int xMax = MathHelper.floor(aabb.d + 1.0D);
+ int yMin = MathHelper.floor(aabb.b);
+ int yMax = MathHelper.floor(aabb.e + 1.0D);
+ int zMin = MathHelper.floor(aabb.c);
+ int zMax = MathHelper.floor(aabb.f + 1.0D);
+ double maxVolume = 0;
+ Vec3D block = null;
+ for (int x = xMin; x < xMax; ++x) {
+ for (int y = yMin; y < yMax; ++y) {
+ for (int z = zMin; z < zMax; ++z) {
+ IBlockData type = this.getType(new BlockPosition(x, y, z));
+ if (material == type.getBlock().getMaterial()) {
+ AxisAlignedBB i = new AxisAlignedBB(x, x+1, y, y+1, z, z+1).a(aabb);
+ double volume = (i.d - i.a) * (i.e - i.b) * (i.f - i.c);
+ if(volume > maxVolume) {
+ maxVolume = volume;
+ block = new Vec3D(x, y, z);
+ }
+ }
+ }
+ }
+ }
+ return block;
+ }
+ // KigPaper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index da902708b..cc99e7597 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -470,18 +470,16 @@ public class CraftEventFactory {
event.getEntity().setLastDamageCause(event);
}
return event;
- } else if (source == DamageSource.LAVA) {
- EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.LAVA, modifiers, modifierFunctions));
- if (!event.isCancelled()) {
- event.getEntity().setLastDamageCause(event);
- }
- return event;
} else if (blockDamage != null) {
DamageCause cause = null;
Block damager = blockDamage;
blockDamage = null;
if (source == DamageSource.CACTUS) {
cause = DamageCause.CONTACT;
+ } else if(source == DamageSource.FIRE) { // KigPaper
+ cause = DamageCause.FIRE;
+ } else if(source == DamageSource.LAVA) { // KigPaper
+ cause = DamageCause.LAVA;
} else {
throw new RuntimeException(String.format("Unhandled damage of %s by %s from %s", entity, damager, source.translationIndex)); // Spigot
}
@@ -513,6 +511,8 @@ public class CraftEventFactory {
DamageCause cause = null;
if (source == DamageSource.FIRE) {
cause = DamageCause.FIRE;
+ } else if (source == DamageSource.LAVA) {
+ cause = DamageCause.LAVA;
} else if (source == DamageSource.STARVE) {
cause = DamageCause.STARVATION;
} else if (source == DamageSource.WITHER) {
--
2.28.0

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
From 3bb81871d338258019a82f7cd3b160a7f6f9de80 Mon Sep 17 00:00:00 2001
From: RoccoDev <hey@rocco.dev>
Date: Wed, 3 Feb 2021 15:50:35 +0100
Subject: [PATCH] Fix extinguish event implementation


diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 0880142f3..85a6a6300 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -812,13 +812,18 @@ public abstract class Entity implements ICommandListener {
}

if (flag2 && this.fireTicks > 0) {
- this.wasOnFire = true; // KigPaper
this.makeSound("random.fizz", 0.7F, 1.6F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F);
this.fireTicks = -this.maxFireTicks;
- } else if(this.wasOnFire && this.fireTicks <= 0) { // KigPaper
+ }
+
+ // KigPaper start
+ if(this.fireTicks > 0) {
+ this.wasOnFire = true;
+ } else if(this.wasOnFire) { // KigPaper
this.wasOnFire = false;
this.world.getServer().getPluginManager().callEvent(new EntityExtinguishEvent(this.getBukkitEntity()));
}
+ // KigPaper end

this.world.methodProfiler.b();
}
--
2.28.0

0 comments on commit 5447230

Please sign in to comment.