mirror of
https://github.com/SunNetservers/Launchpad.git
synced 2024-12-05 01:43:15 +01:00
Initial commit
This commit is contained in:
commit
d9c9813994
90
pom.xml
Normal file
90
pom.xml
Normal file
@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>net.knarcraft</groupId>
|
||||
<artifactId>Launchpad</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Launchpad</name>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<source>16</source>
|
||||
<target>16</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spigotmc-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>sonatype</id>
|
||||
<url>https://oss.sonatype.org/content/groups/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>knarcraft-repo</id>
|
||||
<url>https://git.knarcraft.net/api/packages/EpicKnarvik97/maven</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.20-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>24.0.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.knarcraft</groupId>
|
||||
<artifactId>KnarLib</artifactId>
|
||||
<version>1.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
102
src/main/java/net/knarcraft/launchpad/Launchpad.java
Normal file
102
src/main/java/net/knarcraft/launchpad/Launchpad.java
Normal file
@ -0,0 +1,102 @@
|
||||
package net.knarcraft.launchpad;
|
||||
|
||||
import net.knarcraft.launchpad.command.LaunchpadCommand;
|
||||
import net.knarcraft.launchpad.command.LaunchpadTabCompleter;
|
||||
import net.knarcraft.launchpad.command.ReloadCommand;
|
||||
import net.knarcraft.launchpad.config.LaunchpadConfiguration;
|
||||
import net.knarcraft.launchpad.listener.LaunchpadBreakListener;
|
||||
import net.knarcraft.launchpad.listener.LaunchpadModifyListener;
|
||||
import net.knarcraft.launchpad.listener.LaunchpadUseListener;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* The launchpad plugin's main class
|
||||
*/
|
||||
public final class Launchpad extends JavaPlugin {
|
||||
|
||||
private static Launchpad instance;
|
||||
private LaunchpadConfiguration launchpadConfiguration;
|
||||
|
||||
/**
|
||||
* Gets an instance of this plugin
|
||||
*
|
||||
* @return <p>An instance of this plugin</p>
|
||||
*/
|
||||
public static Launchpad getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads this plugin
|
||||
*/
|
||||
public void reload() {
|
||||
reloadConfig();
|
||||
this.getConfiguration().load(this.getConfig());
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a message
|
||||
*
|
||||
* @param level <p>The message level to log at</p>
|
||||
* @param message <p>The message to log</p>
|
||||
*/
|
||||
public static void log(Level level, String message) {
|
||||
Launchpad.getInstance().getLogger().log(level, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this plugin's configuration
|
||||
*
|
||||
* @return <p>This plugin's configuration</p>
|
||||
*/
|
||||
public LaunchpadConfiguration getConfiguration() {
|
||||
return launchpadConfiguration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
Launchpad.instance = this;
|
||||
getConfig().options().copyDefaults(true);
|
||||
saveConfig();
|
||||
|
||||
// Register events
|
||||
Bukkit.getPluginManager().registerEvents(new LaunchpadUseListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new LaunchpadBreakListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new LaunchpadModifyListener(), this);
|
||||
|
||||
// Register commands
|
||||
registerCommand("reload", new ReloadCommand(), null);
|
||||
registerCommand("launchpad", new LaunchpadCommand(), new LaunchpadTabCompleter());
|
||||
|
||||
this.launchpadConfiguration = new LaunchpadConfiguration(getConfig());
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a command
|
||||
*
|
||||
* @param commandName <p>The name of the command to register (defined in plugin.yml)</p>
|
||||
* @param commandExecutor <p>The executor for the command</p>
|
||||
* @param tabCompleter <p>The tab-completer to use, or null</p>
|
||||
*/
|
||||
private void registerCommand(@NotNull String commandName, @NotNull CommandExecutor commandExecutor,
|
||||
@Nullable TabCompleter tabCompleter) {
|
||||
PluginCommand command = this.getCommand(commandName);
|
||||
if (command != null) {
|
||||
command.setExecutor(commandExecutor);
|
||||
if (tabCompleter != null) {
|
||||
command.setTabCompleter(tabCompleter);
|
||||
}
|
||||
} else {
|
||||
log(Level.SEVERE, "Unable to register the command " + commandName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package net.knarcraft.launchpad.command;
|
||||
|
||||
import net.knarcraft.launchpad.launchpad.ModificationAction;
|
||||
import net.knarcraft.launchpad.launchpad.ModificationRequest;
|
||||
import net.knarcraft.launchpad.launchpad.ModificationRequestHandler;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class LaunchpadCommand implements CommandExecutor {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] arguments) {
|
||||
if (!(commandSender instanceof Player player)) {
|
||||
commandSender.sendMessage("This command can only be used by a player");
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Add an abort action to clear the player's modification requests
|
||||
|
||||
// TODO: Properly allow nulling (unsetting) values
|
||||
|
||||
if (arguments.length < 1) {
|
||||
return false;
|
||||
}
|
||||
ModificationAction action = ModificationAction.getFromCommandName(arguments[0]);
|
||||
if (action == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure
|
||||
if (action.needsArgument() && (arguments.length < 2 || !action.isValidArgument(arguments[1]))) {
|
||||
//TODO: Perhaps display the current value instead when missing an argument?
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Register the modification request
|
||||
ModificationRequest request = null;
|
||||
switch (action) {
|
||||
case ADD, REMOVE -> request = new ModificationRequest(action, null);
|
||||
case VERTICAL_VELOCITY, HORIZONTAL_VELOCITY, FIXED_DIRECTION ->
|
||||
request = new ModificationRequest(action, arguments[1]);
|
||||
}
|
||||
ModificationRequestHandler.addRequest(player.getUniqueId(), request);
|
||||
commandSender.sendMessage("Right-click the block to modify launchpad properties for");
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
package net.knarcraft.launchpad.command;
|
||||
|
||||
import net.knarcraft.launchpad.launchpad.ModificationAction;
|
||||
import net.knarcraft.launchpad.util.TabCompleteHelper;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A tab-completer for the launchpad command
|
||||
*/
|
||||
public class LaunchpadTabCompleter implements TabCompleter {
|
||||
|
||||
private List<String> modificationActions = null;
|
||||
private List<String> blockFaces = null;
|
||||
private List<String> doubles = null;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] arguments) {
|
||||
if (arguments.length == 1) {
|
||||
// Display available sub-commands
|
||||
return TabCompleteHelper.filterMatchingContains(getModificationActions(), arguments[0]);
|
||||
} else if (arguments.length == 2) {
|
||||
// If given a valid modification action, and an argument is expected, display possible values
|
||||
ModificationAction action = ModificationAction.getFromCommandName(arguments[0]);
|
||||
if (action != null && action.needsArgument()) {
|
||||
return TabCompleteHelper.filterMatchingContains(getTabCompletions(action), arguments[1]);
|
||||
} else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets tab-completions for the given modification action
|
||||
*
|
||||
* @param action <p>The action to get tab-completions for</p>
|
||||
* @return <p>Tab-completion values</p>
|
||||
*/
|
||||
private @NotNull List<String> getTabCompletions(@NotNull ModificationAction action) {
|
||||
return switch (action) {
|
||||
case FIXED_DIRECTION -> getBlockFaces();
|
||||
case HORIZONTAL_VELOCITY, VERTICAL_VELOCITY -> getPositiveDoubles();
|
||||
default -> new ArrayList<>();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets tab-completions for positive double values
|
||||
*
|
||||
* @return <p>Tab-completion values</p>
|
||||
*/
|
||||
private List<String> getPositiveDoubles() {
|
||||
if (this.doubles == null) {
|
||||
this.doubles = new ArrayList<>();
|
||||
this.doubles.add("0.1");
|
||||
this.doubles.add("0.5");
|
||||
this.doubles.add("1");
|
||||
this.doubles.add("1.5");
|
||||
this.doubles.add("2");
|
||||
}
|
||||
return this.doubles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets tab-completions for block faces
|
||||
*
|
||||
* @return <p>Tab-completion values</p>
|
||||
*/
|
||||
private List<String> getBlockFaces() {
|
||||
if (this.blockFaces == null) {
|
||||
this.blockFaces = new ArrayList<>();
|
||||
for (BlockFace face : BlockFace.values()) {
|
||||
// Only add block faces on the X Z plane
|
||||
if (face.getDirection().dot(BlockFace.WEST.getDirection().crossProduct(
|
||||
BlockFace.NORTH.getDirection())) == 0 && face != BlockFace.SELF) {
|
||||
blockFaces.add(face.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.blockFaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of every modification action's command
|
||||
*
|
||||
* @return <p>All modification action commands</p>
|
||||
*/
|
||||
private List<String> getModificationActions() {
|
||||
if (this.modificationActions == null) {
|
||||
this.modificationActions = new ArrayList<>();
|
||||
for (ModificationAction action : ModificationAction.values()) {
|
||||
modificationActions.add(action.getCommandName());
|
||||
}
|
||||
}
|
||||
return this.modificationActions;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package net.knarcraft.launchpad.command;
|
||||
|
||||
import net.knarcraft.launchpad.Launchpad;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The command used for reloading this plugin
|
||||
*/
|
||||
public class ReloadCommand implements TabExecutor {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] strings) {
|
||||
Launchpad.getInstance().reload();
|
||||
commandSender.sendMessage("Launchpad reloaded");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] strings) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
package net.knarcraft.launchpad.config;
|
||||
|
||||
import net.knarcraft.launchpad.Launchpad;
|
||||
import net.knarcraft.launchpad.launchpad.LaunchpadBlockHandler;
|
||||
import net.knarcraft.launchpad.util.MaterialHelper;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* The configuration for this plugin
|
||||
*/
|
||||
public class LaunchpadConfiguration {
|
||||
|
||||
private @NotNull FileConfiguration fileConfiguration;
|
||||
private double horizontalVelocity;
|
||||
private double verticalVelocity;
|
||||
private final @NotNull Set<Material> launchpadMaterials = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Instantiate a new launch pad configuration
|
||||
*
|
||||
* @param fileConfiguration <p>The file configuration to use</p>
|
||||
*/
|
||||
public LaunchpadConfiguration(@NotNull FileConfiguration fileConfiguration) {
|
||||
this.fileConfiguration = fileConfiguration;
|
||||
load(fileConfiguration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads this configuration from the given file configuration
|
||||
*
|
||||
* @param fileConfiguration <p>The file configuration to load</p>
|
||||
*/
|
||||
public void load(@NotNull FileConfiguration fileConfiguration) {
|
||||
this.fileConfiguration = fileConfiguration;
|
||||
ConfigurationSection launchpadSection = fileConfiguration.getConfigurationSection("launchpad");
|
||||
if (launchpadSection == null) {
|
||||
Launchpad.log(Level.WARNING, "Unable to load launchpad configuration. " +
|
||||
"The \"launchpad\" configuration section is missing.");
|
||||
return;
|
||||
}
|
||||
this.launchpadMaterials.clear();
|
||||
List<?> materials = launchpadSection.getList("materials");
|
||||
if (materials != null) {
|
||||
this.launchpadMaterials.addAll(MaterialHelper.loadMaterialList(materials));
|
||||
} else {
|
||||
this.launchpadMaterials.add(Material.LIGHT_WEIGHTED_PRESSURE_PLATE);
|
||||
}
|
||||
// If a non-block material is specified, simply ignore it
|
||||
this.launchpadMaterials.removeIf((item) -> !item.isBlock());
|
||||
|
||||
this.horizontalVelocity = launchpadSection.getDouble("horizontalVelocity");
|
||||
this.verticalVelocity = launchpadSection.getDouble("verticalVelocity");
|
||||
|
||||
// Load launchpad blocks
|
||||
LaunchpadBlockHandler.loadAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given material is not used for launch pads
|
||||
*
|
||||
* @param material <p>The material to check</p>
|
||||
* @return <p>True if the given material is not used for launchpads</p>
|
||||
*/
|
||||
public boolean isNotLaunchpadMaterial(@NotNull Material material) {
|
||||
return !this.launchpadMaterials.contains(material);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default horizontal velocity for launchpads
|
||||
*
|
||||
* @param material <p>The material of the launchpad</p>
|
||||
* @return <p>The default horizontal velocity</p>
|
||||
*/
|
||||
public double getHorizontalVelocity(@NotNull Material material) {
|
||||
double materialVelocity = fileConfiguration.getDouble(
|
||||
String.format("launchpad.materialVelocities.%s.horizontalVelocity", material.name()), -1);
|
||||
if (materialVelocity >= 0) {
|
||||
return materialVelocity;
|
||||
}
|
||||
return Math.max(this.horizontalVelocity, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default vertical velocity for launchpads
|
||||
*
|
||||
* @param material <p>The material of the launchpad</p>
|
||||
* @return <p>The default vertical velocity</p>
|
||||
*/
|
||||
public double getVerticalVelocity(@NotNull Material material) {
|
||||
double materialVelocity = fileConfiguration.getDouble(
|
||||
String.format("launchpad.materialVelocities.%s.verticalVelocity", material.name()), -1);
|
||||
if (materialVelocity >= 0) {
|
||||
return materialVelocity;
|
||||
}
|
||||
return Math.max(this.verticalVelocity, 0);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
package net.knarcraft.launchpad.launchpad;
|
||||
|
||||
import net.knarcraft.launchpad.Launchpad;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A block registered as a launchpad
|
||||
*/
|
||||
public class LaunchpadBlock {
|
||||
|
||||
private final @NotNull Block block;
|
||||
private double horizontalVelocity;
|
||||
private double verticalVelocity;
|
||||
private @Nullable BlockFace fixedDirection;
|
||||
|
||||
/**
|
||||
* Instantiates a new launchpad block
|
||||
*
|
||||
* @param block <p>The block to register this launchpad block for</p>
|
||||
*/
|
||||
public LaunchpadBlock(@NotNull Block block) {
|
||||
this.block = block;
|
||||
this.horizontalVelocity = -1;
|
||||
this.verticalVelocity = -1;
|
||||
this.fixedDirection = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new launchpad block
|
||||
*
|
||||
* @param block <p>The block to register this launchpad block for</p>
|
||||
* @param horizontalVelocity <p>The horizontal velocity of the launchpad</p>
|
||||
* @param verticalVelocity <p>The vertical velocity of the launchpad</p>
|
||||
* @param fixedDirection <p>The fixed direction of the launchpad</p>
|
||||
*/
|
||||
public LaunchpadBlock(@NotNull Block block, double horizontalVelocity, double verticalVelocity,
|
||||
@Nullable BlockFace fixedDirection) {
|
||||
this.block = block;
|
||||
setHorizontalVelocity(horizontalVelocity);
|
||||
setVerticalVelocity(verticalVelocity);
|
||||
setFixedDirection(fixedDirection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the block that contains this launchpad
|
||||
*
|
||||
* @return <p>This launchpad's block</p>
|
||||
*/
|
||||
public @NotNull Block getBlock() {
|
||||
return this.block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the horizontal velocity of this launchpad
|
||||
*
|
||||
* @return <p>The horizontal velocity of this launchpad</p>
|
||||
*/
|
||||
public double getHorizontalVelocity() {
|
||||
if (this.horizontalVelocity >= 0) {
|
||||
return this.horizontalVelocity;
|
||||
} else {
|
||||
return Launchpad.getInstance().getConfiguration().getHorizontalVelocity(this.block.getType());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the vertical velocity of this launchpad
|
||||
*
|
||||
* @return <p>The vertical velocity of this launchpad</p>
|
||||
*/
|
||||
public double getVerticalVelocity() {
|
||||
if (this.verticalVelocity >= 0) {
|
||||
return this.verticalVelocity;
|
||||
} else {
|
||||
return Launchpad.getInstance().getConfiguration().getVerticalVelocity(this.block.getType());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fixed direction of this launchpad block
|
||||
*
|
||||
* @return <p>The fixed direction, or null if not fixed</p>
|
||||
*/
|
||||
public @Nullable BlockFace getFixedDirection() {
|
||||
return this.fixedDirection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the horizontal velocity of this launchpad
|
||||
*
|
||||
* @param horizontalVelocity <p>The horizontal velocity to set</p>
|
||||
*/
|
||||
public void setHorizontalVelocity(double horizontalVelocity) {
|
||||
this.horizontalVelocity = Math.max(0, horizontalVelocity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the vertical velocity of this launchpad
|
||||
*
|
||||
* @param verticalVelocity <p>The vertical velocity to set</p>
|
||||
*/
|
||||
public void setVerticalVelocity(double verticalVelocity) {
|
||||
this.verticalVelocity = Math.max(0, verticalVelocity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the fixed direction of this launchpad
|
||||
*
|
||||
* @param fixedDirection <p>The fixed direction, or null to unset the fixed direction</p>
|
||||
*/
|
||||
public void setFixedDirection(@Nullable BlockFace fixedDirection) {
|
||||
// Make sure the fixed direction is in the correct plane by multiplying it by the normal vector to the
|
||||
// North x West plane.
|
||||
if (fixedDirection != null && (fixedDirection.getDirection().dot(BlockFace.WEST.getDirection().crossProduct(
|
||||
BlockFace.NORTH.getDirection()))) != 0) {
|
||||
return;
|
||||
}
|
||||
this.fixedDirection = fixedDirection;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,147 @@
|
||||
package net.knarcraft.launchpad.launchpad;
|
||||
|
||||
import net.knarcraft.launchpad.Launchpad;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* A handler class to keep track of launchpad blocks
|
||||
*/
|
||||
public final class LaunchpadBlockHandler {
|
||||
|
||||
private static final File launchpadsFile = new File(Launchpad.getInstance().getDataFolder(), "data.yml");
|
||||
private static @NotNull Map<Block, LaunchpadBlock> launchpadBlocks = new HashMap<>();
|
||||
|
||||
private LaunchpadBlockHandler() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all current launchpad blocks from disk
|
||||
*/
|
||||
public static void loadAll() {
|
||||
YamlConfiguration yamlConfiguration = YamlConfiguration.loadConfiguration(launchpadsFile);
|
||||
ConfigurationSection launchpadsSection = yamlConfiguration.getConfigurationSection("launchpads");
|
||||
launchpadBlocks = new HashMap<>();
|
||||
if (launchpadsSection == null) {
|
||||
Launchpad.log(Level.WARNING, "Launchpads section not found in data.yml. Ignore this warning if" +
|
||||
" you have no saved launchpads.");
|
||||
return;
|
||||
}
|
||||
|
||||
for (String key : launchpadsSection.getKeys(false)) {
|
||||
try {
|
||||
loadLaunchpad(launchpadsSection, key);
|
||||
} catch (InvalidConfigurationException exception) {
|
||||
Launchpad.log(Level.SEVERE, "Unable to load launchpad " + key + ": " + exception.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new launchpad block
|
||||
*
|
||||
* @param launchpadBlock <p>The launchpad block to register</p>
|
||||
*/
|
||||
public static void registerLaunchpadBlock(@NotNull LaunchpadBlock launchpadBlock) {
|
||||
launchpadBlocks.put(launchpadBlock.getBlock(), launchpadBlock);
|
||||
saveAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters a launchpad block
|
||||
*
|
||||
* @param block <p>The block containing the launchpad block to unregister</p>
|
||||
*/
|
||||
public static void unregisterLaunchpadBlock(@NotNull Block block) {
|
||||
if (launchpadBlocks.containsKey(block)) {
|
||||
launchpadBlocks.remove(block);
|
||||
saveAll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the launchpad block for the given block
|
||||
*
|
||||
* @param block <p>The block containing the launchpad</p>
|
||||
* @return <p>The launchpad block, or null if not a launchpad</p>
|
||||
*/
|
||||
public static @Nullable LaunchpadBlock getLaunchpadBlock(@NotNull Block block) {
|
||||
return launchpadBlocks.get(block);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves all current launchpad blocks to disk
|
||||
*/
|
||||
public static void saveAll() {
|
||||
YamlConfiguration yamlConfiguration = YamlConfiguration.loadConfiguration(launchpadsFile);
|
||||
ConfigurationSection launchpadsSection = yamlConfiguration.createSection("launchpads");
|
||||
for (Block block : launchpadBlocks.keySet()) {
|
||||
String locationString = Objects.requireNonNull(block.getWorld()).getUID() + "," +
|
||||
block.getX() + "," + block.getY() + "," + block.getZ();
|
||||
ConfigurationSection launchpadSection = launchpadsSection.createSection(locationString);
|
||||
LaunchpadBlock launchpadBlock = launchpadBlocks.get(block);
|
||||
launchpadSection.set("verticalVelocity", launchpadBlock.getVerticalVelocity());
|
||||
launchpadSection.set("horizontalVelocity", launchpadBlock.getHorizontalVelocity());
|
||||
launchpadSection.set("fixedDirection", launchpadBlock.getFixedDirection() != null ?
|
||||
launchpadBlock.getFixedDirection().name() : null);
|
||||
}
|
||||
try {
|
||||
yamlConfiguration.save(launchpadsFile);
|
||||
} catch (IOException e) {
|
||||
Launchpad.log(Level.SEVERE, "Unable to save launchpads. Data loss will occur! Please report " +
|
||||
"details about this problem to the developer.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a single launchpad
|
||||
*
|
||||
* @param configurationSection <p>The configuration section to read</p>
|
||||
* @param key <p>The key containing tha launchpad's info</p>
|
||||
* @throws InvalidConfigurationException <p>If unable to parse the launchpad's location</p>
|
||||
*/
|
||||
private static void loadLaunchpad(@NotNull ConfigurationSection configurationSection,
|
||||
@NotNull String key) throws InvalidConfigurationException {
|
||||
String[] locationParts = key.split(",");
|
||||
Block launchpadBlock;
|
||||
try {
|
||||
launchpadBlock = new Location(Bukkit.getWorld(UUID.fromString(locationParts[0])),
|
||||
Double.parseDouble(locationParts[1]), Double.parseDouble(locationParts[2]),
|
||||
Double.parseDouble(locationParts[3])).getBlock();
|
||||
} catch (NumberFormatException exception) {
|
||||
throw new InvalidConfigurationException("Invalid launchpad location");
|
||||
}
|
||||
|
||||
// If the launchpad's block has been removed, ignore it
|
||||
if (launchpadBlock.getType().isAir()) {
|
||||
return;
|
||||
}
|
||||
|
||||
double horizontalVelocity = configurationSection.getDouble(key + ".horizontalVelocity", -1);
|
||||
double verticalVelocity = configurationSection.getDouble(key + ".verticalVelocity", -1);
|
||||
String fixedDirectionString = configurationSection.getString(key + ".fixedDirection");
|
||||
BlockFace fixedDirection = null;
|
||||
if (fixedDirectionString != null) {
|
||||
fixedDirection = BlockFace.valueOf(configurationSection.getString(key + ".fixedDirection"));
|
||||
}
|
||||
launchpadBlocks.put(launchpadBlock, new LaunchpadBlock(launchpadBlock, horizontalVelocity, verticalVelocity,
|
||||
fixedDirection));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
package net.knarcraft.launchpad.launchpad;
|
||||
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A representation of the types of actions that can be used to modify a launchpad
|
||||
*/
|
||||
public enum ModificationAction {
|
||||
|
||||
/**
|
||||
* The action to remove a registered launchpad
|
||||
*/
|
||||
REMOVE("remove", false),
|
||||
|
||||
/**
|
||||
* The action to register a launchpad
|
||||
*/
|
||||
ADD("add", false),
|
||||
|
||||
/**
|
||||
* The action to modify the vertical velocity of a launchpad
|
||||
*/
|
||||
VERTICAL_VELOCITY("verticalVelocity", true),
|
||||
|
||||
/**
|
||||
* The action to modify the horizontal velocity of a launchpad
|
||||
*/
|
||||
HORIZONTAL_VELOCITY("horizontalVelocity", true),
|
||||
|
||||
/**
|
||||
* The action of setting the fixed direction of a launchpad
|
||||
*/
|
||||
FIXED_DIRECTION("fixedDirection", true),
|
||||
;
|
||||
|
||||
private final @NotNull String commandName;
|
||||
private final boolean needsArgument;
|
||||
|
||||
/**
|
||||
* Instantiates a new modification action
|
||||
*
|
||||
* @param commandName <p>The name of the command used to specify this action in command input</p>
|
||||
* @param needsArgument <p>Whether the modification action requires an argument in order to be valid</p>
|
||||
*/
|
||||
ModificationAction(@NotNull String commandName, boolean needsArgument) {
|
||||
this.commandName = commandName;
|
||||
this.needsArgument = needsArgument;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the command name used to specify this action in command input
|
||||
*
|
||||
* @return <p>The command name</p>
|
||||
*/
|
||||
public @NotNull String getCommandName() {
|
||||
return this.commandName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether this modification action requires an argument
|
||||
*
|
||||
* @return <p>True if this action requires an argument</p>
|
||||
*/
|
||||
public boolean needsArgument() {
|
||||
return this.needsArgument;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given argument is valid for this action
|
||||
*
|
||||
* @param argument <p>The argument to check</p>
|
||||
* @return <p>True if the argument is valid</p>
|
||||
*/
|
||||
public boolean isValidArgument(String argument) {
|
||||
if (this == ModificationAction.HORIZONTAL_VELOCITY || this == ModificationAction.VERTICAL_VELOCITY) {
|
||||
try {
|
||||
double ignored = Double.parseDouble(argument);
|
||||
return true;
|
||||
} catch (NullPointerException exception) {
|
||||
return false;
|
||||
}
|
||||
} else if (this == ModificationAction.FIXED_DIRECTION) {
|
||||
try {
|
||||
BlockFace.valueOf(argument.toUpperCase());
|
||||
return true;
|
||||
} catch (IllegalArgumentException exception) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a modification action given its command name
|
||||
*
|
||||
* @param commandName <p>A modification action's command name</p>
|
||||
* @return <p>The matching modification action, or null if not found</p>
|
||||
*/
|
||||
public static @Nullable ModificationAction getFromCommandName(@NotNull String commandName) {
|
||||
for (ModificationAction action : ModificationAction.values()) {
|
||||
if (action.getCommandName().equalsIgnoreCase(commandName)) {
|
||||
return action;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package net.knarcraft.launchpad.launchpad;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A stored representation of a user's request to modify a launchpad
|
||||
*
|
||||
* @param modificationAction <p>The action the user wants to run</p>
|
||||
* @param value <p>The new value of a property, if applicable</p>
|
||||
*/
|
||||
public record ModificationRequest(@NotNull ModificationAction modificationAction, @Nullable String value) {
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package net.knarcraft.launchpad.launchpad;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* A handler to keep track of launchpad modification requests
|
||||
*/
|
||||
public final class ModificationRequestHandler {
|
||||
|
||||
private static final Map<UUID, Set<ModificationRequest>> modificationRequests = new HashMap<>();
|
||||
|
||||
private ModificationRequestHandler() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new modification request to this handler
|
||||
*
|
||||
* @param playerId <p>The id of the player that created the request</p>
|
||||
* @param request <p>The player's modification request</p>
|
||||
*/
|
||||
public static void addRequest(@NotNull UUID playerId, @NotNull ModificationRequest request) {
|
||||
Set<ModificationRequest> requests = modificationRequests.get(playerId);
|
||||
if (requests == null) {
|
||||
modificationRequests.put(playerId, new HashSet<>());
|
||||
requests = modificationRequests.get(playerId);
|
||||
}
|
||||
|
||||
requests.add(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets and removes all modification requests registered for the given player
|
||||
*
|
||||
* @param playerId <p>The player to get modification requests for</p>
|
||||
*/
|
||||
public static @Nullable Set<ModificationRequest> getRequests(@NotNull UUID playerId) {
|
||||
return modificationRequests.remove(playerId);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package net.knarcraft.launchpad.listener;
|
||||
|
||||
import net.knarcraft.launchpad.launchpad.LaunchpadBlockHandler;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockBurnEvent;
|
||||
import org.bukkit.event.block.BlockExplodeEvent;
|
||||
import org.bukkit.event.block.BlockPistonExtendEvent;
|
||||
import org.bukkit.event.block.BlockPistonRetractEvent;
|
||||
import org.bukkit.event.block.LeavesDecayEvent;
|
||||
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* A listener for broken launchpads
|
||||
*/
|
||||
public class LaunchpadBreakListener implements Listener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onLaunchpadBreak(BlockBreakEvent event) {
|
||||
unregisterLaunchpad(event.getBlock());
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onLaunchpadBurn(BlockBurnEvent event) {
|
||||
unregisterLaunchpad(event.getBlock());
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onPistonLaunchpadPush(BlockPistonExtendEvent event) {
|
||||
unregisterLaunchpad(event.getBlocks());
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onPistonLaunchpadPull(BlockPistonRetractEvent event) {
|
||||
unregisterLaunchpad(event.getBlocks());
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onLaunchpadExplode(EntityExplodeEvent event) {
|
||||
unregisterLaunchpad(event.blockList());
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onLaunchpadExplode(BlockExplodeEvent event) {
|
||||
unregisterLaunchpad(event.blockList());
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onLeafLaunchpadDecay(LeavesDecayEvent event) {
|
||||
unregisterLaunchpad(event.getBlock());
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onLaunchpadChange(EntityChangeBlockEvent event) {
|
||||
if (event.getTo().isAir()) {
|
||||
unregisterLaunchpad(event.getBlock());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the given blocks if it's a registered launchpad
|
||||
*
|
||||
* @param blocks <p>The blocks to unregister</p>
|
||||
*/
|
||||
private void unregisterLaunchpad(Collection<Block> blocks) {
|
||||
for (Block block : blocks) {
|
||||
unregisterLaunchpad(block);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the given block if it's a registered launchpad
|
||||
*
|
||||
* @param block <p>The block to unregister</p>
|
||||
*/
|
||||
private void unregisterLaunchpad(Block block) {
|
||||
LaunchpadBlockHandler.unregisterLaunchpadBlock(block);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package net.knarcraft.launchpad.listener;
|
||||
|
||||
import net.knarcraft.launchpad.launchpad.LaunchpadBlock;
|
||||
import net.knarcraft.launchpad.launchpad.LaunchpadBlockHandler;
|
||||
import net.knarcraft.launchpad.launchpad.ModificationRequest;
|
||||
import net.knarcraft.launchpad.launchpad.ModificationRequestHandler;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A listener for application of launchpad requests
|
||||
*/
|
||||
public class LaunchpadModifyListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onLaunchpadClick(PlayerInteractEvent event) {
|
||||
Block clicked = event.getClickedBlock();
|
||||
if (event.getAction() != Action.RIGHT_CLICK_BLOCK || clicked == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<ModificationRequest> requests = ModificationRequestHandler.getRequests(event.getPlayer().getUniqueId());
|
||||
if (requests == null || requests.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (ModificationRequest request : requests) {
|
||||
handleRequest(request, clicked);
|
||||
}
|
||||
|
||||
event.setUseItemInHand(Event.Result.DENY);
|
||||
event.setUseInteractedBlock(Event.Result.DENY);
|
||||
|
||||
event.getPlayer().sendMessage("Modified launchpad at " + clicked.getLocation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the tasks required by the given launchpad modification request
|
||||
*
|
||||
* @param request <p>The modification request to handle</p>
|
||||
* @param block <p>The block to perform the request on</p>
|
||||
*/
|
||||
private void handleRequest(@NotNull ModificationRequest request, @NotNull Block block) {
|
||||
LaunchpadBlock existingLaunchpad = LaunchpadBlockHandler.getLaunchpadBlock(block);
|
||||
boolean isLaunchpad = existingLaunchpad != null;
|
||||
|
||||
if (!isLaunchpad) {
|
||||
existingLaunchpad = new LaunchpadBlock(block);
|
||||
}
|
||||
|
||||
switch (request.modificationAction()) {
|
||||
case REMOVE -> {
|
||||
LaunchpadBlockHandler.unregisterLaunchpadBlock(block);
|
||||
return;
|
||||
}
|
||||
case VERTICAL_VELOCITY -> {
|
||||
if (request.value() != null) {
|
||||
existingLaunchpad.setVerticalVelocity(Double.parseDouble(request.value()));
|
||||
}
|
||||
}
|
||||
case HORIZONTAL_VELOCITY -> {
|
||||
if (request.value() != null) {
|
||||
existingLaunchpad.setHorizontalVelocity(Double.parseDouble(request.value()));
|
||||
}
|
||||
}
|
||||
case FIXED_DIRECTION -> {
|
||||
if (request.value() != null) {
|
||||
existingLaunchpad.setFixedDirection(BlockFace.valueOf(request.value().toUpperCase()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isLaunchpad) {
|
||||
// If not already registered as a launchpad, register it. This completely handles the ADD case
|
||||
LaunchpadBlockHandler.registerLaunchpadBlock(existingLaunchpad);
|
||||
} else {
|
||||
// Save if the existing launchpad was modified
|
||||
LaunchpadBlockHandler.saveAll();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
package net.knarcraft.launchpad.listener;
|
||||
|
||||
import net.knarcraft.launchpad.Launchpad;
|
||||
import net.knarcraft.launchpad.config.LaunchpadConfiguration;
|
||||
import net.knarcraft.launchpad.launchpad.LaunchpadBlock;
|
||||
import net.knarcraft.launchpad.launchpad.LaunchpadBlockHandler;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A listener for any
|
||||
*/
|
||||
public class LaunchpadUseListener implements Listener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPressurePlateUse(PlayerInteractEvent event) {
|
||||
if (event.getAction() != Action.PHYSICAL || !event.hasBlock() || event.getClickedBlock() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// A registered launchpad ignores material checks
|
||||
LaunchpadBlock launchpad = LaunchpadBlockHandler.getLaunchpadBlock(event.getClickedBlock());
|
||||
if (launchpad != null) {
|
||||
launch(event.getPlayer(), launchpad);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the material is a valid launchpad
|
||||
if (Launchpad.getInstance().getConfiguration().isNotLaunchpadMaterial(event.getClickedBlock().getType())) {
|
||||
return;
|
||||
}
|
||||
launch(event.getPlayer(), event.getClickedBlock().getType());
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onMove(PlayerMoveEvent event) {
|
||||
if (event.getTo() == null || event.getFrom().getBlock().equals(event.getTo().getBlock())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the player is standing on a non-full block, event.getTo will give the correct block, but if not, the
|
||||
// block below has to be checked instead.
|
||||
Block block = event.getTo().getBlock();
|
||||
if (block.getType().isAir()) {
|
||||
block = block.getRelative(BlockFace.DOWN);
|
||||
}
|
||||
|
||||
// Pressure plates are detected in onPressurePlateUse instead
|
||||
Material type = block.getType();
|
||||
if (Tag.PRESSURE_PLATES.isTagged(type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LaunchpadBlock launchpad = LaunchpadBlockHandler.getLaunchpadBlock(block);
|
||||
// Ignore material check if the block is a registered launchpad
|
||||
if (launchpad == null && Launchpad.getInstance().getConfiguration().isNotLaunchpadMaterial(type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
double velocity = player.getVelocity().getY();
|
||||
// These are constants for the velocity of a player when landing from a jump and just walking respectively.
|
||||
// When flying, the Y velocity is always 0.
|
||||
double LANDING_Y_VELOCITY = -0.22768848754498797;
|
||||
double DEFAULT_Y_VELOCITY = -0.0784000015258789;
|
||||
// Make sure not to trigger until the player touches the block. This doesn't work if the player is flying.
|
||||
if (!player.isFlying() && (velocity != LANDING_Y_VELOCITY && velocity != DEFAULT_Y_VELOCITY)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Launch the player
|
||||
if (launchpad != null) {
|
||||
launch(event.getPlayer(), launchpad);
|
||||
} else {
|
||||
launch(player, type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches a player that hit a launchpad
|
||||
*
|
||||
* @param player <p>The player to launch</p>
|
||||
* @param material <p>The material used for the launchpad</p>
|
||||
*/
|
||||
private void launch(@NotNull Player player, @NotNull Material material) {
|
||||
LaunchpadConfiguration configuration = Launchpad.getInstance().getConfiguration();
|
||||
launch(player, player.getFacing(), configuration.getHorizontalVelocity(material),
|
||||
configuration.getVerticalVelocity(material));
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches a player that hit a registered launchpad
|
||||
*
|
||||
* @param player <p>The player to launch</p>
|
||||
* @param launchpadBlock <p>The launchpad the player hit</p>
|
||||
*/
|
||||
private void launch(@NotNull Player player, @NotNull LaunchpadBlock launchpadBlock) {
|
||||
BlockFace directionFace = launchpadBlock.getFixedDirection();
|
||||
if (directionFace == null) {
|
||||
directionFace = player.getFacing();
|
||||
}
|
||||
launch(player, directionFace, launchpadBlock.getHorizontalVelocity(), launchpadBlock.getVerticalVelocity());
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches a player that hit a launchpad
|
||||
*
|
||||
* @param player <p>The player that hit the launchpad</p>
|
||||
* @param directionFace <p>The direction to launch the player</p>
|
||||
* @param horizontalVelocity <p>The horizontal velocity to apply to the player</p>
|
||||
* @param verticalVelocity <p>The vertical velocity to apply to the player</p>
|
||||
*/
|
||||
private void launch(@NotNull Player player, @NotNull BlockFace directionFace, double horizontalVelocity,
|
||||
double verticalVelocity) {
|
||||
Vector direction = directionFace.getDirection();
|
||||
direction = direction.multiply(horizontalVelocity);
|
||||
direction = direction.add(new Vector(0, verticalVelocity, 0));
|
||||
player.setVelocity(direction);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package net.knarcraft.launchpad.util;
|
||||
|
||||
import net.knarcraft.launchpad.Launchpad;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Tag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* A helper class for dealing with and parsing materials
|
||||
*/
|
||||
public final class MaterialHelper {
|
||||
|
||||
private MaterialHelper() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the materials specified in the block whitelist
|
||||
*/
|
||||
public static @NotNull Set<Material> loadMaterialList(@NotNull List<?> materials) {
|
||||
Set<Material> parsedMaterials = new HashSet<>();
|
||||
for (Object value : materials) {
|
||||
if (!(value instanceof String string)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to parse a material tag first
|
||||
if (parseMaterialTag(parsedMaterials, string)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to parse a material name
|
||||
Material matched = Material.matchMaterial(string);
|
||||
if (matched != null) {
|
||||
parsedMaterials.add(matched);
|
||||
} else {
|
||||
Launchpad.log(Level.WARNING, "&cUnable to parse material: " + string);
|
||||
}
|
||||
}
|
||||
return parsedMaterials;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to parse the material tag in the specified material name
|
||||
*
|
||||
* @param targetSet <p>The set all parsed materials should be added to</p>
|
||||
* @param materialName <p>The material name that might be a material tag</p>
|
||||
* @return <p>True if a tag was found</p>
|
||||
*/
|
||||
private static boolean parseMaterialTag(@NotNull Set<Material> targetSet, @NotNull String materialName) {
|
||||
Pattern pattern = Pattern.compile("^\\+([a-zA-Z_]+)");
|
||||
Matcher matcher = pattern.matcher(materialName);
|
||||
if (matcher.find()) {
|
||||
// The material is a material tag
|
||||
Tag<Material> tag = Bukkit.getTag(Tag.REGISTRY_BLOCKS, NamespacedKey.minecraft(
|
||||
matcher.group(1).toLowerCase()), Material.class);
|
||||
if (tag != null) {
|
||||
targetSet.addAll(tag.getValues());
|
||||
} else {
|
||||
Launchpad.log(Level.WARNING, "Unable to parse: " + materialName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package net.knarcraft.launchpad.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A helper-class for common tab-completions
|
||||
*/
|
||||
public final class TabCompleteHelper {
|
||||
|
||||
private TabCompleteHelper() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds tab complete values that contain the typed text
|
||||
*
|
||||
* @param values <p>The values to filter</p>
|
||||
* @param typedText <p>The text the player has started typing</p>
|
||||
* @return <p>The given string values that contain the player's typed text</p>
|
||||
*/
|
||||
public static List<String> filterMatchingContains(@NotNull List<String> values, @NotNull String typedText) {
|
||||
List<String> configValues = new ArrayList<>();
|
||||
for (String value : values) {
|
||||
if (value.toLowerCase().contains(typedText.toLowerCase())) {
|
||||
configValues.add(value);
|
||||
}
|
||||
}
|
||||
return configValues;
|
||||
}
|
||||
|
||||
}
|
19
src/main/resources/config.yml
Normal file
19
src/main/resources/config.yml
Normal file
@ -0,0 +1,19 @@
|
||||
launchpad:
|
||||
# A list of all materials used as a launch-pad. Use +PRESSURE_PLATES for all pressure plates, or
|
||||
# +WOODEN_PRESSURE_PLATES for all wooden pressure plates.
|
||||
materials:
|
||||
- LIGHT_WEIGHTED_PRESSURE_PLATE # This is the gold pressure plate
|
||||
- HEAVY_WEIGHTED_PRESSURE_PLATE # This is the iron pressure plate
|
||||
# The default vertical (upwards) velocity set for a player
|
||||
verticalVelocity: 0.2
|
||||
# The default horizontal (outwards) velocity set for a player
|
||||
horizontalVelocity: 0.5
|
||||
# Default velocities for specific launchpad materials. You can use this to set up different velocities for each type
|
||||
# of pressure plate or other material.
|
||||
materialVelocities:
|
||||
LIGHT_WEIGHTED_PRESSURE_PLATE:
|
||||
verticalVelocity: 0.2
|
||||
horizontalVelocity: 0.5
|
||||
HEAVY_WEIGHTED_PRESSURE_PLATE:
|
||||
verticalVelocity: 0.3
|
||||
horizontalVelocity: 1
|
36
src/main/resources/plugin.yml
Normal file
36
src/main/resources/plugin.yml
Normal file
@ -0,0 +1,36 @@
|
||||
name: Launchpad
|
||||
version: '${project.version}'
|
||||
main: net.knarcraft.launchpad.Launchpad
|
||||
api-version: '1.20'
|
||||
author: EpicKnarvik97
|
||||
description: A plugin that adds customizable launchpads to the game
|
||||
website: https://git.knarcraft.net
|
||||
|
||||
commands:
|
||||
reload:
|
||||
usage: /<command>
|
||||
description: Used to reload the Launchpad plugin
|
||||
permission: launchpad.reload
|
||||
launchpad:
|
||||
usage: /<command> <add|remove|verticalVelocity|horizontalVelocity|fixedDirection> [value]
|
||||
description: Used to alter launchpads
|
||||
permission: launchpad.modify
|
||||
|
||||
permissions:
|
||||
launchpad.*:
|
||||
default: false
|
||||
description: Alias of launchpad.admin
|
||||
children:
|
||||
- launchpad.admin
|
||||
launchpad.admin:
|
||||
default: op
|
||||
description: Gives all permissions
|
||||
children:
|
||||
- launchpad.reload
|
||||
- launchpad.modify
|
||||
launchpad.reload:
|
||||
default: false
|
||||
description: Allows reloading Launchpad
|
||||
launchpad.modify:
|
||||
default: false
|
||||
description: Allows adding and modifying launchpads
|
Loading…
Reference in New Issue
Block a user