diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java index c8ca84e..9ef75b1 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java @@ -11,46 +11,47 @@ import java.util.List; import java.util.Random; /** - * The portal destinations contain information about a portal's destinations, and is responsible for cycling destinations + * The portal activator activates/de-activates portals and keeps track of a portal's destinations * - *
The activator is responsible for activating/de-activating the portal and contains information about + *
The portal activator is responsible for activating/de-activating the portal and contains information about * available destinations and which player activated the portal.
*/ public class PortalActivator { + private final Portal portal; + private final PortalOpener opener; + + private ListThe portal which this this object stores destinations for
- * @param activatorThe activator to use when a player activates a portal
- * @param destination + * @param portalThe portal which this this object stores destinations for
+ * @param portalOpenerThe portal opener to trigger when the activation causes the portal to open
+ * @param destinationThe fixed destination specified on the portal's sign
*/ - public PortalActivator(Portal portal, PortalOpener activator, String destination) { + public PortalActivator(Portal portal, PortalOpener portalOpener, String destination) { this.portal = portal; - this.activator = activator; + this.opener = portalOpener; this.destination = destination; } /** - * Gets the player currently using this portal activator's portal + * Gets the player which this activator's portal is currently activated for * - * @returnThe player currently using this portal activator's portal
+ * @returnThe player this activator's portal is currently activated for
*/ public Player getActivePlayer() { return activePlayer; } /** - * Gets the destinations of this portal + * Gets the available portal destinations * - * @returnThe destinations of this portal
+ * @returnThe available portal destinations
*/ public ListThe destination portal the player should teleport to
*/ public Portal getDestination(Player player) { + String portalNetwork = portal.getNetwork(); if (portal.getOptions().isRandom()) { - destinations = PortalHandler.getDestinations(portal, player, portal.getNetwork()); + //Find possible destinations + ListFor random portals, getDestination must be given a player to decide which destinations are valid. Without a + * player, or with a null player, behavior is only defined for a non-random gate.
+ * + * @returnThe portal destination
+ */ + public Portal getDestination() { + return getDestination(null); + } + + /** + * Sets the destination of this portal activator's portal + * + * @param destinationThe new destination of this portal activator's portal
+ */ + public void setDestination(Portal destination) { + setDestination(destination.getName()); + } + + /** + * Sets the destination of this portal activator's portal + * + * @param destinationThe new destination of this portal activator's portal
+ */ + public void setDestination(String destination) { + this.destination = destination; + } + + /** + * Gets the name of the selected destination + * + * @returnThe name of the selected destination
+ */ + public String getDestinationName() { + return destination; + } + + /** + * Activates this activator's portal for the given player * * @param playerThe player to activate the portal for
* @returnTrue if the portal was activated
*/ boolean activate(Player player) { + //Clear previous destination data this.destination = ""; this.destinations.clear(); + + //Adds the active gate to the active queue to allow it to be remotely deactivated Stargate.activePortalsQueue.add(portal); + + //Set the given player as the active player activePlayer = player; + String network = portal.getNetwork(); destinations = PortalHandler.getDestinations(portal, player, network); + + //Sort destinations if enabled if (Stargate.sortNetworkDestinations) { Collections.sort(destinations); } + + //Select last used destination if remember destination is enabled if (Stargate.rememberDestination && !lastDestination.isEmpty() && destinations.contains(lastDestination)) { destination = lastDestination; } + //Trigger an activation event to allow the cancellation to be cancelled + return triggerStargateActivationEvent(player); + } + + /** + * Triggers a stargate activation event to allow other plugins to cancel the activation + * + *The event may also end up changing destinations.
+ * + * @param playerThe player trying to activate this activator's portal
+ * @returnTrue if the portal was activated. False otherwise
+ */ + private boolean triggerStargateActivationEvent(Player player) { StargateActivateEvent event = new StargateActivateEvent(portal, player, destinations, destination); Stargate.server.getPluginManager().callEvent(event); if (event.isCancelled()) { Stargate.activePortalsQueue.remove(portal); return false; } + + //Update destinations in case they changed, and update the sign destination = event.getDestination(); destinations = event.getDestinations(); portal.drawSign(); @@ -111,16 +180,24 @@ public class PortalActivator { * Deactivates this portal */ public void deactivate() { + //Trigger a stargate deactivate event to allow other plugins to cancel the event StargateDeactivateEvent event = new StargateDeactivateEvent(portal); Stargate.server.getPluginManager().callEvent(event); if (event.isCancelled()) { return; } + //Un-mark the portal as activated Stargate.activePortalsQueue.remove(portal); + + //For a fixed gate, the destinations and the sign never really change, but at the same time, fixed gates are + // never really activated, so in theory, this check should be redundant. + //TODO: Decide if this check is really useless if (portal.getOptions().isFixed()) { return; } + + //Clear destinations and the active player before re-drawing the sign to show that it's deactivated destinations.clear(); destination = ""; activePlayer = null; @@ -128,54 +205,16 @@ public class PortalActivator { } /** - * Gets whether this portal is active + * Gets whether this portal activator's portal is active * - * @returnWhether this portal is active
+ * @returnWhether this portal activator's portal is active
*/ public boolean isActive() { return portal.getOptions().isFixed() || (destinations.size() > 0); } /** - * Gets the portal destination - * - *If this portal is random, a player should be given to get correct destinations.
- * - * @returnThe portal destination
- */ - public Portal getDestination() { - return getDestination(null); - } - - /** - * Sets the destination of this portal - * - * @param destinationThe new destination of this portal
- */ - public void setDestination(Portal destination) { - setDestination(destination.getName()); - } - - /** - * Sets the destination of this portal - * - * @param destinationThe new destination of this portal
- */ - public void setDestination(String destination) { - this.destination = destination; - } - - /** - * Gets the name of the destination of this portal - * - * @returnThe name of this portal's destination
- */ - public String getDestinationName() { - return destination; - } - - /** - * Cycles destination for a network gate forwards + * Cycles destination for a non-fixed gate by one forwards step * * @param playerThe player to cycle the gate for
*/ @@ -184,37 +223,44 @@ public class PortalActivator { } /** - * Cycles destination for a network gate + * Cycles destination for a non-fixed gate * * @param playerThe player cycling destinations
* @param directionThe direction of the cycle (+1 for next, -1 for previous)
*/ public void cycleDestination(Player player, int direction) { + //Only allow going exactly one step in either direction if (direction != 1 && direction != -1) { throw new IllegalArgumentException("The destination direction must be 1 or -1."); } boolean activate = false; if (!isActive() || getActivePlayer() != player) { - //If the stargate activate event is cancelled, return + //If not active or not active for the given player, and the activation is denied, just abort if (!activate(player)) { return; } + activate = true; + Stargate.debug("cycleDestination", "Network Size: " + PortalHandler.getNetwork(portal.getNetwork()).size()); Stargate.debug("cycleDestination", "Player has access to: " + destinations.size()); - activate = true; } + //If no destinations are available, just tell the player and quit if (destinations.size() == 0) { Stargate.sendErrorMessage(player, Stargate.getString("destEmpty")); return; } + //Cycle if destination remembering is disabled, if the portal was already active, or it has no last destination if (!Stargate.rememberDestination || !activate || lastDestination.isEmpty()) { cycleDestination(direction); } - activator.setOpenTime(System.currentTimeMillis() / 1000); + + //Update the activated time to allow it to be deactivated after a timeout, and re-draw the sign to show the + // selected destination + opener.setActivatedTime(System.currentTimeMillis() / 1000); portal.drawSign(); }