Skip to content
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
54 changes: 30 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,36 +15,42 @@ $ mvn install

Note: `/destination purge` and `/portal purge` require [specific keywords defined below these commands](#definitions).

| Command | Description |
|-------------------------------------------------------------|--------------------------------------------------------------------|
|`/destination change <destination_name>` | Sets the location of a destination to the user's current position. |
|`/destination clear <portal_name>` | Removes the destination of a portal. |
|`/destination create <destination_name>` | Creates a new destination at the user's current position. |
|`/destination info <destination_name>` | Displays information about the current destination. |
|`/destination list` | Displays a list of all the existing destinations. |
|`/destination purge <'invalid'/'no-portals'/'both'>` | Purges any unused and / or invalid destinations. |
|`/destination remove <destination_name>` | Removes a destination. |
|`/destination set <portal_name> <destination_name>` | Sets the destination of a portal. |
|`/destination sethere <portal_name>` | Sets the destination of the portal to the user's current location. |
|`/destination teleport <destination_name>` | Teleports the user to the provided destination. |
|`/portal create <portal_name>` | Creates a permissionless portal using the selected area. |
|`/portal debug` | Displays information about the portal being entered (no teleport). |
|`/portal info <portal_name>` | Displays information about a portal. |
|`/portal list` | Lists all existing portals. |
|`/portal permission whimc-portals.entry.<permission_suffix>` | Sets or removes portal permissions. |
|`/portal purge <'invalid'/'no-destination'/'both'>` | Purges any unused and / or invalid portals. |
|`/portal refill <portal_name>` | Regenerates the filler of a portal. |
|`/portal remove <portal_name>` | Removes a portal. |
|`/portal reshape <portal_name>` | Reshape a portal to your current selection. |
|`/portal setfiller <portal_name> <block_type>` | Sets the filler of a portal. |
|`/portal teleport <portal_name>` | Teleports the user to the provided portal. |
|`/portal tool` | Gives user the portal selector tool. |
| Command | Description |
|--------------------------------------------------------------|--------------------------------------------------------------------|
| `/destination change <destination_name>` | Sets the location of a destination to the user's current position. |
| `/destination clear <portal_name>` | Removes the destination of a portal. |
| `/destination create <destination_name>` | Creates a new destination at the user's current position. |
| `/destination info <destination_name>` | Displays information about the current destination. |
| `/destination list` | Displays a list of all the existing destinations. |
| `/destination purge <'invalid'/'no-portals'/'both'>` | Purges any unused and / or invalid destinations. |
| `/destination remove <destination_name>` | Removes a destination. |
| `/destination set <portal_name> <destination_name>` | Sets the destination of a portal. |
| `/destination sethere <portal_name>` | Sets the destination of the portal to the user's current location. |
| `/destination teleport <destination_name>` | Teleports the user to the provided destination. |
| `/portal create <portal_name>` | Creates a permissionless portal using the selected area. |
| `/portal debug` | Displays information about the portal being entered (no teleport). |
| `/portal info <portal_name>` | Displays information about a portal. |
| `/portal list` | Lists all existing portals. |
| `/portal permission whimc-portals.entry.<permission_suffix>` | Sets or removes portal permissions. |
| `/portal purge <'invalid'/'no-destination'/'both'>` | Purges any unused and / or invalid portals. |
| `/portal refill <portal_name>` | Regenerates the filler of a portal. |
| `/portal remove <portal_name>` | Removes a portal. |
| `/portal reshape <portal_name>` | Reshape a portal to your current selection. |
| `/portal setfiller <portal_name> <block_type>` | Sets the filler of a portal. |
| `/portal teleport <portal_name>` | Teleports the user to the provided portal. |
| `/portal tool` | Gives user the portal selector tool. |
| `/portal allowcitizens <portal_name>` | Allows Citizens NPCs to use the specified portal. |

### Definitions
- `invalid` means that the destination/portal is in a non-existent world (used in `/destination purge` and `/portal purge`)
- `no-portals` means that the destination has no linked portals (used in `/destination purge`)
- `no-destination` means that the portal has no linked destinations (used in `/portal purge`)

### Notes About Citizens Integration
- The pathing waypoint must be set 1 block behind the portal so that a Citizen steps on the portal block
- Citizens will swim up water filled portals
- Citizens will not go through lava filled portals

### How to Create a Portal

To set up a new portal you'll want to do `/portal tool` to get the portal selection tool. Then left click to select your first position and right click to select your second. These two blocks will be the bounding corners of a cuboid [like WorldEdit](https://worldedit.enginehub.org/en/latest/usage/regions/selections/). Then do:
Expand Down
17 changes: 16 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>edu.whimc</groupId>
<artifactId>WHIMC-Portals</artifactId>
<version>2.8.3</version>
<version>2.9.0</version>
<name>WHIMC Portals</name>
<description>Create portals for player teleportation</description>

Expand All @@ -14,6 +14,12 @@
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>

<!-- Add Citizens API -->
<repository>
<id>everything</id>
<url>https://repo.citizensnpcs.co/</url>
</repository>
</repositories>

<dependencies>
Expand All @@ -24,6 +30,15 @@
<version>1.14.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>

<!-- Add Citizens API -->
<dependency>
<groupId>net.citizensnpcs</groupId>
<artifactId>citizens-main</artifactId>
<version>2.0.29-SNAPSHOT</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
</dependencies>

<properties>
Expand Down
22 changes: 17 additions & 5 deletions src/main/java/edu/whimc/portals/Main.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package edu.whimc.portals;

import edu.whimc.portals.listeners.*;
import net.citizensnpcs.api.CitizensPlugin;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
Expand All @@ -10,10 +12,6 @@

import edu.whimc.portals.commands.destination.DestinationCommand;
import edu.whimc.portals.commands.portal.PortalCommand;
import edu.whimc.portals.listeners.PortalBlockChangeListener;
import edu.whimc.portals.listeners.PortalDamageListener;
import edu.whimc.portals.listeners.PortalEnterListener;
import edu.whimc.portals.listeners.ToolSelectListener;
import edu.whimc.portals.utils.LocationSaver;
import edu.whimc.portals.utils.MyConfig;
import edu.whimc.portals.utils.MyConfigManager;
Expand All @@ -32,11 +30,15 @@ public class Main extends JavaPlugin {
/** The instance of the location saver. */
private LocationSaver locationSaver;

/** Instance variable storing whether Citizens Plugin is enabled*/
private boolean citizensEnabled;

@Override
public void onEnable() {
manager = new MyConfigManager(this);
portalData = manager.getNewConfig("portalData.yml");
locationSaver = new LocationSaver(this);
citizensEnabled = Bukkit.getPluginManager().isPluginEnabled("Citizens");

Permission parent = new Permission(PERM_PREFIX + ".*");
Bukkit.getPluginManager().addPermission(parent);
Expand All @@ -59,6 +61,9 @@ public LocationSaver getLocationSaver() {
return locationSaver;
}

/** @return Status of Citizens Plugin */
public boolean getPluginStatus() { return citizensEnabled;}

/**
* Registers event listeners and sub-commands.
*/
Expand All @@ -69,6 +74,11 @@ private void registerStuff() {
pm.registerEvents(new PortalBlockChangeListener(), this);
pm.registerEvents(new PortalDamageListener(), this);

// check if Citizens is enabled
if (citizensEnabled) {
pm.registerEvents(new PortalEnterCitizensListener(), this);
}

PortalCommand pc = new PortalCommand(this);
getCommand("portal").setExecutor(pc);
getCommand("portal").setTabCompleter(pc);
Expand Down Expand Up @@ -117,7 +127,9 @@ private void initializeConfig() {
String fillerName = portalData.getString("Portals." + key + ".filler", "");
Material filler = Material.matchMaterial(fillerName);

Portal.loadPortal(this, key, permission, portalWorldName, pos1, pos2, dest, filler);
boolean allowCitizens = portalData.getBoolean("Portals." + key + ".allowcitizens");

Portal.loadPortal(this, key, permission, portalWorldName, pos1, pos2, dest, filler, allowCitizens);
}
}
}
Expand Down
28 changes: 24 additions & 4 deletions src/main/java/edu/whimc/portals/Portal.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ public class Portal {
/** If the portal is valid. */
private boolean valid = true;

/** If the portal allows citizens to use it. */
private boolean allowCitizens;

/**
* Creates a Portal.
*
Expand All @@ -74,7 +77,7 @@ public class Portal {
* @return The new Portal.
*/
public static Portal createPortal(Main plugin, String name, String permission, World world, Vector pos1, Vector pos2) {
return new Portal(plugin, name, permission, world.getName(), pos1, pos2, null, defaultFiller, true);
return new Portal(plugin, name, permission, world.getName(), pos1, pos2, null, defaultFiller, false, true);
}

/**
Expand All @@ -90,8 +93,8 @@ public static Portal createPortal(Main plugin, String name, String permission, W
* @param filler The filler materials of the portal.
* @return The loaded portal.
*/
public static Portal loadPortal(Main plugin, String name, String permission, String worldName, Vector pos1, Vector pos2, Destination destination, Material filler) {
return new Portal(plugin, name, permission, worldName, pos1, pos2, destination, filler, false);
public static Portal loadPortal(Main plugin, String name, String permission, String worldName, Vector pos1, Vector pos2, Destination destination, Material filler, boolean allowCitizens) {
return new Portal(plugin, name, permission, worldName, pos1, pos2, destination, filler, allowCitizens, false);
}

/**
Expand All @@ -107,7 +110,7 @@ public static Portal loadPortal(Main plugin, String name, String permission, Str
* @param filler The filler materials of the portal.
* @param isNew If the portal is a newly created one.
*/
private Portal(Main plugin, String name, String permission, String worldName, Vector pos1, Vector pos2, Destination destination, Material filler, boolean isNew){
private Portal(Main plugin, String name, String permission, String worldName, Vector pos1, Vector pos2, Destination destination, Material filler, boolean allowCitizens, boolean isNew){
this.plugin = plugin;
this.name = name;
this.worldName = worldName;
Expand All @@ -120,6 +123,7 @@ private Portal(Main plugin, String name, String permission, String worldName, Ve
} else {
this.filler = filler;
}
this.allowCitizens = allowCitizens;

if(isNew) {
setConfig("world", worldName);
Expand All @@ -129,6 +133,7 @@ private Portal(Main plugin, String name, String permission, String worldName, Ve
setConfig("filler", this.filler.toString());
setConfig("permission", permission);
setConfig("destination", destination == null ? Destination.NONE : name);
setConfig("allowcitizens", this.allowCitizens);
saveConfig();
}
portals.add(this);
Expand Down Expand Up @@ -655,4 +660,19 @@ public String toString() {
return "&f&o" + this.name;
}

/**
* Sets if Citizens NPCs are allowed to use the portal.
*
* @param allowCitizens Allow Citizens NPCs to use the portal.
*/
public void setAllowCitizens(boolean allowCitizens) {
this.allowCitizens = allowCitizens;
setConfig("allowcitizens", this.allowCitizens);
saveConfig();
}

/** If Citizens NPCs are allowed to use the portal. */
public boolean getAllowCitizens() {
return allowCitizens;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package edu.whimc.portals.commands.portal;

import edu.whimc.portals.Main;
import edu.whimc.portals.Portal;
import edu.whimc.portals.commands.AbstractSubCommand;
import edu.whimc.portals.utils.Messenger;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.Material;

import java.util.List;

/**
* The command to allow Citizens NPCs to use a portal.
* Command: "/portal allowcitizens"
*/
public class PortalAllowCitizens extends AbstractSubCommand {
/**
* Constructs a PortalAllowCitizens command with the given arguments.
*
* @param plugin the instance of the plugin.
* @param baseCommand the base command keyword.
* @param subCommand the sub command keyword.
*/
public PortalAllowCitizens(Main plugin, String baseCommand, String subCommand) {
super(plugin, baseCommand, subCommand);
super.description("Toggles Citizens NPCs' ability to travel through the portal.");
super.arguments("portal");
}

@Override
protected boolean onCommand(CommandSender sender, String[] args) {

// notify if Citizens plugin is not loaded and abort command execution
if(!plugin.getPluginStatus()) {
Messenger.msg(sender, "Citizens plugin is not loaded");
return true;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If Citizens isn't loaded you should send a message to the user and return early.

// notify if portal does not exist and abort command execution
Portal portal = Portal.getPortal(args[0]);
if (portal == null) {
Messenger.msg(sender, Messenger.ReplaceMessage.PORTAL_DOES_NOT_EXIST, args[0]);
return true;
}

// notify if portal is invalid, suggest deletion, and abort command execution
if (!portal.isValid()) {
Messenger.msg(sender, Messenger.ReplaceMessage.PORTAL_INVALID, portal.getName());
Messenger.msg(sender, Messenger.ReplaceMessage.SUGGEST_DELETE, "/portal remove " + portal.getName());
return true;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the portal's filler is water or lava I'd send a message to the user telling them about the consequences as noted in the README. I'd do the same thing in the setfiller sub-command if the portal allows citizens and the new fill type is water/lava.

portal.setAllowCitizens(!portal.getAllowCitizens());
Messenger.msg(sender, portal.getName() + " allows citizens: " + portal.getAllowCitizens());

// Notify consequences of water/lava filler
if (portal.getFiller() == Material.WATER) {
Messenger.msg(sender, Messenger.ReplaceMessage.WATER_FILLER);
}
if (portal.getFiller() == Material.LAVA) {
Messenger.msg(sender, Messenger.ReplaceMessage.LAVA_FILLER);
}

return true;
}

/**
* {@inheritDoc}
*/
@Override
protected List<String> onTabComplete(CommandSender sender, String[] args) {
return Portal.getTabCompletedPortals(args[0]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public PortalCommand(Main plugin) {
subCommands.put("setfiller", new PortalSetFiller(plugin, "portal", "setfiller"));
subCommands.put("teleport", new PortalTeleport(plugin, "portal", "teleport"));
subCommands.put("tool", new PortalTool(plugin, "portal", "tool"));
subCommands.put("allowcitizens", new PortalAllowCitizens(plugin, "portal", "allowcitizens"));
}

/**
Expand All @@ -57,7 +58,7 @@ public PortalCommand(Main plugin) {
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
// send command usages to user if no arguments provided
if (args.length == 0){
if (args.length == 0) {
sendCommands(sender);
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,17 @@ protected boolean onCommand(CommandSender sender, String[] args) {
// set the filler block of the portal
portal.setFiller(mat);
Messenger.msg(sender, ReplaceMessage.PORTAL_FILLER_SET, portal.getName(), mat.toString());

// if portal allows citizens, notify consequences of water/lava filler
if (portal.getAllowCitizens()) {
if (portal.getFiller() == Material.WATER) {
Messenger.msg(sender, ReplaceMessage.WATER_FILLER);
}
if (portal.getFiller() == Material.LAVA) {
Messenger.msg(sender, ReplaceMessage.LAVA_FILLER);
}
}

return true;
}

Expand Down
Loading