feat(pocket-base): allow mobs through portals
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package games.dmg.spigotbase;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
@@ -8,20 +9,26 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Mob;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
final class PocketBaseControllerTest {
|
||||
@@ -230,6 +237,151 @@ final class PocketBaseControllerTest {
|
||||
verify(event).setCancelled(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void activeEntranceTransportsMobsOnceButNotOtherEntities() {
|
||||
UUID ownerId = UUID.randomUUID();
|
||||
UUID worldId = UUID.randomUUID();
|
||||
PocketPortalLocation portal = new PocketPortalLocation(
|
||||
worldId, "world", -2, 64, 0, PocketPortalAxis.X
|
||||
);
|
||||
PocketBaseState state = new PocketBaseState(ownerId, 1, Optional.of(portal));
|
||||
Server server = mock(Server.class);
|
||||
World world = intactPortalWorld(worldId, portal);
|
||||
Mob mob = mock(Mob.class);
|
||||
Entity item = mock(Entity.class);
|
||||
Location arrival = new Location(mock(World.class), 0.5, 65.0, 5.5);
|
||||
PocketBaseManager pocketBases = mock(PocketBaseManager.class);
|
||||
|
||||
when(mob.getUniqueId()).thenReturn(UUID.randomUUID());
|
||||
when(item.getUniqueId()).thenReturn(UUID.randomUUID());
|
||||
when(world.getNearbyEntities(any(BoundingBox.class), any()))
|
||||
.thenReturn(List.of(mob, item));
|
||||
when(server.getWorld(worldId)).thenReturn(world);
|
||||
when(pocketBases.knownStates()).thenReturn(Map.of(ownerId, state));
|
||||
when(pocketBases.pocketArrival(ownerId)).thenReturn(arrival);
|
||||
PocketBaseController controller = controller(server, pocketBases);
|
||||
|
||||
controller.scanMobPortals();
|
||||
controller.scanMobPortals();
|
||||
|
||||
verify(mob).teleport(arrival, PlayerTeleportEvent.TeleportCause.PLUGIN);
|
||||
verify(item, never()).teleport(
|
||||
any(Location.class),
|
||||
any(PlayerTeleportEvent.TeleportCause.class)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void activeReturnPortalTransportsMobOutsideIntactEntrance() {
|
||||
UUID ownerId = UUID.randomUUID();
|
||||
UUID normalWorldId = UUID.randomUUID();
|
||||
UUID pocketWorldId = UUID.randomUUID();
|
||||
PocketPortalLocation entrance = new PocketPortalLocation(
|
||||
normalWorldId, "world", -2, 64, 0, PocketPortalAxis.X
|
||||
);
|
||||
PocketPortalLocation returnPortal = new PocketPortalLocation(
|
||||
pocketWorldId, "pocket", 8, 65, 8, PocketPortalAxis.Z
|
||||
);
|
||||
PocketBaseState state = new PocketBaseState(ownerId, 1, Optional.of(entrance));
|
||||
Server server = mock(Server.class);
|
||||
World normalWorld = intactPortalWorld(normalWorldId, entrance);
|
||||
World pocketWorld = intactPortalWorld(pocketWorldId, returnPortal);
|
||||
Mob mob = mock(Mob.class);
|
||||
PocketBaseManager pocketBases = mock(PocketBaseManager.class);
|
||||
|
||||
when(mob.getUniqueId()).thenReturn(UUID.randomUUID());
|
||||
when(normalWorld.getNearbyEntities(any(BoundingBox.class), any()))
|
||||
.thenReturn(List.of());
|
||||
when(pocketWorld.getNearbyEntities(any(BoundingBox.class), any()))
|
||||
.thenReturn(List.of(mob));
|
||||
when(server.getWorld(normalWorldId)).thenReturn(normalWorld);
|
||||
when(server.getWorld(pocketWorldId)).thenReturn(pocketWorld);
|
||||
when(pocketBases.knownStates()).thenReturn(Map.of(ownerId, state));
|
||||
when(pocketBases.state(ownerId)).thenReturn(state);
|
||||
when(pocketBases.returnPortalIsIntact(ownerId)).thenReturn(true);
|
||||
when(pocketBases.returnPortal(ownerId)).thenReturn(returnPortal);
|
||||
PocketBaseController controller = controller(server, pocketBases);
|
||||
|
||||
controller.scanMobPortals();
|
||||
|
||||
verify(mob).teleport(
|
||||
new Location(normalWorld, 0.0, 65.0, 1.5),
|
||||
PlayerTeleportEvent.TeleportCause.PLUGIN
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void mobReturnFallsBackToServerSpawnWithoutValidEntrance() {
|
||||
UUID ownerId = UUID.randomUUID();
|
||||
UUID pocketWorldId = UUID.randomUUID();
|
||||
PocketPortalLocation returnPortal = new PocketPortalLocation(
|
||||
pocketWorldId, "pocket", 8, 65, 8, PocketPortalAxis.Z
|
||||
);
|
||||
PocketBaseState state = new PocketBaseState(ownerId, 1, Optional.empty());
|
||||
Server server = mock(Server.class);
|
||||
World pocketWorld = intactPortalWorld(pocketWorldId, returnPortal);
|
||||
World fallbackWorld = mock(World.class);
|
||||
Location spawn = new Location(fallbackWorld, 10.5, 70.0, 10.5);
|
||||
Mob mob = mock(Mob.class);
|
||||
PocketBaseManager pocketBases = mock(PocketBaseManager.class);
|
||||
|
||||
when(mob.getUniqueId()).thenReturn(UUID.randomUUID());
|
||||
when(pocketWorld.getNearbyEntities(any(BoundingBox.class), any()))
|
||||
.thenReturn(List.of(mob));
|
||||
when(server.getWorld(pocketWorldId)).thenReturn(pocketWorld);
|
||||
when(server.getWorlds()).thenReturn(List.of(fallbackWorld));
|
||||
when(fallbackWorld.getSpawnLocation()).thenReturn(spawn);
|
||||
when(pocketBases.knownStates()).thenReturn(Map.of(ownerId, state));
|
||||
when(pocketBases.state(ownerId)).thenReturn(state);
|
||||
when(pocketBases.returnPortalIsIntact(ownerId)).thenReturn(true);
|
||||
when(pocketBases.returnPortal(ownerId)).thenReturn(returnPortal);
|
||||
PocketBaseController controller = controller(server, pocketBases);
|
||||
|
||||
controller.scanMobPortals();
|
||||
|
||||
verify(mob).teleport(
|
||||
spawn,
|
||||
PlayerTeleportEvent.TeleportCause.PLUGIN
|
||||
);
|
||||
}
|
||||
|
||||
private static PocketBaseController controller(
|
||||
Server server,
|
||||
PocketBaseManager pocketBases
|
||||
) {
|
||||
PluginSettings settings = PluginSettings.from(Map.of());
|
||||
return new PocketBaseController(
|
||||
server,
|
||||
mock(BaseStateManager.class),
|
||||
new BaseBoundsService(settings),
|
||||
pocketBases,
|
||||
new PluginSettingsProvider(settings),
|
||||
Logger.getAnonymousLogger()
|
||||
);
|
||||
}
|
||||
|
||||
private static World intactPortalWorld(
|
||||
UUID worldId,
|
||||
PocketPortalLocation portal
|
||||
) {
|
||||
World world = mock(World.class);
|
||||
Set<BlockPosition> frame = new HashSet<>(PocketPortalGeometry.frameBlocks(portal));
|
||||
when(world.getUID()).thenReturn(worldId);
|
||||
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenAnswer(invocation -> {
|
||||
BlockPosition position = new BlockPosition(
|
||||
invocation.getArgument(0), invocation.getArgument(1), invocation.getArgument(2)
|
||||
);
|
||||
return block(
|
||||
world,
|
||||
position.x(),
|
||||
position.y(),
|
||||
position.z(),
|
||||
frame.contains(position) ? Material.DIAMOND_BLOCK : Material.AIR
|
||||
);
|
||||
});
|
||||
return world;
|
||||
}
|
||||
|
||||
private static ItemStack item(Material material) {
|
||||
ItemStack item = mock(ItemStack.class);
|
||||
when(item.getType()).thenReturn(material);
|
||||
|
||||
Reference in New Issue
Block a user