feat: NPC move event (#3172)

This commit is contained in:
ZX夏夜之风 2024-11-05 22:53:37 +08:00 committed by GitHub
parent 52556f560e
commit 601068c117
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 67 additions and 0 deletions

View File

@ -4,6 +4,7 @@ import java.lang.reflect.Method;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import net.citizensnpcs.api.event.NPCMoveEvent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -214,6 +215,14 @@ public class EventListen implements Listener {
if (pbeac != null) { if (pbeac != null) {
registerPushEvent(pbeac); registerPushEvent(pbeac);
} }
Class<?> paperEntityMoveEventClazz = null;
try {
paperEntityMoveEventClazz = Class.forName("io.papermc.paper.event.entity.EntityMoveEvent");
} catch (ClassNotFoundException e) {
}
if (paperEntityMoveEventClazz != null) {
registerMoveEvent(paperEntityMoveEventClazz);
}
} }
private void checkCreationEvent(CommandSenderCreateNPCEvent event) { private void checkCreationEvent(CommandSenderCreateNPCEvent event) {
@ -937,6 +946,44 @@ public class EventListen implements Listener {
} }
} }
private void registerMoveEvent(Class<?> clazz) {
try {
final HandlerList handlers = (HandlerList) clazz.getMethod("getHandlerList").invoke(null);
final Method getEntity = clazz.getMethod("getEntity");
final Method getFrom = clazz.getMethod("getFrom");
final Method getTo = clazz.getMethod("getTo");
handlers.register(new RegisteredListener(new Listener() {
}, (listener, event) -> {
if (NPCMoveEvent.getHandlerList().getRegisteredListeners().length == 0 || event.getClass() != clazz)
return;
try {
final Entity entity = (Entity) getEntity.invoke(event);
if (!(entity instanceof NPCHolder))
return;
final NPC npc = ((NPCHolder) entity).getNPC();
final Location from = (Location) getFrom.invoke(event);
final Location to = (Location) getTo.invoke(event);
final NPCMoveEvent npcMoveEvent = new NPCMoveEvent(npc, from, to.clone());
Bukkit.getPluginManager().callEvent(npcMoveEvent);
if (!npcMoveEvent.isCancelled()) {
final Location eventTo = npcMoveEvent.getTo();
if (!to.equals(eventTo)) {
Bukkit.getScheduler().runTaskLater(plugin, () -> entity.teleport(eventTo), 1L);
}
} else {
final Location eventFrom = npcMoveEvent.getFrom();
Bukkit.getScheduler().runTaskLater(plugin, () -> entity.teleport(eventFrom), 1L);
}
} catch (Throwable ex) {
ex.printStackTrace();
}
}, EventPriority.NORMAL, plugin, true));
} catch (Throwable ex) {
Messaging.severe("Error registering move event forwarder");
ex.printStackTrace();
}
}
private void respawnAllFromCoord(ChunkCoord coord, Event event) { private void respawnAllFromCoord(ChunkCoord coord, Event event) {
List<NPC> ids = Lists.newArrayList(toRespawn.get(coord)); List<NPC> ids = Lists.newArrayList(toRespawn.get(coord));
if (ids.size() > 0) { if (ids.size() > 0) {

View File

@ -149,6 +149,7 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
onGround = false; onGround = false;
} }
pushEntities(); pushEntities();
NMSImpl.callNPCMoveEvent(this);
if (npc.useMinecraftAI()) { if (npc.useMinecraftAI()) {
foodData.tick(this); foodData.tick(this);
} }

View File

@ -18,6 +18,7 @@ import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import net.citizensnpcs.api.event.NPCMoveEvent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -2208,6 +2209,24 @@ public class NMSImpl implements NMSBridge {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
public static <T extends Entity & NPCHolder> void callNPCMoveEvent(T what) {
final NPC npc = what.getNPC();
if (npc != null && NPCMoveEvent.getHandlerList().getRegisteredListeners().length > 0) {
if (what.xo != what.getX() || what.yo != what.getY() || what.zo != what.getZ() || what.yRotO != what.getYRot() || what.xRotO != what.getXRot()) {
Location from = new Location(what.level().getWorld(), what.xo, what.yo, what.zo, what.yRotO, what.xRotO);
Location to = new Location(what.level().getWorld(), what.getX(), what.getY(), what.getZ(), what.getYRot(), what.getXRot());
final NPCMoveEvent event = new NPCMoveEvent(npc, from, to.clone());
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
final Location eventFrom = event.getFrom();
what.absMoveTo(eventFrom.getX(), eventFrom.getY(), eventFrom.getZ(), eventFrom.getYaw(), eventFrom.getPitch());
} else if (!to.equals(event.getTo())) {
what.absMoveTo(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ(), event.getTo().getYaw(), event.getTo().getPitch());
}
}
}
}
public static TreeMap<?, ?> getBehaviorMap(LivingEntity entity) { public static TreeMap<?, ?> getBehaviorMap(LivingEntity entity) {
try { try {
return (TreeMap<?, ?>) AVAILABLE_BEHAVIORS_BY_PRIORITY.invoke(entity.getBrain()); return (TreeMap<?, ?>) AVAILABLE_BEHAVIORS_BY_PRIORITY.invoke(entity.getBrain());