From 5a5435d8151918f91bb0c4f553212f4be3b6e3a7 Mon Sep 17 00:00:00 2001 From: tastybento Date: Thu, 17 Sep 2020 08:09:39 -0700 Subject: [PATCH] Let Citizens handle its own PVP protection. https://github.com/BentoBoxWorld/BentoBox/issues/1518 --- .../listeners/flags/settings/PVPListener.java | 12 ++++----- .../flags/settings/PVPListenerTest.java | 27 +++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/settings/PVPListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/settings/PVPListener.java index e5d541496..0a39e2ad7 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/settings/PVPListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/settings/PVPListener.java @@ -50,8 +50,8 @@ public class PVPListener extends FlagListener { @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void onEntityDamage(EntityDamageByEntityEvent e) { if (e.getEntity() instanceof Player && getPlugin().getIWM().inWorld(e.getEntity().getWorld())) { - // Allow self damage - if (e.getEntity().equals(e.getDamager())) { + // Allow self damage or NPC attack because Citizens handles its own PVP + if (e.getEntity().equals(e.getDamager()) || e.getEntity().hasMetadata("NPC")) { return; } // Protect visitors @@ -112,8 +112,8 @@ public class PVPListener extends FlagListener { @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void onFishing(PlayerFishEvent e) { if (e.getCaught() instanceof Player && getPlugin().getIWM().inWorld(e.getCaught().getLocation())) { - // Allow self-inflicted damage - if (e.getCaught().equals(e.getPlayer())) { + // Allow self-inflicted damage or NPC damage + if (e.getCaught().equals(e.getPlayer()) || e.getCaught().hasMetadata("NPC")) { return; } // Protect visitors @@ -154,8 +154,8 @@ public class PVPListener extends FlagListener { * @return true if PVP should be blocked otherwise false */ private boolean blockPVP(User user, LivingEntity le, Event e, Flag flag) { - // Check for self-inflicted damage - if (le.equals(user.getPlayer())) { + // Check for self-inflicted damage or Citizen NPCs + if (le.equals(user.getPlayer()) || le.hasMetadata("NPC")) { return false; } if (le instanceof Player) { diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/settings/PVPListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/flags/settings/PVPListenerTest.java index cfcc0e8ee..b67dd9706 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/settings/PVPListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/settings/PVPListenerTest.java @@ -273,6 +273,25 @@ public class PVPListenerTest { assertFalse(e.isCancelled()); } + /** + * Test method for {@link PVPListener#onEntityDamage(org.bukkit.event.entity.EntityDamageByEntityEvent)}. + */ + @Test + public void testOnEntityDamageNPC() { + // Player 2 is an NPC + when(player2.hasMetadata(eq("NPC"))).thenReturn(true); + // PVP is not allowed + when(island.isAllowed(any())).thenReturn(false); + EntityDamageByEntityEvent e = new EntityDamageByEntityEvent(player, player2, EntityDamageEvent.DamageCause.ENTITY_ATTACK, + new EnumMap<>(ImmutableMap.of(DamageModifier.BASE, 0D)), + new EnumMap>(ImmutableMap.of(DamageModifier.BASE, Functions.constant(-0.0)))); + new PVPListener().onEntityDamage(e); + // PVP should be allowed for NPC + assertFalse(e.isCancelled()); + verify(player, never()).sendMessage(Flags.PVP_OVERWORLD.getHintReference()); + + } + /** * Test method for {@link PVPListener#onEntityDamage(org.bukkit.event.entity.EntityDamageByEntityEvent)}. */ @@ -671,6 +690,14 @@ public class PVPListenerTest { new PVPListener().onFishing(pfe); assertFalse(pfe.isCancelled()); + // Disallow PVP , attack on NPC + when(player2.hasMetadata(eq("NPC"))).thenReturn(true); + when(island.isAllowed(any())).thenReturn(false); + pfe = new PlayerFishEvent(player, player2, hook, null); + new PVPListener().onFishing(pfe); + assertFalse(pfe.isCancelled()); + + // Wrong world wrongWorld(); pfe = new PlayerFishEvent(player, player2, hook, null);