Split the animal/monster spawn flags to "natural" and "spawners"

Implements https://github.com/BentoBoxWorld/BentoBox/issues/1351
This commit is contained in:
Florian CUNY 2020-06-21 17:47:01 +02:00
parent aa9a4d16f1
commit cbbd361b03
4 changed files with 53 additions and 35 deletions

View File

@ -2,21 +2,22 @@ package world.bentobox.bentobox.listeners.flags.settings;
import java.util.Optional;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.PufferFish;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.CreatureSpawnEvent;
import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.flags.FlagListener;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.lists.Flags;
import world.bentobox.bentobox.util.Util;
/**
* Handles natural mob spawning.
* @author tastybento
*
*/
public class MobSpawnListener extends FlagListener {
@ -27,7 +28,7 @@ public class MobSpawnListener extends FlagListener {
* @return true if cancelled
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public boolean onNaturalMobSpawn(CreatureSpawnEvent e) {
public boolean onMobSpawn(CreatureSpawnEvent e) {
// If not in the right world, or spawning is not natural return
if (!getIWM().inWorld(e.getEntity().getLocation())) {
return false;
@ -50,22 +51,27 @@ public class MobSpawnListener extends FlagListener {
case TRAP:
case VILLAGE_DEFENSE:
case VILLAGE_INVASION:
// Deal with natural spawning
Optional<Island> island = getIslands().getIslandAt(e.getLocation());
// Cancel the event if these are true
if (Util.isHostileEntity(e.getEntity()) && !(e.getEntity() instanceof PufferFish)) {
boolean cancel = island.map(i -> !i.isAllowed(Flags.MONSTER_SPAWN)).orElse(!Flags.MONSTER_SPAWN.isSetForWorld(e.getEntity().getWorld()));
e.setCancelled(cancel);
return cancel;
} else if (Util.isPassiveEntity(e.getEntity()) || e.getEntity() instanceof PufferFish) {
boolean cancel = island.map(i -> !i.isAllowed(Flags.ANIMAL_SPAWN)).orElse(!Flags.ANIMAL_SPAWN.isSetForWorld(e.getEntity().getWorld()));
e.setCancelled(cancel);
return cancel;
}
return false;
boolean cancelNatural = shouldCancel(e.getEntity(), e.getLocation(), Flags.ANIMAL_NATURAL_SPAWN, Flags.MONSTER_NATURAL_SPAWN);
e.setCancelled(cancelNatural);
return cancelNatural;
// Spawners
case SPAWNER:
boolean cancelSpawners = shouldCancel(e.getEntity(), e.getLocation(), Flags.ANIMAL_SPAWNERS_SPAWN, Flags.MONSTER_SPAWNERS_SPAWN);
e.setCancelled(cancelSpawners);
return cancelSpawners;
default:
return false;
}
}
private boolean shouldCancel(Entity entity, Location loc, Flag animalSpawnFlag, Flag monsterSpawnFlag) {
Optional<Island> island = getIslands().getIslandAt(loc);
if (Util.isHostileEntity(entity) && !(entity instanceof PufferFish)) {
return island.map(i -> !i.isAllowed(monsterSpawnFlag)).orElse(!monsterSpawnFlag.isSetForWorld(entity.getWorld()));
} else if (Util.isPassiveEntity(entity) || entity instanceof PufferFish) {
return island.map(i -> !i.isAllowed(animalSpawnFlag)).orElse(!animalSpawnFlag.isSetForWorld(entity.getWorld()));
}
return false;
}
}

View File

@ -468,6 +468,7 @@ public final class Flags {
/**
* Provides a list of all the Flag instances contained in this class using reflection.
* Deprecated Flags are
* @return List of all the flags in this class
*/
public static List<Flag> values() {

View File

@ -681,9 +681,12 @@ ranks:
protection:
command-is-banned: "Command is banned for visitors"
flags:
ANIMAL_SPAWN:
description: "Toggle natural spawning"
name: "Animal spawning"
ANIMAL_NATURAL_SPAWN:
description: "Toggle natural animal spawning"
name: "Animal natural spawn"
ANIMAL_SPAWNERS_SPAWN:
description: "Toggle animal spawning with spawners"
name: "Animal spawners"
ANVIL:
description: "Toggle interaction"
name: "Anvils"
@ -1011,9 +1014,12 @@ protection:
name: "Minecarts"
description: "Toggle minecart interactions"
hint: "Minecart interaction disabled"
MONSTER_SPAWN:
description: "Toggle natural spawning"
name: "Monster spawning"
MONSTER_NATURAL_SPAWN:
description: "Toggle natural monster spawning"
name: "Monster natural spawn"
MONSTER_SPAWNERS_SPAWN:
description: "Toggle monster spawning with spawners"
name: "Monster spawners"
MOUNT_INVENTORY:
description: |-
&a Toggle access

View File

@ -143,7 +143,7 @@ public class MobSpawnListenerTest {
when(plugin.isLoaded()).thenReturn(false);
CreatureSpawnEvent e = new CreatureSpawnEvent(livingEntity, SpawnReason.NATURAL);
MobSpawnListener l = new MobSpawnListener();
assertFalse(l.onNaturalMobSpawn(e));
assertFalse(l.onMobSpawn(e));
assertFalse(e.isCancelled());
}
@ -171,7 +171,7 @@ public class MobSpawnListenerTest {
when(e.getEntity()).thenReturn(entity);
// Should not be canceled
assertFalse(l.onNaturalMobSpawn(e));
assertFalse(l.onMobSpawn(e));
}
@Test
@ -225,9 +225,13 @@ public class MobSpawnListenerTest {
case VILLAGE_DEFENSE:
case VILLAGE_INVASION:
// These should be blocked
assertTrue("Should be blocked: " + reason.toString(), l.onNaturalMobSpawn(e));
assertTrue("Natural spawn should be blocked: " + reason.toString(), l.onMobSpawn(e));
break;
// Unnatural - player involved
// Spawners
case SPAWNER:
assertTrue("Spawners spawn should be blocked: " + reason.toString(), l.onMobSpawn(e));
break;
// Unnatural - player involved
case BREEDING:
case BUILD_IRONGOLEM:
case BUILD_SNOWMAN:
@ -241,9 +245,8 @@ public class MobSpawnListenerTest {
case INFECTION:
case SHEARED:
case SHOULDER_ENTITY:
case SPAWNER:
case SPAWNER_EGG:
assertFalse("Should be not blocked: " + reason.toString(), l.onNaturalMobSpawn(e));
assertFalse("Should be not blocked: " + reason.toString(), l.onMobSpawn(e));
break;
default:
break;
@ -285,9 +288,8 @@ public class MobSpawnListenerTest {
private void checkUnBlocked(CreatureSpawnEvent e, MobSpawnListener l) {
for (SpawnReason reason: SpawnReason.values()) {
when(e.getSpawnReason()).thenReturn(reason);
assertFalse(l.onNaturalMobSpawn(e));
assertFalse(l.onMobSpawn(e));
}
}
@Test
@ -297,8 +299,10 @@ public class MobSpawnListenerTest {
when(im.getIslandAt(any())).thenReturn(Optional.empty());
// Block mobs
Flags.MONSTER_SPAWN.setDefaultSetting(false);
Flags.ANIMAL_SPAWN.setDefaultSetting(false);
Flags.MONSTER_NATURAL_SPAWN.setDefaultSetting(false);
Flags.ANIMAL_NATURAL_SPAWN.setDefaultSetting(false);
Flags.MONSTER_SPAWNERS_SPAWN.setDefaultSetting(false);
Flags.ANIMAL_SPAWNERS_SPAWN.setDefaultSetting(false);
// Setup event
CreatureSpawnEvent e = mock(CreatureSpawnEvent.class);
when(e.getLocation()).thenReturn(location);
@ -325,8 +329,10 @@ public class MobSpawnListenerTest {
when(im.getIslandAt(any())).thenReturn(Optional.empty());
// Block mobs
Flags.MONSTER_SPAWN.setDefaultSetting(true);
Flags.ANIMAL_SPAWN.setDefaultSetting(true);
Flags.MONSTER_NATURAL_SPAWN.setDefaultSetting(true);
Flags.ANIMAL_NATURAL_SPAWN.setDefaultSetting(true);
Flags.MONSTER_SPAWNERS_SPAWN.setDefaultSetting(true);
Flags.ANIMAL_SPAWNERS_SPAWN.setDefaultSetting(true);
// Setup event
CreatureSpawnEvent e = mock(CreatureSpawnEvent.class);
@ -344,7 +350,6 @@ public class MobSpawnListenerTest {
// Check animal
when(e.getEntity()).thenReturn(cow);
checkUnBlocked(e,l);
}
}