diff --git a/src/main/java/world/bentobox/bentobox/listeners/BlockEndDragon.java b/src/main/java/world/bentobox/bentobox/listeners/BlockEndDragon.java index dbbf544d8..acd550177 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/BlockEndDragon.java +++ b/src/main/java/world/bentobox/bentobox/listeners/BlockEndDragon.java @@ -1,17 +1,23 @@ package world.bentobox.bentobox.listeners; import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.World.Environment; +import org.bukkit.entity.EnderDragon; import org.bukkit.entity.EntityType; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.world.ChunkLoadEvent; import world.bentobox.bentobox.BentoBox; @@ -30,6 +36,8 @@ public class BlockEndDragon implements Listener { private BentoBox plugin; + private Set enderDragons = new HashSet<>(); + public BlockEndDragon(BentoBox plugin) { this.plugin = plugin; } @@ -42,19 +50,31 @@ public class BlockEndDragon implements Listener { */ @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public boolean onDragonSpawn(CreatureSpawnEvent e) { - if (!e.getEntityType().equals(EntityType.ENDER_DRAGON) || plugin.getIWM().isDragonSpawn(e.getEntity().getWorld())) { + if (!e.getSpawnReason().equals(SpawnReason.NATURAL) + || !e.getEntityType().equals(EntityType.ENDER_DRAGON) + || plugin.getIWM().isDragonSpawn(e.getEntity().getWorld())) { return true; } - e.getEntity().setHealth(0); - e.getEntity().remove(); - e.setCancelled(true); + EnderDragon d = (EnderDragon)e.getEntity(); + d.getBossBar().setVisible(false); + d.setHealth(0); + enderDragons.add(d.getUniqueId()); return false; } + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onDragonDeath(EntityDeathEvent e) { + if (enderDragons.contains(e.getEntity().getUniqueId())) { + plugin.logDebug("removing drops"); + e.setDroppedExp(0); + e.getDrops().clear(); + enderDragons.remove(e.getEntity().getUniqueId()); + } + } /** * This listener aims to delete the end trophy from the end when it is generated - * It is added by special code in the server that can't be overidden so the only + * It is added by special code in the server that can't be overridden so the only * option is to delete it manually. This means that any island at 0,0 will have * a dead zone of a few blocks directly above it. Hopefully this will not be a * major issue. diff --git a/src/test/java/world/bentobox/bentobox/listeners/BlockEndDragonTest.java b/src/test/java/world/bentobox/bentobox/listeners/BlockEndDragonTest.java index 634891d5a..375fde942 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/BlockEndDragonTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/BlockEndDragonTest.java @@ -7,9 +7,12 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import org.bukkit.Bukkit; +import org.bukkit.boss.BossBar; +import org.bukkit.entity.EnderDragon; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; @@ -35,7 +38,7 @@ public class BlockEndDragonTest { public void testOnDragonSpawnWrongEntityOkayToSpawn() { LivingEntity le = mock(LivingEntity.class); when(le.getType()).thenReturn(EntityType.AREA_EFFECT_CLOUD); - CreatureSpawnEvent event = new CreatureSpawnEvent(le, null); + CreatureSpawnEvent event = new CreatureSpawnEvent(le, SpawnReason.NATURAL); BentoBox plugin = mock(BentoBox.class); IslandWorldManager iwm = mock(IslandWorldManager.class); when(plugin.getIWM()).thenReturn(iwm); @@ -50,7 +53,7 @@ public class BlockEndDragonTest { public void testOnDragonSpawnWrongEntityNoDragonSpawn() { LivingEntity le = mock(LivingEntity.class); when(le.getType()).thenReturn(EntityType.AREA_EFFECT_CLOUD); - CreatureSpawnEvent event = new CreatureSpawnEvent(le, null); + CreatureSpawnEvent event = new CreatureSpawnEvent(le, SpawnReason.NATURAL); BentoBox plugin = mock(BentoBox.class); IslandWorldManager iwm = mock(IslandWorldManager.class); when(plugin.getIWM()).thenReturn(iwm); @@ -63,9 +66,9 @@ public class BlockEndDragonTest { @Test public void testOnDragonSpawnRightEntityOkayToSpawn() { - LivingEntity le = mock(LivingEntity.class); + EnderDragon le = mock(EnderDragon.class); when(le.getType()).thenReturn(EntityType.ENDER_DRAGON); - CreatureSpawnEvent event = new CreatureSpawnEvent(le, null); + CreatureSpawnEvent event = new CreatureSpawnEvent(le, SpawnReason.NATURAL); BentoBox plugin = mock(BentoBox.class); IslandWorldManager iwm = mock(IslandWorldManager.class); when(plugin.getIWM()).thenReturn(iwm); @@ -78,9 +81,10 @@ public class BlockEndDragonTest { @Test public void testOnDragonSpawnRightEntityNotOkayToSpawn() { - LivingEntity le = mock(LivingEntity.class); + EnderDragon le = mock(EnderDragon.class); + when(le.getBossBar()).thenReturn(mock(BossBar.class)); when(le.getType()).thenReturn(EntityType.ENDER_DRAGON); - CreatureSpawnEvent event = new CreatureSpawnEvent(le, null); + CreatureSpawnEvent event = new CreatureSpawnEvent(le, SpawnReason.NATURAL); BentoBox plugin = mock(BentoBox.class); IslandWorldManager iwm = mock(IslandWorldManager.class); when(plugin.getIWM()).thenReturn(iwm); @@ -88,9 +92,6 @@ public class BlockEndDragonTest { when(iwm.isDragonSpawn(Mockito.any())).thenReturn(false); BlockEndDragon bed = new BlockEndDragon(plugin); assertFalse(bed.onDragonSpawn(event)); - Mockito.verify(le).remove(); - Mockito.verify(le).setHealth(0); - assertTrue(event.isCancelled()); } }