1
0
mirror of https://github.com/PaperMC/Paper.git synced 2025-02-20 06:22:13 +01:00

EndermanEscapeEvent

Fires an event anytime an enderman intends to teleport away from the player

You may cancel this, enabling ranged attacks to damage the enderman for example.

Resolves 
This commit is contained in:
Aikar 2018-04-30 13:16:42 -04:00
parent 4fd6aedac9
commit 2c7a08b1df
2 changed files with 167 additions and 0 deletions
Spigot-API-Patches
Spigot-Server-Patches

View File

@ -0,0 +1,88 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 30 Apr 2018 13:14:30 -0400
Subject: [PATCH] EndermanEscapeEvent
Fires an event anytime an enderman intends to teleport away from the player
You may cancel this, enabling ranged attacks to damage the enderman for example.
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EndermanEscapeEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EndermanEscapeEvent.java
new file mode 100644
index 00000000..958c66b3
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EndermanEscapeEvent.java
@@ -0,0 +0,0 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.Enderman;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+
+public class EndermanEscapeEvent extends EntityEvent implements Cancellable {
+ private final Reason reason;
+
+ public EndermanEscapeEvent(Enderman entity, Reason reason) {
+ super(entity);
+ this.reason = reason;
+ }
+
+ /**
+ * @return The reason the enderman is trying to escape
+ */
+ public Reason getReason() {
+ return reason;
+ }
+
+ private static final HandlerList handlers = new HandlerList();
+
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+
+ private boolean cancelled = false;
+
+ @Override
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ /**
+ * Cancels the escape.
+ *
+ * If this escape normally would of resulted in damage avoidance such as indirect,
+ * the enderman will now take damage.
+ *
+ * @param cancel true if you wish to cancel this event
+ */
+ @Override
+ public void setCancelled(boolean cancel) {
+ cancelled = cancel;
+ }
+
+ public enum Reason {
+ /**
+ * The enderman has stopped attacking and ran away
+ */
+ RUNAWAY,
+ /**
+ * The enderman has teleported away due to indirect damage (ranged)
+ */
+ INDIRECT,
+ /**
+ * The enderman has teleported away due to a critical hit
+ */
+ CRITICAL_HIT,
+ /**
+ * The enderman has teleported away due to the player staring at it during combat
+ */
+ STARE
+ }
+}
--

View File

@ -0,0 +1,79 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 30 Apr 2018 13:15:55 -0400
Subject: [PATCH] EndermanEscapeEvent
Fires an event anytime an enderman intends to teleport away from the player
You may cancel this, enabling ranged attacks to damage the enderman for example.
diff --git a/src/main/java/net/minecraft/server/EntityEnderman.java b/src/main/java/net/minecraft/server/EntityEnderman.java
index 2f59e7071..7b1fb6b7b 100644
--- a/src/main/java/net/minecraft/server/EntityEnderman.java
+++ b/src/main/java/net/minecraft/server/EntityEnderman.java
@@ -0,0 +0,0 @@
package net.minecraft.server;
+import com.destroystokyo.paper.event.entity.EndermanEscapeEvent;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster {
setGoalTarget(entityliving, EntityTargetEvent.TargetReason.UNKNOWN, true);
}
+ // Paper start
+ private boolean tryEscape(EndermanEscapeEvent.Reason reason) {
+ return new EndermanEscapeEvent((org.bukkit.craftbukkit.entity.CraftEnderman) this.getBukkitEntity(), reason).callEvent();
+ }
+ // Paper end
+
@Override
public boolean setGoalTarget(EntityLiving entityliving, org.bukkit.event.entity.EntityTargetEvent.TargetReason reason, boolean fireEvent) {
if (!super.setGoalTarget(entityliving, reason, fireEvent)) {
@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster {
if (f > 0.5F && this.world.h(new BlockPosition(this)) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F) {
this.setGoalTarget((EntityLiving) null);
- this.dm();
+ if (tryEscape(EndermanEscapeEvent.Reason.RUNAWAY)) this.dm(); // Paper
}
}
@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster {
public boolean damageEntity(DamageSource damagesource, float f) {
if (this.isInvulnerable(damagesource)) {
return false;
- } else if (damagesource instanceof EntityDamageSourceIndirect) {
+ } else if (damagesource instanceof EntityDamageSourceIndirect && tryEscape(EndermanEscapeEvent.Reason.INDIRECT)) { // Paper
for (int i = 0; i < 64; ++i) {
if (this.dm()) {
return true;
@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster {
} else {
boolean flag = super.damageEntity(damagesource, f);
- if (damagesource.ignoresArmor() && this.random.nextInt(10) != 0) {
+ if (damagesource.ignoresArmor() && this.random.nextInt(10) != 0 && tryEscape(EndermanEscapeEvent.Reason.CRITICAL_HIT)) { // Paper
this.dm();
}
@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster {
static class PathfinderGoalPlayerWhoLookedAtTarget extends PathfinderGoalNearestAttackableTarget<EntityHuman> {
- private final EntityEnderman i;
+ private final EntityEnderman i; public EntityEnderman getEnderman() { return i; } // Paper - OBFHELPER
private EntityHuman j;
private int k;
private int l;
@@ -0,0 +0,0 @@ public class EntityEnderman extends EntityMonster {
} else {
if (this.d != null) {
if (this.i.f((EntityHuman) this.d)) {
- if (((EntityHuman) this.d).h(this.i) < 16.0D) {
+ if (((EntityHuman) this.d).h(this.i) < 16.0D && this.getEnderman().tryEscape(EndermanEscapeEvent.Reason.STARE)) { // Paper
this.i.dm();
}
--