Tweak PlayerDeathEvent to not use npc.getEntity()

This commit is contained in:
fullwall 2023-09-01 02:36:04 +08:00
parent 6c80f7554d
commit 7c0eb422a6
1 changed files with 62 additions and 42 deletions

View File

@ -220,6 +220,7 @@ public class EventListen implements Listener {
if (Messaging.isDebugging() && Setting.DEBUG_CHUNK_LOADS.asBoolean() && toRespawn.containsKey(coord)) { if (Messaging.isDebugging() && Setting.DEBUG_CHUNK_LOADS.asBoolean() && toRespawn.containsKey(coord)) {
new Exception("CITIZENS CHUNK LOAD DEBUG " + coord).printStackTrace(); new Exception("CITIZENS CHUNK LOAD DEBUG " + coord).printStackTrace();
} }
if (event instanceof Cancellable) { if (event instanceof Cancellable) {
runnable.run(); runnable.run();
} else { } else {
@ -267,7 +268,9 @@ public class EventListen implements Listener {
NPC npc = CitizensAPI.getNPCRegistry().getNPC(event.getEntity()); NPC npc = CitizensAPI.getNPCRegistry().getNPC(event.getEntity());
if (npc == null) if (npc == null)
return; return;
event.setCancelled(npc.isProtected()); event.setCancelled(npc.isProtected());
if (event instanceof EntityCombustByEntityEvent) { if (event instanceof EntityCombustByEntityEvent) {
Bukkit.getPluginManager().callEvent(new NPCCombustByEntityEvent((EntityCombustByEntityEvent) event, npc)); Bukkit.getPluginManager().callEvent(new NPCCombustByEntityEvent((EntityCombustByEntityEvent) event, npc));
} else if (event instanceof EntityCombustByBlockEvent) { } else if (event instanceof EntityCombustByBlockEvent) {
@ -321,9 +324,8 @@ public class EventListen implements Listener {
@EventHandler(ignoreCancelled = true) @EventHandler(ignoreCancelled = true)
public void onEntityDeath(EntityDeathEvent event) { public void onEntityDeath(EntityDeathEvent event) {
final NPC npc = CitizensAPI.getNPCRegistry().getNPC(event.getEntity()); final NPC npc = CitizensAPI.getNPCRegistry().getNPC(event.getEntity());
if (npc == null) { if (npc == null)
return; return;
}
if (!npc.data().get(NPC.Metadata.DROPS_ITEMS, false)) { if (!npc.data().get(NPC.Metadata.DROPS_ITEMS, false)) {
event.getDrops().clear(); event.getDrops().clear();
@ -336,6 +338,7 @@ public class EventListen implements Listener {
int delay = npc.data().get(NPC.Metadata.RESPAWN_DELAY, -1); int delay = npc.data().get(NPC.Metadata.RESPAWN_DELAY, -1);
if (delay < 0) if (delay < 0)
return; return;
int deathAnimationTicks = event.getEntity() instanceof LivingEntity ? 20 : 2; int deathAnimationTicks = event.getEntity() instanceof LivingEntity ? 20 : 2;
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> { Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
if (!npc.isSpawned() && npc.getOwningRegistry().getByUniqueId(npc.getUniqueId()) == npc) { if (!npc.isSpawned() && npc.getOwningRegistry().getByUniqueId(npc.getUniqueId()) == npc) {
@ -375,6 +378,7 @@ public class EventListen implements Listener {
NPC npc = CitizensAPI.getNPCRegistry().getNPC(event.getTarget()); NPC npc = CitizensAPI.getNPCRegistry().getNPC(event.getTarget());
if (npc == null) if (npc == null)
return; return;
event.setCancelled(!npc.data().get(NPC.Metadata.TARGETABLE, !npc.isProtected())); event.setCancelled(!npc.data().get(NPC.Metadata.TARGETABLE, !npc.isProtected()));
Bukkit.getPluginManager().callEvent(new EntityTargetNPCEvent(event, npc)); Bukkit.getPluginManager().callEvent(new EntityTargetNPCEvent(event, npc));
} }
@ -384,6 +388,7 @@ public class EventListen implements Listener {
NPC npc = CitizensAPI.getNPCRegistry().getNPC(event.getEntity()); NPC npc = CitizensAPI.getNPCRegistry().getNPC(event.getEntity());
if (npc == null) if (npc == null)
return; return;
event.setCancelled(true); event.setCancelled(true);
} }
@ -457,6 +462,7 @@ public class EventListen implements Listener {
skinUpdateTracker.updatePlayer(event.getPlayer(), 20, true); skinUpdateTracker.updatePlayer(event.getPlayer(), 20, true);
if (CitizensAPI.getNPCRegistry().getNPC(event.getPlayer()) == null) if (CitizensAPI.getNPCRegistry().getNPC(event.getPlayer()) == null)
return; return;
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> { Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
NMS.replaceTracker(event.getPlayer()); NMS.replaceTracker(event.getPlayer());
NMS.removeFromServerPlayerList(event.getPlayer()); NMS.removeFromServerPlayerList(event.getPlayer());
@ -472,13 +478,12 @@ public class EventListen implements Listener {
@EventHandler(ignoreCancelled = true) @EventHandler(ignoreCancelled = true)
public void onPlayerDeath(PlayerDeathEvent event) { public void onPlayerDeath(PlayerDeathEvent event) {
final NPC npc = CitizensAPI.getNPCRegistry().getNPC(event.getEntity()); NPC npc = CitizensAPI.getNPCRegistry().getNPC(event.getEntity());
if (npc == null) { if (npc == null)
return; return;
}
if (npc.requiresNameHologram()) { if (npc.requiresNameHologram()) {
event.setDeathMessage(event.getDeathMessage().replace(npc.getEntity().getName(), npc.getFullName())); event.setDeathMessage(event.getDeathMessage().replace(event.getEntity().getName(), npc.getFullName()));
} }
} }
@ -493,44 +498,50 @@ public class EventListen implements Listener {
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) { public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
NPC npc = CitizensAPI.getNPCRegistry().getNPC(event.getRightClicked()); NPC npc = CitizensAPI.getNPCRegistry().getNPC(event.getRightClicked());
if (npc == null || Util.isOffHand(event)) { if (npc == null || Util.isOffHand(event))
return; return;
}
if (npc.hasTrait(ClickRedirectTrait.class)) { ClickRedirectTrait crt = npc.getTraitNullable(ClickRedirectTrait.class);
npc = npc.getTraitNullable(ClickRedirectTrait.class).getRedirectNPC(); if (crt != null && (npc = crt.getRedirectNPC()) == null)
if (npc == null) return;
return;
}
Player player = event.getPlayer(); Player player = event.getPlayer();
NPCRightClickEvent rightClickEvent = new NPCRightClickEvent(npc, player); NPCRightClickEvent rightClickEvent = new NPCRightClickEvent(npc, player);
if (event.getPlayer().getItemInHand().getType() == Material.NAME_TAG) { if (event.getPlayer().getItemInHand().getType() == Material.NAME_TAG) {
rightClickEvent.setCancelled(npc.isProtected()); rightClickEvent.setCancelled(npc.isProtected());
} }
Bukkit.getPluginManager().callEvent(rightClickEvent); Bukkit.getPluginManager().callEvent(rightClickEvent);
if (rightClickEvent.isCancelled()) { if (rightClickEvent.isCancelled()) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
if (SUPPORT_STOP_USE_ITEM) {
try {
PlayerAnimation.STOP_USE_ITEM.play(player);
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),
() -> PlayerAnimation.STOP_USE_ITEM.play(player));
} catch (UnsupportedOperationException e) {
SUPPORT_STOP_USE_ITEM = false;
}
}
if (npc.hasTrait(CommandTrait.class)) { if (npc.hasTrait(CommandTrait.class)) {
npc.getTraitNullable(CommandTrait.class).dispatch(player, CommandTrait.Hand.RIGHT); npc.getTraitNullable(CommandTrait.class).dispatch(player, CommandTrait.Hand.RIGHT);
rightClickEvent.setDelayedCancellation(true); rightClickEvent.setDelayedCancellation(true);
} }
if (npc.hasTrait(ShopTrait.class)) { if (npc.hasTrait(ShopTrait.class)) {
npc.getTraitNullable(ShopTrait.class).onRightClick(player); npc.getTraitNullable(ShopTrait.class).onRightClick(player);
rightClickEvent.setDelayedCancellation(true); rightClickEvent.setDelayedCancellation(true);
} }
if (rightClickEvent.isDelayedCancellation()) { if (rightClickEvent.isDelayedCancellation()) {
event.setCancelled(true); event.setCancelled(true);
} }
if (event.isCancelled()) {
if (SUPPORT_STOP_USE_ITEM) {
try {
PlayerAnimation.STOP_USE_ITEM.play(player);
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),
() -> PlayerAnimation.STOP_USE_ITEM.play(player));
} catch (UnsupportedOperationException e) {
SUPPORT_STOP_USE_ITEM = false;
}
}
}
} }
@EventHandler(priority = EventPriority.MONITOR) @EventHandler(priority = EventPriority.MONITOR)
@ -543,9 +554,9 @@ public class EventListen implements Listener {
@EventHandler(ignoreCancelled = true) @EventHandler(ignoreCancelled = true)
public void onPlayerLeashEntity(PlayerLeashEntityEvent event) { public void onPlayerLeashEntity(PlayerLeashEntityEvent event) {
NPC npc = CitizensAPI.getNPCRegistry().getNPC(event.getEntity()); NPC npc = CitizensAPI.getNPCRegistry().getNPC(event.getEntity());
if (npc == null) { if (npc == null)
return; return;
}
boolean leashProtected = npc.isProtected(); boolean leashProtected = npc.isProtected();
if (npc.data().get(NPC.Metadata.LEASH_PROTECTED, leashProtected)) { if (npc.data().get(NPC.Metadata.LEASH_PROTECTED, leashProtected)) {
event.setCancelled(true); event.setCancelled(true);
@ -568,6 +579,7 @@ public class EventListen implements Listener {
event.getPlayer().leaveVehicle(); event.getPlayer().leaveVehicle();
} }
} }
skinUpdateTracker.removePlayer(event.getPlayer().getUniqueId()); skinUpdateTracker.removePlayer(event.getPlayer().getUniqueId());
CitizensAPI.getLocationLookup().onQuit(event); CitizensAPI.getLocationLookup().onQuit(event);
} }
@ -583,16 +595,14 @@ public class EventListen implements Listener {
if (event.getCause() == TeleportCause.PLUGIN && !event.getPlayer().hasMetadata("citizens-force-teleporting") if (event.getCause() == TeleportCause.PLUGIN && !event.getPlayer().hasMetadata("citizens-force-teleporting")
&& npc != null && Setting.PLAYER_TELEPORT_DELAY.asTicks() > 0) { && npc != null && Setting.PLAYER_TELEPORT_DELAY.asTicks() > 0) {
event.setCancelled(true); event.setCancelled(true);
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() { Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
@Override event.getPlayer().setMetadata("citizens-force-teleporting",
public void run() { new FixedMetadataValue(CitizensAPI.getPlugin(), true));
event.getPlayer().setMetadata("citizens-force-teleporting", event.getPlayer().teleport(event.getTo());
new FixedMetadataValue(CitizensAPI.getPlugin(), true)); event.getPlayer().removeMetadata("citizens-force-teleporting", CitizensAPI.getPlugin());
event.getPlayer().teleport(event.getTo());
event.getPlayer().removeMetadata("citizens-force-teleporting", CitizensAPI.getPlugin());
}
}, Setting.PLAYER_TELEPORT_DELAY.asTicks()); }, Setting.PLAYER_TELEPORT_DELAY.asTicks());
} }
skinUpdateTracker.updatePlayer(event.getPlayer(), 15, true); skinUpdateTracker.updatePlayer(event.getPlayer(), 15, true);
} }
@ -615,6 +625,7 @@ public class EventListen implements Listener {
NPC npc = CitizensAPI.getNPCRegistry().getNPC(entity); NPC npc = CitizensAPI.getNPCRegistry().getNPC(entity);
if (npc == null) if (npc == null)
continue; continue;
if (npc.isProtected()) { if (npc.isProtected()) {
event.setIntensity(entity, 0); event.setIntensity(entity, 0);
} }
@ -634,6 +645,7 @@ public class EventListen implements Listener {
if (n++ > 5) { if (n++ > 5) {
cancel(); cancel();
} }
NMS.removeHookIfNecessary(CitizensAPI.getNPCRegistry(), (FishHook) event.getEntity()); NMS.removeHookIfNecessary(CitizensAPI.getNPCRegistry(), (FishHook) event.getEntity());
} }
}.runTaskTimer(CitizensAPI.getPlugin(), 0, 1); }.runTaskTimer(CitizensAPI.getPlugin(), 0, 1);
@ -642,9 +654,9 @@ public class EventListen implements Listener {
@EventHandler @EventHandler
public void onVehicleDamage(VehicleDamageEvent event) { public void onVehicleDamage(VehicleDamageEvent event) {
NPC npc = CitizensAPI.getNPCRegistry().getNPC(event.getVehicle()); NPC npc = CitizensAPI.getNPCRegistry().getNPC(event.getVehicle());
if (npc == null) { if (npc == null)
return; return;
}
event.setCancelled(npc.isProtected()); event.setCancelled(npc.isProtected());
NPCVehicleDamageEvent damageEvent = new NPCVehicleDamageEvent(npc, event); NPCVehicleDamageEvent damageEvent = new NPCVehicleDamageEvent(npc, event);
@ -652,6 +664,7 @@ public class EventListen implements Listener {
if (!damageEvent.isCancelled() || !(damageEvent.getDamager() instanceof Player)) if (!damageEvent.isCancelled() || !(damageEvent.getDamager() instanceof Player))
return; return;
Player damager = (Player) damageEvent.getDamager(); Player damager = (Player) damageEvent.getDamager();
NPCLeftClickEvent leftClickEvent = new NPCLeftClickEvent(npc, damager); NPCLeftClickEvent leftClickEvent = new NPCLeftClickEvent(npc, damager);
@ -664,9 +677,9 @@ public class EventListen implements Listener {
@EventHandler @EventHandler
public void onVehicleDestroy(VehicleDestroyEvent event) { public void onVehicleDestroy(VehicleDestroyEvent event) {
NPC npc = CitizensAPI.getNPCRegistry().getNPC(event.getVehicle()); NPC npc = CitizensAPI.getNPCRegistry().getNPC(event.getVehicle());
if (npc == null) { if (npc == null)
return; return;
}
event.setCancelled(npc.isProtected()); event.setCancelled(npc.isProtected());
} }
@ -701,6 +714,7 @@ public class EventListen implements Listener {
for (NPC npc : getAllNPCs()) { for (NPC npc : getAllNPCs()) {
if (npc == null || !npc.isSpawned() || !npc.getEntity().getWorld().equals(event.getWorld())) if (npc == null || !npc.isSpawned() || !npc.getEntity().getWorld().equals(event.getWorld()))
continue; continue;
boolean despawned = npc.despawn(DespawnReason.WORLD_UNLOAD); boolean despawned = npc.despawn(DespawnReason.WORLD_UNLOAD);
if (event.isCancelled() || !despawned) { if (event.isCancelled() || !despawned) {
for (ChunkCoord coord : toRespawn.keySet()) { for (ChunkCoord coord : toRespawn.keySet()) {
@ -711,6 +725,7 @@ public class EventListen implements Listener {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
if (npc.isSpawned()) { if (npc.isSpawned()) {
toRespawn.put(new ChunkCoord(npc.getEntity().getLocation()), npc); toRespawn.put(new ChunkCoord(npc.getEntity().getLocation()), npc);
Messaging.debug("Despawned", npc, "due to world unload at", event.getWorld().getName()); Messaging.debug("Despawned", npc, "due to world unload at", event.getWorld().getName());
@ -788,22 +803,26 @@ public class EventListen implements Listener {
if (ids.size() > 0) { if (ids.size() > 0) {
Messaging.debug("Respawning all NPCs at", coord, "due to", event); Messaging.debug("Respawning all NPCs at", coord, "due to", event);
} }
for (int i = 0; i < ids.size(); i++) { for (int i = 0; i < ids.size(); i++) {
NPC npc = ids.get(i); NPC npc = ids.get(i);
if (npc.getOwningRegistry().getById(npc.getId()) != npc) { if (npc.getOwningRegistry().getById(npc.getId()) != npc) {
Messaging.idebug(() -> "Prevented deregistered NPC from respawning " + npc); Messaging.idebug(() -> "Prevented deregistered NPC from respawning " + npc);
continue; continue;
} }
if (npc.isSpawned()) { if (npc.isSpawned()) {
Messaging.idebug(() -> "Can't respawn NPC " + npc + ": already spawned"); Messaging.idebug(() -> "Can't respawn NPC " + npc + ": already spawned");
continue; continue;
} }
boolean success = spawn(npc); boolean success = spawn(npc);
if (!success) { if (!success) {
ids.remove(i--); ids.remove(i--);
Messaging.idebug(() -> Joiner.on(' ').join("Couldn't respawn", npc, "during", event, "at", coord)); Messaging.idebug(() -> Joiner.on(' ').join("Couldn't respawn", npc, "during", event, "at", coord));
continue; continue;
} }
Messaging.idebug(() -> Joiner.on(' ').join("Spawned", npc, "during", event, "at", coord)); Messaging.idebug(() -> Joiner.on(' ').join("Spawned", npc, "during", event, "at", coord));
} }
for (NPC npc : ids) { for (NPC npc : ids) {
@ -830,8 +849,10 @@ public class EventListen implements Listener {
continue; continue;
toDespawn.add(npc); toDespawn.add(npc);
} }
if (toDespawn.isEmpty()) if (toDespawn.isEmpty())
return; return;
ChunkCoord coord = new ChunkCoord(event.getChunk()); ChunkCoord coord = new ChunkCoord(event.getChunk());
boolean loadChunk = false; boolean loadChunk = false;
for (NPC npc : toDespawn) { for (NPC npc : toDespawn) {
@ -842,6 +863,7 @@ public class EventListen implements Listener {
toRespawn.put(coord, npc); toRespawn.put(coord, npc);
continue; continue;
} }
((Cancellable) event).setCancelled(true); ((Cancellable) event).setCancelled(true);
Messaging.debug("Cancelled chunk unload at", coord); Messaging.debug("Cancelled chunk unload at", coord);
respawnAllFromCoord(coord, event); respawnAllFromCoord(coord, event);
@ -853,14 +875,12 @@ public class EventListen implements Listener {
if (Messaging.isDebugging() && Setting.DEBUG_CHUNK_LOADS.asBoolean()) { if (Messaging.isDebugging() && Setting.DEBUG_CHUNK_LOADS.asBoolean()) {
new Exception("CITIZENS CHUNK UNLOAD DEBUG " + coord).printStackTrace(); new Exception("CITIZENS CHUNK UNLOAD DEBUG " + coord).printStackTrace();
} }
if (loadChunk) { if (loadChunk) {
Messaging.idebug(() -> Joiner.on(' ').join("Loading chunk in 10 ticks due to forced chunk load at", coord)); Messaging.idebug(() -> Joiner.on(' ').join("Loading chunk in 10 ticks due to forced chunk load at", coord));
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() { Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
@Override if (!event.getChunk().isLoaded()) {
public void run() { event.getChunk().load();
if (!event.getChunk().isLoaded()) {
event.getChunk().load();
}
} }
}, 10); }, 10);
} }