Fixes some oddities regarding vehicle teleportation

Accounts for size when blocking an entity near a portal from teleporting to the nether
Ignores boats and minecarts when teleporting a vehicle after the player
Makes it easy to get a portal by adjacent entrance for any given range
This commit is contained in:
Kristian Knarvik 2021-02-23 19:17:05 +01:00
parent e42da6d6bd
commit 5f685b2460
4 changed files with 68 additions and 65 deletions

View File

@ -4,6 +4,7 @@ import net.knarcraft.stargate.portal.Portal;
import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.PortalHandler;
import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.Stargate;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@ -27,8 +28,10 @@ public class EntityEventListener implements Listener {
return; return;
} }
Portal portal = PortalHandler.getByAdjacentEntrance(event.getFrom()); Entity entity = event.getEntity();
if (portal != null) { int entitySize = (int) Math.ceil((float) Math.max(entity.getBoundingBox().getWidthX(),
entity.getBoundingBox().getWidthZ()));
if (PortalHandler.getByAdjacentEntrance(event.getFrom(), entitySize) != null) {
event.setCancelled(true); event.setCancelled(true);
} }
} }

View File

@ -11,7 +11,9 @@ import org.bukkit.GameMode;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.data.type.WallSign; import org.bukkit.block.data.type.WallSign;
import org.bukkit.entity.Boat;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Minecart;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Vehicle; import org.bukkit.entity.Vehicle;
import org.bukkit.event.Event; import org.bukkit.event.Event;
@ -84,11 +86,13 @@ public class PlayerEventsListener implements Listener {
Entity playerVehicle = event.getPlayer().getVehicle(); Entity playerVehicle = event.getPlayer().getVehicle();
Portal portal = PortalHandler.getByEntrance(event.getFrom()); Portal portal = PortalHandler.getByEntrance(event.getFrom());
if (playerVehicle != null && PortalHandler.getByEntrance(event.getFrom()) != null) { if (playerVehicle != null && PortalHandler.getByEntrance(event.getFrom()) != null &&
!(playerVehicle instanceof Minecart) &&
!(playerVehicle instanceof Boat)) {
Portal destinationPortal = portal.getDestination(); Portal destinationPortal = portal.getDestination();
if (destinationPortal != null) { if (destinationPortal != null) {
VehicleEventListener.teleportVehicleAfterPlayer((Vehicle) playerVehicle, destinationPortal, event.getPlayer()); VehicleEventListener.teleportVehicleAfterPlayer((Vehicle) playerVehicle, destinationPortal, event.getPlayer());
Stargate.log.info("Player was driving " + playerVehicle.getName()); Stargate.debug("playerTeleport", "Player was driving " + playerVehicle.getName());
} }
} }
} }

View File

@ -32,14 +32,26 @@ public class VehicleEventListener implements Listener {
} }
/** /**
* Teleports a vehicle through a stargate * Check for a vehicle moving through a portal
* *
* @param passengers <p>The passengers inside the vehicle</p> * @param event <p>The triggered move event</p>
* @param entrancePortal <p>The portal the vehicle is entering</p>
* @param vehicle <p>The vehicle passing through</p>
*/ */
public static void teleportVehicle(List<Entity> passengers, Portal entrancePortal, Vehicle vehicle) { @EventHandler
teleportVehicle(passengers, entrancePortal, vehicle, false); public void onVehicleMove(VehicleMoveEvent event) {
if (!Stargate.handleVehicles) {
return;
}
List<Entity> passengers = event.getVehicle().getPassengers();
Vehicle vehicle = event.getVehicle();
Portal entrancePortal = PortalHandler.getByEntrance(event.getTo());
//Return if the portal cannot be teleported through
if (entrancePortal == null || !entrancePortal.isOpen() || entrancePortal.isBungee()) {
return;
}
teleportVehicle(passengers, entrancePortal, vehicle);
} }
/** /**
@ -48,12 +60,11 @@ public class VehicleEventListener implements Listener {
* @param passengers <p>The passengers inside the vehicle</p> * @param passengers <p>The passengers inside the vehicle</p>
* @param entrancePortal <p>The portal the vehicle is entering</p> * @param entrancePortal <p>The portal the vehicle is entering</p>
* @param vehicle <p>The vehicle passing through</p> * @param vehicle <p>The vehicle passing through</p>
* @param skipOpenCheck <p>Skips the check for whether the portal is open for the player</p>
*/ */
public static void teleportVehicle(List<Entity> passengers, Portal entrancePortal, Vehicle vehicle, boolean skipOpenCheck) { private static void teleportVehicle(List<Entity> passengers, Portal entrancePortal, Vehicle vehicle) {
if (!passengers.isEmpty() && passengers.get(0) instanceof Player) { if (!passengers.isEmpty() && passengers.get(0) instanceof Player) {
Stargate.log.info(Stargate.getString("prefox") + "Found passenger vehicle"); Stargate.log.info(Stargate.getString("prefox") + "Found passenger vehicle");
teleportPlayerAndVehicle(entrancePortal, vehicle, passengers, skipOpenCheck); teleportPlayerAndVehicle(entrancePortal, vehicle, passengers);
} else { } else {
Stargate.log.info(Stargate.getString("prefox") + "Found empty vehicle"); Stargate.log.info(Stargate.getString("prefox") + "Found empty vehicle");
Portal destinationPortal = entrancePortal.getDestination(); Portal destinationPortal = entrancePortal.getDestination();
@ -72,10 +83,9 @@ public class VehicleEventListener implements Listener {
* @param vehicle <p>The vehicle to teleport</p> * @param vehicle <p>The vehicle to teleport</p>
* @param passengers <p>Any entities sitting in the minecart</p> * @param passengers <p>Any entities sitting in the minecart</p>
*/ */
private static void teleportPlayerAndVehicle(Portal entrancePortal, Vehicle vehicle, List<Entity> passengers, private static void teleportPlayerAndVehicle(Portal entrancePortal, Vehicle vehicle, List<Entity> passengers) {
boolean skipOpenCheck) {
Player player = (Player) passengers.get(0); Player player = (Player) passengers.get(0);
if (!skipOpenCheck && !entrancePortal.isOpenFor(player)) { if (!entrancePortal.isOpenFor(player)) {
Stargate.sendMessage(player, Stargate.getString("denyMsg")); Stargate.sendMessage(player, Stargate.getString("denyMsg"));
return; return;
} }
@ -105,29 +115,4 @@ public class VehicleEventListener implements Listener {
entrancePortal.close(false); entrancePortal.close(false);
} }
/**
* Check for a vehicle moving through a portal
*
* @param event <p>The triggered move event</p>
*/
@EventHandler
public void onVehicleMove(VehicleMoveEvent event) {
if (!Stargate.handleVehicles) {
return;
}
List<Entity> passengers = event.getVehicle().getPassengers();
Vehicle vehicle = event.getVehicle();
Portal entrancePortal = PortalHandler.getByEntrance(event.getTo());
//Return if the portal cannot be teleported through
if (entrancePortal == null || !entrancePortal.isOpen() || entrancePortal.isBungee()) {
return;
}
//TODO: As there are a lot of vehicles in the game now, a lot needs to be accounted for to make this work as expected
teleportVehicle(passengers, entrancePortal, vehicle);
}
} }

View File

@ -555,33 +555,44 @@ public class PortalHandler {
/** /**
* Gets a portal given a location adjacent to its entrance * Gets a portal given a location adjacent to its entrance
* *
* @param loc <p>A location adjacent to the portal's entrance</p> * @param location <p>A location adjacent to the portal's entrance</p>
* @return <p>The portal adjacent to the given location</p> * @return <p>The portal adjacent to the given location</p>
*/ */
public static Portal getByAdjacentEntrance(Location loc) { public static Portal getByAdjacentEntrance(Location location) {
int centerX = loc.getBlockX(); return getByAdjacentEntrance(location, 1);
int centerY = loc.getBlockY(); }
int centerZ = loc.getBlockZ();
World world = loc.getWorld(); /**
Portal portal = lookupEntrances.get(new BlockLocation(world, centerX, centerY, centerZ)); * Gets a portal given a location adjacent to its entrance
*
* @param location <p>A location adjacent to the portal's entrance</p>
* @param range <p>The range to scan for portals</p>
* @return <p>The portal adjacent to the given location</p>
*/
public static Portal getByAdjacentEntrance(Location location, int range) {
List<BlockLocation> adjacentPositions = new ArrayList<>();
BlockLocation centerLocation = new BlockLocation(location.getBlock());
adjacentPositions.add(centerLocation);
for (int index = 1; index <= range; index++) {
adjacentPositions.add(centerLocation.makeRelative(index, 0, 0));
adjacentPositions.add(centerLocation.makeRelative(-index, 0, 0));
adjacentPositions.add(centerLocation.makeRelative(0, 0, index));
adjacentPositions.add(centerLocation.makeRelative(0, 0, -index));
if (index < range) {
adjacentPositions.add(centerLocation.makeRelative(index, 0, index));
adjacentPositions.add(centerLocation.makeRelative(-index, 0, -index));
adjacentPositions.add(centerLocation.makeRelative(index, 0, -index));
adjacentPositions.add(centerLocation.makeRelative(-index, 0, index));
}
}
for (BlockLocation adjacentPosition : adjacentPositions) {
Stargate.debug("getByAdjacentEntrance", "Testing" + adjacentPosition);
Portal portal = lookupEntrances.get(adjacentPosition);
if (portal != null) { if (portal != null) {
return portal; return portal;
} }
portal = lookupEntrances.get(new BlockLocation(world, centerX + 1, centerY, centerZ));
if (portal != null) {
return portal;
}
portal = lookupEntrances.get(new BlockLocation(world, centerX - 1, centerY, centerZ));
if (portal != null) {
return portal;
}
portal = lookupEntrances.get(new BlockLocation(world, centerX, centerY, centerZ + 1));
if (portal != null) {
return portal;
}
portal = lookupEntrances.get(new BlockLocation(world, centerX, centerY, centerZ - 1));
if (portal != null) {
return portal;
} }
return null; return null;
} }