mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-11-26 04:35:43 +01:00
Merge pull request #2508 from BentoBoxWorld/2507_Allow_creepers_to_hurt_but_not_destroy_blocks
Change how creeper damage flag works. #2507
This commit is contained in:
commit
e90755d73d
@ -141,7 +141,6 @@ public class Settings implements ConfigObject {
|
|||||||
private Set<String> fakePlayers = new HashSet<>();
|
private Set<String> fakePlayers = new HashSet<>();
|
||||||
|
|
||||||
/* PANELS */
|
/* PANELS */
|
||||||
|
|
||||||
@ConfigComment("Toggle whether panels should be closed or not when the player clicks anywhere outside of the inventory view.")
|
@ConfigComment("Toggle whether panels should be closed or not when the player clicks anywhere outside of the inventory view.")
|
||||||
@ConfigEntry(path = "panel.close-on-click-outside")
|
@ConfigEntry(path = "panel.close-on-click-outside")
|
||||||
private boolean closePanelOnClickOutside = true;
|
private boolean closePanelOnClickOutside = true;
|
||||||
@ -189,6 +188,13 @@ public class Settings implements ConfigObject {
|
|||||||
/*
|
/*
|
||||||
* Island
|
* Island
|
||||||
*/
|
*/
|
||||||
|
@ConfigComment("Override island distance mismatch checking. BentoBox normally refuses to run if")
|
||||||
|
@ConfigComment("the island distance in the gamemode config is different to the one stored in the database")
|
||||||
|
@ConfigComment("for safety. This overrides that check. You should never need this, and if you do not understand it")
|
||||||
|
@ConfigComment("keep it as false")
|
||||||
|
@ConfigEntry(path = "island.override-safety-check")
|
||||||
|
private boolean overrideSafetyCheck = false;
|
||||||
|
|
||||||
// Number of islands
|
// Number of islands
|
||||||
@ConfigComment("The default number of concurrent islands a player may have.")
|
@ConfigComment("The default number of concurrent islands a player may have.")
|
||||||
@ConfigComment("This may be overridden by individual game mode config settings.")
|
@ConfigComment("This may be overridden by individual game mode config settings.")
|
||||||
@ -1034,4 +1040,18 @@ public class Settings implements ConfigObject {
|
|||||||
this.hideUsedBlueprints = hideUsedBlueprints;
|
this.hideUsedBlueprints = hideUsedBlueprints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the overrideSafetyCheck
|
||||||
|
*/
|
||||||
|
public boolean isOverrideSafetyCheck() {
|
||||||
|
return overrideSafetyCheck;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param overrideSafetyCheck the overrideSafetyCheck to set
|
||||||
|
*/
|
||||||
|
public void setOverrideSafetyCheck(boolean overrideSafetyCheck) {
|
||||||
|
this.overrideSafetyCheck = overrideSafetyCheck;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,6 @@ import org.bukkit.entity.EntityType;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
|
||||||
import org.bukkit.event.entity.EntityDamageEvent;
|
|
||||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||||
|
|
||||||
@ -40,9 +38,10 @@ public class CreeperListener extends FlagListener {
|
|||||||
if (!Flags.CREEPER_DAMAGE.isSetForWorld(e.getLocation().getWorld())) {
|
if (!Flags.CREEPER_DAMAGE.isSetForWorld(e.getLocation().getWorld())) {
|
||||||
// If any were removed, then prevent damage too
|
// If any were removed, then prevent damage too
|
||||||
e.blockList().clear();
|
e.blockList().clear();
|
||||||
e.setCancelled(true);
|
// Still allow player and mob damage
|
||||||
return;
|
e.setCancelled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for griefing
|
// Check for griefing
|
||||||
Creeper creeper = (Creeper)e.getEntity();
|
Creeper creeper = (Creeper)e.getEntity();
|
||||||
if (!Flags.CREEPER_GRIEFING.isSetForWorld(e.getLocation().getWorld())
|
if (!Flags.CREEPER_GRIEFING.isSetForWorld(e.getLocation().getWorld())
|
||||||
@ -55,25 +54,6 @@ public class CreeperListener extends FlagListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prevent entities being damaged by explosion
|
|
||||||
* @param e - event
|
|
||||||
* @since 1.10.0
|
|
||||||
*/
|
|
||||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
|
||||||
public void onExplosion(final EntityDamageByEntityEvent e) {
|
|
||||||
if (!e.getCause().equals(EntityDamageEvent.DamageCause.ENTITY_EXPLOSION) || !getIWM().inWorld(e.getEntity().getLocation())
|
|
||||||
|| !e.getDamager().getType().equals(EntityType.CREEPER)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// If creeper damage is not allowed in world cancel the damage
|
|
||||||
if (!Flags.CREEPER_DAMAGE.isSetForWorld(e.getEntity().getWorld())) {
|
|
||||||
e.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevent creepers from igniting if they are not allowed to grief
|
* Prevent creepers from igniting if they are not allowed to grief
|
||||||
* @param e - event
|
* @param e - event
|
||||||
|
@ -1267,7 +1267,8 @@ public class IslandsManager {
|
|||||||
// These will be deleted later
|
// These will be deleted later
|
||||||
deletedIslands.add(island.getUniqueId());
|
deletedIslands.add(island.getUniqueId());
|
||||||
} // Check island distance and if incorrect stop BentoBox
|
} // Check island distance and if incorrect stop BentoBox
|
||||||
else if (island.getWorld() != null && plugin.getIWM().inWorld(island.getWorld())
|
else if (!plugin.getSettings().isOverrideSafetyCheck() && island.getWorld() != null
|
||||||
|
&& plugin.getIWM().inWorld(island.getWorld())
|
||||||
&& island.getRange() != plugin.getIWM().getIslandDistance(island.getWorld())) {
|
&& island.getRange() != plugin.getIWM().getIslandDistance(island.getWorld())) {
|
||||||
throw new IOException("Island distance mismatch!\n" + "World '" + island.getWorld().getName()
|
throw new IOException("Island distance mismatch!\n" + "World '" + island.getWorld().getName()
|
||||||
+ "' distance " + plugin.getIWM().getIslandDistance(island.getWorld()) + " != island range "
|
+ "' distance " + plugin.getIWM().getIslandDistance(island.getWorld()) + " != island range "
|
||||||
|
@ -0,0 +1,136 @@
|
|||||||
|
package world.bentobox.bentobox.listeners.flags.worldsettings;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.Creeper;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||||
|
import org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
|
||||||
|
import world.bentobox.bentobox.BentoBox;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
import world.bentobox.bentobox.listeners.flags.AbstractCommonSetup;
|
||||||
|
import world.bentobox.bentobox.lists.Flags;
|
||||||
|
import world.bentobox.bentobox.util.Util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@RunWith(PowerMockRunner.class)
|
||||||
|
@PrepareForTest({ Bukkit.class, BentoBox.class, Flags.class, Util.class })
|
||||||
|
public class CreeperListenerTest extends AbstractCommonSetup {
|
||||||
|
|
||||||
|
private CreeperListener cl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws java.lang.Exception
|
||||||
|
*/
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
|
||||||
|
cl = new CreeperListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws java.lang.Exception
|
||||||
|
*/
|
||||||
|
@After
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
User.clearUsers();
|
||||||
|
Mockito.framework().clearInlineMocks();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.bentobox.listeners.flags.worldsettings.CreeperListener#onExplosion(org.bukkit.event.entity.EntityExplodeEvent)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testOnExplosionNotCreeper() {
|
||||||
|
List<Block> list = new ArrayList<>();
|
||||||
|
Entity entity = mock(Entity.class);
|
||||||
|
when(entity.getType()).thenReturn(EntityType.TNT);
|
||||||
|
when(iwm.inWorld(location)).thenReturn(true);
|
||||||
|
EntityExplodeEvent event = new EntityExplodeEvent(entity, location, list, 0);
|
||||||
|
cl.onExplosion(event);
|
||||||
|
assertFalse(event.isCancelled());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.bentobox.listeners.flags.worldsettings.CreeperListener#onExplosion(org.bukkit.event.entity.EntityExplodeEvent)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testOnExplosionNotInWorld() {
|
||||||
|
List<Block> list = new ArrayList<>();
|
||||||
|
Entity entity = mock(Entity.class);
|
||||||
|
when(entity.getLocation()).thenReturn(location);
|
||||||
|
when(entity.getType()).thenReturn(EntityType.CREEPER);
|
||||||
|
when(iwm.inWorld(location)).thenReturn(false);
|
||||||
|
EntityExplodeEvent event = new EntityExplodeEvent(entity, location, list, 0);
|
||||||
|
cl.onExplosion(event);
|
||||||
|
assertFalse(event.isCancelled());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.bentobox.listeners.flags.worldsettings.CreeperListener#onExplosion(org.bukkit.event.entity.EntityExplodeEvent)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testOnExplosionCreeperInWorldDamageOK() {
|
||||||
|
List<Block> list = new ArrayList<>();
|
||||||
|
list.add(mock(Block.class));
|
||||||
|
list.add(mock(Block.class));
|
||||||
|
list.add(mock(Block.class));
|
||||||
|
Creeper entity = mock(Creeper.class);
|
||||||
|
when(entity.getLocation()).thenReturn(location);
|
||||||
|
when(entity.getType()).thenReturn(EntityType.CREEPER);
|
||||||
|
when(iwm.inWorld(location)).thenReturn(true);
|
||||||
|
EntityExplodeEvent event = new EntityExplodeEvent(entity, location, list, 0);
|
||||||
|
cl.onExplosion(event);
|
||||||
|
assertFalse(event.isCancelled());
|
||||||
|
assertFalse(event.blockList().isEmpty()); // No clearing of block list
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.bentobox.listeners.flags.worldsettings.CreeperListener#onExplosion(org.bukkit.event.entity.EntityExplodeEvent)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testOnExplosionCreeperInWorldDamageNOK() {
|
||||||
|
Flags.CREEPER_DAMAGE.setSetting(world, false);
|
||||||
|
List<Block> list = new ArrayList<>();
|
||||||
|
list.add(mock(Block.class));
|
||||||
|
list.add(mock(Block.class));
|
||||||
|
list.add(mock(Block.class));
|
||||||
|
Creeper entity = mock(Creeper.class);
|
||||||
|
when(location.getWorld()).thenReturn(world);
|
||||||
|
when(entity.getLocation()).thenReturn(location);
|
||||||
|
when(entity.getType()).thenReturn(EntityType.CREEPER);
|
||||||
|
when(iwm.inWorld(location)).thenReturn(true);
|
||||||
|
EntityExplodeEvent event = new EntityExplodeEvent(entity, location, list, 0);
|
||||||
|
cl.onExplosion(event);
|
||||||
|
assertFalse(event.isCancelled());
|
||||||
|
assertTrue(event.blockList().isEmpty()); // No clearing of block list
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.bentobox.listeners.flags.worldsettings.CreeperListener#onPlayerInteractEntity(org.bukkit.event.player.PlayerInteractEntityEvent)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testOnPlayerInteractEntity() {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -153,6 +153,8 @@ public class IslandsManagerTest extends AbstractCommonSetup {
|
|||||||
// Class under test
|
// Class under test
|
||||||
IslandsManager im;
|
IslandsManager im;
|
||||||
|
|
||||||
|
private Settings settings;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void beforeClass() throws IllegalAccessException, InvocationTargetException, IntrospectionException {
|
public static void beforeClass() throws IllegalAccessException, InvocationTargetException, IntrospectionException {
|
||||||
@ -187,12 +189,12 @@ public class IslandsManagerTest extends AbstractCommonSetup {
|
|||||||
when(world.getEnvironment()).thenReturn(World.Environment.NORMAL);
|
when(world.getEnvironment()).thenReturn(World.Environment.NORMAL);
|
||||||
when(iwm.inWorld(any(World.class))).thenReturn(true);
|
when(iwm.inWorld(any(World.class))).thenReturn(true);
|
||||||
when(iwm.inWorld(any(Location.class))).thenReturn(true);
|
when(iwm.inWorld(any(Location.class))).thenReturn(true);
|
||||||
|
when(iwm.getIslandDistance(any())).thenReturn(25);
|
||||||
when(plugin.getIWM()).thenReturn(iwm);
|
when(plugin.getIWM()).thenReturn(iwm);
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
Settings s = mock(Settings.class);
|
settings = new Settings();
|
||||||
when(plugin.getSettings()).thenReturn(s);
|
when(plugin.getSettings()).thenReturn(settings);
|
||||||
when(s.getDatabaseType()).thenReturn(DatabaseType.JSON);
|
|
||||||
|
|
||||||
// World
|
// World
|
||||||
when(world.getEnvironment()).thenReturn(World.Environment.NORMAL);
|
when(world.getEnvironment()).thenReturn(World.Environment.NORMAL);
|
||||||
@ -827,14 +829,41 @@ public class IslandsManagerTest extends AbstractCommonSetup {
|
|||||||
/**
|
/**
|
||||||
* Test method for
|
* Test method for
|
||||||
* {@link world.bentobox.bentobox.managers.IslandsManager#load()}.
|
* {@link world.bentobox.bentobox.managers.IslandsManager#load()}.
|
||||||
|
* @throws IOException
|
||||||
|
* @throws IntrospectionException
|
||||||
|
* @throws NoSuchMethodException
|
||||||
|
* @throws ClassNotFoundException
|
||||||
|
* @throws InvocationTargetException
|
||||||
|
* @throws IllegalAccessException
|
||||||
|
* @throws InstantiationException
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testLoad() {
|
public void testLoad() throws IOException, InstantiationException, IllegalAccessException,
|
||||||
//
|
InvocationTargetException, ClassNotFoundException, NoSuchMethodException, IntrospectionException {
|
||||||
// im.load();
|
when(island.getRange()).thenReturn(100);
|
||||||
|
when(h.loadObjects()).thenReturn(List.of(island));
|
||||||
|
try {
|
||||||
|
im.load();
|
||||||
|
} catch (IOException e) {
|
||||||
|
assertEquals("Island distance mismatch!\n" + "World 'world' distance 25 != island range 100!\n"
|
||||||
|
+ "Island ID in database is null.\n"
|
||||||
|
+ "Island distance in config.yml cannot be changed mid-game! Fix config.yml or clean database.",
|
||||||
|
e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoadNoDistanceCheck() throws IOException, InstantiationException, IllegalAccessException,
|
||||||
|
InvocationTargetException, ClassNotFoundException, NoSuchMethodException, IntrospectionException {
|
||||||
|
settings.setOverrideSafetyCheck(true);
|
||||||
|
when(island.getUniqueId()).thenReturn(UUID.randomUUID().toString());
|
||||||
|
when(island.getRange()).thenReturn(100);
|
||||||
|
when(h.loadObjects()).thenReturn(List.of(island));
|
||||||
|
im.load();
|
||||||
|
// No exception should be thrown
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for
|
* Test method for
|
||||||
* {@link world.bentobox.bentobox.managers.IslandsManager#locationIsOnIsland(org.bukkit.entity.Player, org.bukkit.Location)}.
|
* {@link world.bentobox.bentobox.managers.IslandsManager#locationIsOnIsland(org.bukkit.entity.Player, org.bukkit.Location)}.
|
||||||
|
Loading…
Reference in New Issue
Block a user