diff --git a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java
index 0f6dccb..ca2f2fa 100644
--- a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java
+++ b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java
@@ -90,6 +90,15 @@ public class CommandConfig implements CommandExecutor {
configuration.set(selectedOption.getConfigNode(), intValue);
}
}
+ case DOUBLE -> {
+ Double doubleValue = getDouble(commandSender, selectedOption, value);
+ if (doubleValue == null) {
+ return;
+ } else {
+ Stargate.getStargateConfig().getConfigOptionsReference().put(selectedOption, doubleValue);
+ configuration.set(selectedOption.getConfigNode(), doubleValue);
+ }
+ }
case STRING -> {
updateStringConfigValue(selectedOption, commandSender, value);
configuration.set(selectedOption.getConfigNode(), value);
@@ -314,6 +323,30 @@ public class CommandConfig implements CommandExecutor {
}
}
+ /**
+ * Gets a double from a string
+ *
+ * @param commandSender
The command sender that sent the config command
+ * @param selectedOption The option the command sender is trying to change
+ * @param value The value given
+ * @return A double, or null if it was invalid
+ */
+ private Double getDouble(CommandSender commandSender, ConfigOption selectedOption, String value) {
+ try {
+ double doubleValue = Double.parseDouble(value);
+
+ if (selectedOption == ConfigOption.EXIT_VELOCITY && doubleValue < 0) {
+ commandSender.sendMessage(ChatColor.RED + "This config option cannot be negative.");
+ return null;
+ }
+
+ return doubleValue;
+ } catch (NumberFormatException exception) {
+ commandSender.sendMessage(ChatColor.RED + "Invalid number given");
+ return null;
+ }
+ }
+
/**
* Reloads the config if necessary
*
diff --git a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java
index c37de81..693fc26 100644
--- a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java
+++ b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java
@@ -21,16 +21,17 @@ public class ConfigTabCompleter implements TabCompleter {
private List signTypes;
private List booleans;
- private List numbers;
+ private List integers;
private List chatColors;
private List languages;
private List extendedColors;
+ private List doubles;
@Nullable
@Override
public List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
@NotNull String[] args) {
- if (signTypes == null || booleans == null || numbers == null || chatColors == null || languages == null) {
+ if (signTypes == null || booleans == null || integers == null || chatColors == null || languages == null) {
initializeAutoCompleteLists();
}
if (args.length > 1) {
@@ -104,7 +105,16 @@ public class ConfigTabCompleter implements TabCompleter {
//If the config value is an integer, display some valid numbers
if (selectedOption.getDataType() == OptionDataType.INTEGER) {
if (typedText.trim().isEmpty()) {
- return numbers;
+ return integers;
+ } else {
+ return new ArrayList<>();
+ }
+ }
+
+ //If the config value is a double, display some valid numbers
+ if (selectedOption.getDataType() == OptionDataType.DOUBLE) {
+ if (typedText.trim().isEmpty()) {
+ return doubles;
} else {
return new ArrayList<>();
}
@@ -164,9 +174,9 @@ public class ConfigTabCompleter implements TabCompleter {
booleans.add("true");
booleans.add("false");
- numbers = new ArrayList<>();
- numbers.add("0");
- numbers.add("5");
+ integers = new ArrayList<>();
+ integers.add("0");
+ integers.add("5");
signTypes = new ArrayList<>();
for (Material material : Material.values()) {
@@ -181,6 +191,12 @@ public class ConfigTabCompleter implements TabCompleter {
extendedColors = new ArrayList<>(chatColors);
extendedColors.add("default");
extendedColors.add("inverted");
+
+ doubles = new ArrayList<>();
+ doubles.add("5");
+ doubles.add("1");
+ doubles.add("0.5");
+ doubles.add("0.1");
}
diff --git a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java
index 76d3870..2169d14 100644
--- a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java
+++ b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java
@@ -156,8 +156,12 @@ public enum ConfigOption {
/**
* Whether to alert admins about new updates
*/
- ADMIN_UPDATE_ALERT("adminUpdateAlert", "Whether to alert admins about new plugin updates", true);
+ ADMIN_UPDATE_ALERT("adminUpdateAlert", "Whether to alert admins about new plugin updates", true),
+ /**
+ * The velocity of players exiting a stargate, relative to the entry velocity
+ */
+ EXIT_VELOCITY("gates.exitVelocity", "The velocity of players exiting stargates, relative to the entry velocity", 0.1D);
private final String configNode;
private final String description;
@@ -184,6 +188,8 @@ public enum ConfigOption {
this.dataType = OptionDataType.BOOLEAN;
} else if (defaultValue instanceof Integer) {
this.dataType = OptionDataType.INTEGER;
+ } else if (defaultValue instanceof Double) {
+ this.dataType = OptionDataType.DOUBLE;
} else {
throw new IllegalArgumentException("Unknown config data type encountered: " + defaultValue);
}
diff --git a/src/main/java/net/knarcraft/stargate/config/OptionDataType.java b/src/main/java/net/knarcraft/stargate/config/OptionDataType.java
index 5cb8bee..25fcf76 100644
--- a/src/main/java/net/knarcraft/stargate/config/OptionDataType.java
+++ b/src/main/java/net/knarcraft/stargate/config/OptionDataType.java
@@ -6,17 +6,28 @@ package net.knarcraft.stargate.config;
public enum OptionDataType {
/**
- * The data type for the option is a String
+ * The data type if the option is a String
*/
STRING,
+
/**
- * The data type for the option is a Boolean
+ * The data type if the option is a Boolean
*/
BOOLEAN,
- STRING_LIST,
+
/**
- * The data type for the option is an Integer
+ * The data type if the option is a string list
*/
- INTEGER
+ STRING_LIST,
+
+ /**
+ * The data type if the option is an Integer
+ */
+ INTEGER,
+
+ /**
+ * The data type if the option is a double
+ */
+ DOUBLE
}
diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java
index 346bb4d..d8acd65 100644
--- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java
+++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java
@@ -358,6 +358,7 @@ public final class StargateConfig {
}
case BOOLEAN -> optionValue = newConfig.getBoolean(configNode);
case INTEGER -> optionValue = newConfig.getInt(configNode);
+ case DOUBLE -> optionValue = newConfig.getDouble(configNode);
default -> throw new IllegalArgumentException("Invalid config data type encountered");
}
configOptions.put(option, optionValue);
diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java
index 001ced9..1e19865 100644
--- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java
+++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java
@@ -179,6 +179,15 @@ public final class StargateGateConfig {
return (String) configOptions.get(ConfigOption.DEFAULT_GATE_NETWORK);
}
+ /**
+ * Gets the exit velocity of players using stargates, relative to the entry velocity
+ *
+ * @return The relative exit velocity
+ */
+ public double getExitVelocity() {
+ return (double) configOptions.get(ConfigOption.EXIT_VELOCITY);
+ }
+
/**
* Loads all config values related to gates
*/
diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java
index e8232bb..57d6e6d 100644
--- a/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java
+++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java
@@ -3,9 +3,12 @@ package net.knarcraft.stargate.portal.teleporter;
import net.knarcraft.stargate.Stargate;
import net.knarcraft.stargate.event.StargatePlayerPortalEvent;
import net.knarcraft.stargate.portal.Portal;
+import net.knarcraft.stargate.utility.DirectionHelper;
+import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerMoveEvent;
+import org.bukkit.util.Vector;
/**
* The portal teleporter takes care of the actual portal teleportation for any players
@@ -32,6 +35,7 @@ public class PlayerTeleporter extends Teleporter {
* @param event The player move event triggering the event
*/
public void teleport(Portal origin, PlayerMoveEvent event) {
+ double velocity = player.getVelocity().length();
Location traveller = player.getLocation();
Location exit = getExit(player, traveller);
@@ -56,9 +60,16 @@ public class PlayerTeleporter extends Teleporter {
if (event == null) {
player.teleport(exit);
} else {
- //The new method to teleport in a move event is set the "to" field.
+ //Set the exit location of the event
event.setTo(exit);
}
+
+ //Set the velocity of the teleported player after the teleportation is finished
+ Bukkit.getScheduler().scheduleSyncDelayedTask(Stargate.getInstance(), () -> {
+ Vector newVelocityDirection = DirectionHelper.getDirectionVectorFromYaw(portal.getYaw());
+ Vector newVelocity = newVelocityDirection.multiply(velocity * Stargate.getGateConfig().getExitVelocity());
+ player.setVelocity(newVelocity);
+ }, 1);
}
/**
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index 46d18d2..9775000 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -15,6 +15,8 @@ gates:
maxGatesEachNetwork: 0
# defaultGateNetwork - The default gate network
defaultGateNetwork: central
+ # exitVelocity - The velocity of players exiting stargates, relative to the entry velocity
+ exitVelocity: 0.1
cosmetic:
# rememberDestination - Whether to remember the cursor location between uses
rememberDestination: false