Skip to content

Commit 085bf4e

Browse files
Copilottastybento
andauthored
Fix: skip InvincibleVisitors targeting cancellation for XP orbs
Agent-Logs-Url: https://github.com/BentoBoxWorld/BentoBox/sessions/19b02680-6fb9-456c-9cae-a1c06b2d716b Co-authored-by: tastybento <4407265+tastybento@users.noreply.github.com>
1 parent f4bd1ab commit 085bf4e

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/InvincibleVisitorsListener.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import org.bukkit.Material;
99
import org.bukkit.Sound;
1010
import org.bukkit.World;
11+
import org.bukkit.entity.ExperienceOrb;
1112
import org.bukkit.entity.Player;
1213
import org.bukkit.event.EventHandler;
1314
import org.bukkit.event.EventPriority;
@@ -185,6 +186,7 @@ public void onVisitorTargeting(EntityTargetLivingEntityEvent e)
185186
if (!(e.getTarget() instanceof Player p) ||
186187
!this.getIWM().inWorld(world) ||
187188
e.getTarget().hasMetadata("NPC") ||
189+
e.getEntity() instanceof ExperienceOrb ||
188190
this.getIslands().userIsOnIsland(world, User.getInstance(e.getTarget())) ||
189191
this.isPvpAllowed(p.getLocation()) ||
190192
e.getReason() == EntityTargetEvent.TargetReason.TARGET_DIED ||

src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/InvincibleVisitorsListenerTest.java

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,13 @@
2626
import org.bukkit.Location;
2727
import org.bukkit.World;
2828
import org.bukkit.World.Environment;
29+
import org.bukkit.entity.ExperienceOrb;
2930
import org.bukkit.entity.LivingEntity;
31+
import org.bukkit.entity.Zombie;
3032
import org.bukkit.event.entity.EntityDamageEvent;
3133
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
34+
import org.bukkit.event.entity.EntityTargetEvent.TargetReason;
35+
import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
3236
import org.bukkit.event.inventory.ClickType;
3337
import org.bukkit.inventory.Inventory;
3438
import org.bukkit.inventory.ItemStack;
@@ -291,4 +295,59 @@ void testOnVisitorGetDamageVoidPlayerHasIsland() {
291295
verify(im).homeTeleportAsync(any(), eq(mockPlayer));
292296
verify(pim).callEvent(any(InvincibleVistorFlagDamageRemovalEvent.class));
293297
}
298+
299+
/**
300+
* Test that onVisitorTargeting cancels mob targeting of a visitor when ENTITY_ATTACK is in IV settings.
301+
*/
302+
@Test
303+
void testOnVisitorTargetingCancelsMobTargeting() {
304+
ivSettings.add(DamageCause.ENTITY_ATTACK.name());
305+
Zombie zombie = mock(Zombie.class);
306+
when(zombie.getWorld()).thenReturn(world);
307+
EntityTargetLivingEntityEvent e = new EntityTargetLivingEntityEvent(zombie, mockPlayer, TargetReason.CLOSEST_PLAYER);
308+
listener.onVisitorTargeting(e);
309+
assertTrue(e.isCancelled());
310+
}
311+
312+
/**
313+
* Test that onVisitorTargeting does NOT cancel experience orb targeting of a visitor.
314+
* XP orbs should still be able to track visitors for pickup, regardless of IV settings.
315+
*/
316+
@Test
317+
void testOnVisitorTargetingDoesNotCancelExperienceOrbTargeting() {
318+
ivSettings.add(DamageCause.ENTITY_ATTACK.name());
319+
ExperienceOrb orb = mock(ExperienceOrb.class);
320+
when(orb.getWorld()).thenReturn(world);
321+
EntityTargetLivingEntityEvent e = new EntityTargetLivingEntityEvent(orb, mockPlayer, TargetReason.CLOSEST_PLAYER);
322+
listener.onVisitorTargeting(e);
323+
assertFalse(e.isCancelled());
324+
}
325+
326+
/**
327+
* Test that onVisitorTargeting does not cancel when entity_attack is not in IV settings.
328+
*/
329+
@Test
330+
void testOnVisitorTargetingNotInIvSettings() {
331+
// ENTITY_ATTACK is not in ivSettings by default
332+
Zombie zombie = mock(Zombie.class);
333+
when(zombie.getWorld()).thenReturn(world);
334+
EntityTargetLivingEntityEvent e = new EntityTargetLivingEntityEvent(zombie, mockPlayer, TargetReason.CLOSEST_PLAYER);
335+
listener.onVisitorTargeting(e);
336+
assertFalse(e.isCancelled());
337+
}
338+
339+
/**
340+
* Test that onVisitorTargeting does not cancel when user is on their own island.
341+
*/
342+
@Test
343+
void testOnVisitorTargetingNotVisitor() {
344+
ivSettings.add(DamageCause.ENTITY_ATTACK.name());
345+
when(im.userIsOnIsland(any(), any())).thenReturn(true);
346+
Zombie zombie = mock(Zombie.class);
347+
when(zombie.getWorld()).thenReturn(world);
348+
EntityTargetLivingEntityEvent e = new EntityTargetLivingEntityEvent(zombie, mockPlayer, TargetReason.CLOSEST_PLAYER);
349+
listener.onVisitorTargeting(e);
350+
assertFalse(e.isCancelled());
351+
}
352+
294353
}

0 commit comments

Comments
 (0)