Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Force field fling on teleport #2122

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 additions & 2 deletions src/main/java/world/bentobox/bentobox/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,15 @@ public class Settings implements ConfigObject {
@ConfigEntry(path = "general.fakeplayers", experimental = true)
private Set<String> fakePlayers = new HashSet<>();

@ConfigComment("Flingback power. How far hostile mobs will be flung back when a player teleports into them.")
@ConfigComment("2.5 will push back a number of blocks, 5 will throw them far, 1 will not do much.")
@ConfigEntry(path = "general.flingback")
private double flingback = 2.5D;

@ConfigComment("Kill mobs on teleport. If the world flag in Admin Settings is set, then they will be killed/removed instead of flung.")
@ConfigEntry(path = "general.teleport-remove-mobs")
private boolean teleportRemoveMobs = false;

/* PANELS */

@ConfigComment("Toggle whether panels should be closed or not when the player clicks anywhere outside of the inventory view.")
Expand Down Expand Up @@ -983,8 +992,8 @@ public int getMaximumPoolSize()
{
return maximumPoolSize;
}


/**
* Gets safe spot search range.
*
Expand Down Expand Up @@ -1038,4 +1047,32 @@ public void setSafeSpotSearchRange(int safeSpotSearchRange)
{
this.safeSpotSearchRange = safeSpotSearchRange;
}

/**
* @return the flingback
*/
public double getFlingback() {
return flingback;
}

/**
* @param flingback the flingback to set
*/
public void setFlingback(double flingback) {
this.flingback = flingback;
}

/**
* @return the teleportRemoveMobs
*/
public boolean isTeleportRemoveMobs() {
return teleportRemoveMobs;
}

/**
* @param teleportRemoveMobs the teleportRemoveMobs to set
*/
public void setTeleportRemoveMobs(boolean teleportRemoveMobs) {
this.teleportRemoveMobs = teleportRemoveMobs;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.Objects;
import java.util.Optional;
import java.util.Queue;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
Expand All @@ -22,6 +23,7 @@
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
Expand Down Expand Up @@ -66,6 +68,7 @@
public class IslandsManager {

private final BentoBox plugin;
private final Random rand = new Random();

// Tree species to boat material map
private static final Map<Type, Material> TREE_TO_BOAT = ImmutableMap.<Type, Material>builder().
Expand Down Expand Up @@ -1633,6 +1636,7 @@ public void setOwner(User user, UUID targetUUID, Island island) {
*/
public void clearArea(Location loc) {
if (!plugin.getIWM().inWorld(loc)) return;

loc.getWorld().getNearbyEntities(loc, plugin.getSettings().getClearRadius(),
plugin.getSettings().getClearRadius(),
plugin.getSettings().getClearRadius()).stream()
Expand All @@ -1642,7 +1646,29 @@ public void clearArea(Location loc) {
&& !(en instanceof PufferFish)
&& ((LivingEntity)en).getRemoveWhenFarAway())
.filter(en -> en.getCustomName() == null)
.forEach(Entity::remove);
.forEach(e -> flingOrKill(e, loc));
}

private void flingOrKill(Entity e, Location loc) {
if (plugin.getSettings().isTeleportRemoveMobs()) {
e.remove();
return;
}
Vector entVec = e.getLocation().toVector();
double dist = plugin.getSettings().getFlingback() - entVec.distance(loc.toVector());
if (dist < 1) {
dist = 1;
}
Vector direction = entVec.subtract(loc.toVector());
if (direction.lengthSquared() < 3) {
// On top of us
direction.add(new Vector(rand.nextDouble(), 0, rand.nextDouble()));
}
// Add a bit of lift
direction.add(new Vector(0, rand.nextDouble(), 0));
direction.multiply(dist);
loc.getWorld().playSound(e, Sound.ENTITY_ILLUSIONER_HURT, 1F, 5F);
e.setVelocity(direction);
}

/**
Expand Down
8 changes: 6 additions & 2 deletions src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ general:
prefix-character: ''
# Custom connection datasource properties that will be applied to connection pool.
# Check available values to your SQL driver implementation.
# Example: ")
# custom-properties:
# Example:
# custom-properties:
# cachePrepStmts: 'true'
# prepStmtCacheSize: '250'
# prepStmtCacheSqlLimit: '2048'
Expand All @@ -98,6 +98,10 @@ general:
# /!\ This feature is experimental and might not work as expected or might not work at all.
fakeplayers:
- '[CoFH]'
# Flingback power. How far hostile mobs will be flung back when a player teleports into them.
flingback: 5.0
# Remove mobs on teleport.
teleport-remove-mobs: false
panel:
# Toggle whether panels should be closed or not when the player clicks anywhere outside of the inventory view.
close-on-click-outside: true
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/locales/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1292,9 +1292,9 @@ protection:
name: "Remove end exit island"
REMOVE_MOBS:
description: |-
&a Remove monsters when
&a Push monsters away when
&a teleporting to island
name: "Remove monsters"
name: "Fling back monsters"
RIDING:
description: "Toggle riding"
name: "Animal riding"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,11 @@ public String getTitle() {

@Override
public String getOriginalTitle() {
// TODO Auto-generated method stub
return "";
}

@Override
public void setTitle(String title) {
// TODO Auto-generated method stub
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyDouble;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
Expand Down Expand Up @@ -33,6 +34,7 @@
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
Expand All @@ -51,6 +53,7 @@
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.plugin.PluginManager;
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.util.Vector;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -76,7 +79,6 @@
import world.bentobox.bentobox.api.events.island.IslandDeleteEvent;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.Database;
import world.bentobox.bentobox.database.DatabaseSetup.DatabaseType;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.lists.Flags;
import world.bentobox.bentobox.managers.island.IslandCache;
Expand Down Expand Up @@ -140,6 +142,7 @@ public class IslandsManagerTest {

// Class under test
IslandsManager im;
private Settings s;

/**
*/
Expand All @@ -163,9 +166,9 @@ public void setUp() throws Exception {
when(plugin.getIslandChunkDeletionManager()).thenReturn(chunkDeletionManager);

// Settings
Settings s = mock(Settings.class);
s = new Settings();
when(plugin.getSettings()).thenReturn(s);
when(s.getDatabaseType()).thenReturn(DatabaseType.JSON);
//when(s.getDatabaseType()).thenReturn(DatabaseType.JSON);

// World
when(world.getEnvironment()).thenReturn(World.Environment.NORMAL);
Expand All @@ -181,6 +184,7 @@ public void setUp() throws Exception {
User.setPlugin(plugin);
// Set up user already
when(player.getUniqueId()).thenReturn(uuid);
when(player.getLocation()).thenReturn(location);
User.getInstance(player);

// Locales
Expand Down Expand Up @@ -210,6 +214,8 @@ public void setUp() throws Exception {
when(location.clone()).thenReturn(location);
Chunk chunk = mock(Chunk.class);
when(location.getChunk()).thenReturn(chunk);
// Vector
when(location.toVector()).thenReturn(new Vector(100D, 120D, 100D));
when(space1.getRelative(BlockFace.DOWN)).thenReturn(ground);
when(space1.getRelative(BlockFace.UP)).thenReturn(space2);
// A safe spot
Expand Down Expand Up @@ -276,7 +282,6 @@ public void setUp() throws Exception {

when(iwm.getRemoveMobsWhitelist(any())).thenReturn(whitelist);


// Monsters and animals
when(zombie.getLocation()).thenReturn(location);
when(zombie.getType()).thenReturn(EntityType.ZOMBIE);
Expand All @@ -288,13 +293,17 @@ public void setUp() throws Exception {
when(cow.getType()).thenReturn(EntityType.COW);
when(wither.getType()).thenReturn(EntityType.WITHER);
when(wither.getRemoveWhenFarAway()).thenReturn(true);
when(wither.getLocation()).thenReturn(location);
when(creeper.getType()).thenReturn(EntityType.CREEPER);
when(creeper.getRemoveWhenFarAway()).thenReturn(true);
when(creeper.getLocation()).thenReturn(location);
when(pufferfish.getType()).thenReturn(EntityType.PUFFERFISH);
when(pufferfish.getLocation()).thenReturn(location);
// Named monster
when(skelly.getType()).thenReturn(EntityType.SKELETON);
when(skelly.getCustomName()).thenReturn("Skelly");
when(skelly.getRemoveWhenFarAway()).thenReturn(true);
when(skelly.getLocation()).thenReturn(location);

Collection<Entity> collection = new ArrayList<>();
collection.add(player);
Expand All @@ -305,9 +314,7 @@ public void setUp() throws Exception {
collection.add(creeper);
collection.add(pufferfish);
collection.add(skelly);
when(world
.getNearbyEntities(any(Location.class), Mockito.anyDouble(), Mockito.anyDouble(), Mockito.anyDouble()))
.thenReturn(collection);
when(world.getNearbyEntities(any(Location.class), anyDouble(), anyDouble(), anyDouble())).thenReturn(collection);



Expand Down Expand Up @@ -1105,7 +1112,8 @@ public void testClearAreaWrongWorld() {
* Test method for {@link world.bentobox.bentobox.managers.IslandsManager#clearArea(Location)}.
*/
@Test
public void testClearArea() {
public void testClearAreaRemove() {
s.setTeleportRemoveMobs(true);
im.clearArea(location);
// Only the correct entities should be cleared
verify(zombie).remove();
Expand All @@ -1117,6 +1125,34 @@ public void testClearArea() {
verify(pufferfish, never()).remove();
verify(skelly, never()).remove();
}

/**
* Test method for {@link world.bentobox.bentobox.managers.IslandsManager#clearArea(Location)}.
*/
@Test
public void testClearArea() {
im.clearArea(location);
// Only the correct entities should be cleared
verify(zombie, never()).remove();
verify(player, never()).remove();
verify(cow, never()).remove();
verify(slime, never()).remove();
verify(wither, never()).remove();
verify(creeper, never()).remove();
verify(pufferfish, never()).remove();
verify(skelly, never()).remove();

verify(zombie).setVelocity(any(Vector.class));
verify(slime).setVelocity(any(Vector.class));
verify(creeper).setVelocity(any(Vector.class));
verify(player, never()).setVelocity(any(Vector.class));
verify(cow, never()).setVelocity(any(Vector.class));
verify(wither, never()).setVelocity(any(Vector.class));
verify(pufferfish, never()).setVelocity(any(Vector.class));
verify(skelly, never()).setVelocity(any(Vector.class));

verify(world).playSound(zombie, Sound.ENTITY_ILLUSIONER_HURT, 1F, 5F);
}

/**
* Test method for {@link world.bentobox.bentobox.managers.IslandsManager#getIslandById(String)}.
Expand Down