diff --git a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java index 700b90a..6fdeab6 100644 --- a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java @@ -30,7 +30,7 @@ public class EntityEventListener implements Listener { } Entity entity = event.getEntity(); - if (PortalHandler.getByAdjacentEntrance(event.getFrom(), (int) EntityHelper.getEntityMaxSize(entity)) != null) { + if (PortalHandler.getByAdjacentEntrance(event.getFrom(), EntityHelper.getEntityMaxSizeInt(entity)) != null) { event.setCancelled(true); } } diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java index 6673fd2..108470a 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventsListener.java @@ -91,7 +91,8 @@ public class PlayerEventsListener implements Listener { !(playerVehicle instanceof Boat)) { Portal destinationPortal = portal.getDestination(); if (destinationPortal != null) { - VehicleEventListener.teleportVehicleAfterPlayer((Vehicle) playerVehicle, destinationPortal, event.getPlayer()); + VehicleEventListener.teleportVehicleAfterPlayer((Vehicle) playerVehicle, destinationPortal, + event.getPlayer(), portal); } } } diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index db71f90..b45c834 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -26,9 +26,10 @@ public class VehicleEventListener implements Listener { * @param vehicle
The vehicle to teleport
* @param destinationPortalThe portal the player teleported to
* @param playerThe player who teleported
+ * @param originThe portal the player entered
*/ - public static void teleportVehicleAfterPlayer(Vehicle vehicle, Portal destinationPortal, Player player) { - destinationPortal.teleport(vehicle); + public static void teleportVehicleAfterPlayer(Vehicle vehicle, Portal destinationPortal, Player player, Portal origin) { + destinationPortal.teleport(vehicle, origin); Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate, () -> vehicle.addPassenger(player), 6); } @@ -46,7 +47,7 @@ public class VehicleEventListener implements Listener { Vehicle vehicle = event.getVehicle(); Portal entrancePortal; - int entitySize = (int) EntityHelper.getEntityMaxSize(vehicle); + int entitySize = EntityHelper.getEntityMaxSizeInt(vehicle); if (EntityHelper.getEntityMaxSize(vehicle) > 1) { entrancePortal = PortalHandler.getByAdjacentEntrance(event.getTo(), entitySize - 1); } else { @@ -79,7 +80,7 @@ public class VehicleEventListener implements Listener { Stargate.log.warning(Stargate.getString("prefox") + "Unable to find portal destination"); return; } - destinationPortal.teleport(vehicle); + destinationPortal.teleport(vehicle, entrancePortal); } } @@ -118,7 +119,7 @@ public class VehicleEventListener implements Listener { } Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false); - destinationPortal.teleport(vehicle); + destinationPortal.teleport(vehicle, entrancePortal); entrancePortal.close(false); } diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 3515ead..9962413 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -692,11 +692,14 @@ public class Portal { * Teleports a vehicle to this portal * * @param vehicleThe vehicle to teleport
+ * @param originThe portal the vehicle entered
*/ - public void teleport(final Vehicle vehicle) { + public void teleport(final Vehicle vehicle, Portal origin) { Location traveller = vehicle.getLocation(); Location exit = getExit(vehicle, traveller); + adjustRotation(traveller, exit, origin); + double velocity = vehicle.getVelocity().length(); // Stop and teleport @@ -793,13 +796,12 @@ public class Portal { double entitySize = EntityHelper.getEntityMaxSize(entity); if (entitySize > 1) { - exitLocation = preventExitSuffocation(relativeExit, exitLocation, entitySize); + exitLocation = preventExitSuffocation(relativeExit, exitLocation, entity); } } else { Stargate.log.log(Level.WARNING, Stargate.getString("prefix") + "Missing destination point in .gate file " + gate.getFilename()); } - return adjustExitLocation(traveller, exitLocation); } @@ -808,10 +810,10 @@ public class Portal { * * @param relativeExitThe relative exit defined as the portal's exit
* @param exitLocationThe currently calculated portal exit
- * @param entitySizeThe size of the travelling entity
+ * @param entityThe travelling entity
* @returnA location which won't suffocate the entity inside the portal
*/ - private Location preventExitSuffocation(RelativeBlockVector relativeExit, Location exitLocation, double entitySize) { + private Location preventExitSuffocation(RelativeBlockVector relativeExit, Location exitLocation, Entity entity) { //Go left to find start of opening RelativeBlockVector openingLeft = getPortalExitEdge(relativeExit, -1); @@ -828,8 +830,16 @@ public class Portal { newOffset -= 0.5; } exitLocation = DirectionHelper.adjustLocation(exitLocation, newOffset, 0, 0, modX, modZ); - if (entitySize > openingWidth) { - exitLocation = DirectionHelper.adjustLocation(exitLocation, 0, 0, (entitySize / 2D), modX, modZ); + + //Move large entities further from the portal, especially if this portal will teleport them at once + double entitySize = EntityHelper.getEntityMaxSize(entity); + int entityBoxSize = EntityHelper.getEntityMaxSizeInt(entity); + if (entitySize > 1) { + if (isAlwaysOn()) { + exitLocation = DirectionHelper.adjustLocation(exitLocation, 0, 0, (entityBoxSize / 2D), modX, modZ); + } else { + exitLocation = DirectionHelper.adjustLocation(exitLocation, 0, 0, (entitySize / 2D) - 1, modX, modZ); + } } return exitLocation; @@ -869,6 +879,8 @@ public class Portal { BlockData blockData = getWorld().getBlockAt(exitLocation).getBlockData(); if (blockData instanceof Bisected && ((Bisected) blockData).getHalf() == Bisected.Half.BOTTOM) { exitLocation.add(0, 0.5, 0); + } else if (blockData.getMaterial() == Material.WATER) { + exitLocation.add(0, 1, 0); } exitLocation.setPitch(traveller.getPitch()); diff --git a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java index eb67b99..8c0c966 100644 --- a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java @@ -7,7 +7,11 @@ import org.bukkit.Location; /** * This class helps with direction-dependent (modX, modZ) calculations */ -public class DirectionHelper { +public final class DirectionHelper { + + private DirectionHelper() { + + } /** * Gets the block at a relative block vector location diff --git a/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java b/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java index 2fd3342..157eb3c 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java @@ -18,10 +18,20 @@ public final class EntityHelper { * contain the entity. * * @param entityThe entity to get max size for
- * @return + * @returnThe max size of the entity
+ */ + public static int getEntityMaxSizeInt(Entity entity) { + return (int) Math.ceil((float) getEntityMaxSize(entity)); + } + + /** + * Gets the max size of an entity along its x and z axis + * + * @param entityThe entity to get max size for
+ * @returnThe max size of the entity
*/ public static double getEntityMaxSize(Entity entity) { - return Math.ceil((float) Math.max(entity.getBoundingBox().getWidthX(), entity.getBoundingBox().getWidthZ())); + return Math.max(entity.getBoundingBox().getWidthX(), entity.getBoundingBox().getWidthZ()); } }