Added random plot command by Jakob Stranz
This commit is contained in:
parent
18de5cebd6
commit
eb7bd6cc95
|
|
@ -47,4 +47,8 @@ dependencies {
|
||||||
|
|
||||||
compileOnly("org.projectlombok:lombok:1.18.38")
|
compileOnly("org.projectlombok:lombok:1.18.38")
|
||||||
annotationProcessor("org.projectlombok:lombok:1.18.38")
|
annotationProcessor("org.projectlombok:lombok:1.18.38")
|
||||||
|
|
||||||
|
implementation(platform("com.intellectualsites.bom:bom-newest:1.56"))
|
||||||
|
compileOnly("com.intellectualsites.plotsquared:plotsquared-core")
|
||||||
|
compileOnly("com.intellectualsites.plotsquared:plotsquared-bukkit") { isTransitive = false }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,9 @@ dependencyResolutionManagement {
|
||||||
password = nexusPass
|
password = nexusPass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
maven("https://repo.destro.xyz/snapshots")
|
|
||||||
maven("https://jitpack.io")
|
maven("https://jitpack.io")
|
||||||
|
// PlotSquared
|
||||||
|
maven("https://repo.papermc.io/repository/maven-public/")
|
||||||
}
|
}
|
||||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,29 +2,42 @@ package com.alttd.playerutils;
|
||||||
|
|
||||||
import com.alttd.playerutils.commands.PlayerUtilsCommand;
|
import com.alttd.playerutils.commands.PlayerUtilsCommand;
|
||||||
import com.alttd.playerutils.commands.playerutils_subcommands.GhastSpeed;
|
import com.alttd.playerutils.commands.playerutils_subcommands.GhastSpeed;
|
||||||
|
import com.alttd.playerutils.commands.playerutils_subcommands.RandomPlot;
|
||||||
import com.alttd.playerutils.commands.playerutils_subcommands.RotateBlock;
|
import com.alttd.playerutils.commands.playerutils_subcommands.RotateBlock;
|
||||||
import com.alttd.playerutils.config.Config;
|
import com.alttd.playerutils.config.Config;
|
||||||
import com.alttd.playerutils.config.KeyStorage;
|
import com.alttd.playerutils.config.KeyStorage;
|
||||||
import com.alttd.playerutils.config.Messages;
|
import com.alttd.playerutils.config.Messages;
|
||||||
import com.alttd.playerutils.event_listeners.*;
|
import com.alttd.playerutils.event_listeners.*;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.PluginManager;
|
import org.bukkit.plugin.PluginManager;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
public final class PlayerUtils extends JavaPlugin {
|
public final class PlayerUtils extends JavaPlugin {
|
||||||
|
|
||||||
private PlayerUtilsCommand playerUtilsCommand;
|
private PlayerUtilsCommand playerUtilsCommand;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
registerCommands();
|
|
||||||
registerEvents();
|
|
||||||
reloadConfigs();
|
reloadConfigs();
|
||||||
|
registerCommands();
|
||||||
|
registerRandomPlot();
|
||||||
|
registerEvents();
|
||||||
registerSchedulers();
|
registerSchedulers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void registerRandomPlot() {
|
||||||
|
if (!getServer().getPluginManager().isPluginEnabled("PlotSquared")) {
|
||||||
|
log.warn("PlotSquared not found — random plot command will not be registered.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
playerUtilsCommand.addSubCommand(new RandomPlot(this));
|
||||||
|
log.info("PlotSquared found - registered random plot command.");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
KeyStorage.STORAGE.save();
|
KeyStorage.STORAGE.save();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,181 @@
|
||||||
|
package com.alttd.playerutils.commands.playerutils_subcommands;
|
||||||
|
|
||||||
|
import com.alttd.playerutils.PlayerUtils;
|
||||||
|
import com.alttd.playerutils.commands.SubCommand;
|
||||||
|
import com.alttd.playerutils.config.Config;
|
||||||
|
import com.alttd.playerutils.config.Messages;
|
||||||
|
import com.plotsquared.bukkit.player.BukkitPlayer;
|
||||||
|
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||||
|
import com.plotsquared.core.PlotSquared;
|
||||||
|
import com.plotsquared.core.events.TeleportCause;
|
||||||
|
import com.plotsquared.core.plot.Plot;
|
||||||
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
|
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||||
|
import net.kyori.adventure.title.Title;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class RandomPlot extends SubCommand {
|
||||||
|
private static final String PERMISSION = "playerutils.randomplot";
|
||||||
|
private final PlayerUtils plugin;
|
||||||
|
private final MiniMessage miniMessage = MiniMessage.miniMessage();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(CommandSender commandSender, String[] args) {
|
||||||
|
if (!(commandSender instanceof Player player)) {
|
||||||
|
commandSender.sendRichMessage(Messages.GENERIC.PLAYER_ONLY);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String worldName = player.getWorld().getName();
|
||||||
|
if (!Config.RANDOM_PLOT.ALLOWED_WORLDS.contains(worldName)) {
|
||||||
|
player.sendRichMessage(Messages.RANDOM_PLOT.WORLD_NOT_ALLOWED);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!player.hasPermission(PERMISSION)) {
|
||||||
|
player.sendRichMessage(Messages.GENERIC.NO_PERMISSION, Placeholder.parsed("permission", PERMISSION));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Bukkit.getPluginManager().isPluginEnabled("PlotSquared")) {
|
||||||
|
player.sendRichMessage(Messages.RANDOM_PLOT.PLOT_SQUARED_NOT_ENABLED);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Plot> plots = collectPlots(worldName);
|
||||||
|
if (plots.isEmpty()) {
|
||||||
|
player.sendRichMessage(Messages.RANDOM_PLOT.NO_PLOTS_FOUND);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Plot target = plots.get(ThreadLocalRandom.current().nextInt(plots.size()));
|
||||||
|
player.sendRichMessage(Messages.RANDOM_PLOT.TELEPORT_START);
|
||||||
|
startCountdown(player, target);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── PlotSquared helpers ───────────────────────────────────────────────────
|
||||||
|
|
||||||
|
private List<Plot> collectPlots(String worldName) {
|
||||||
|
try {
|
||||||
|
return PlotSquared.get().getPlotAreaManager().getPlotAreasSet(worldName)
|
||||||
|
.stream()
|
||||||
|
.map(PlotArea::getPlots)
|
||||||
|
.flatMap(Collection::stream)
|
||||||
|
.toList();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to retrieve plots from PlotSquared for world '{}'", worldName, e);
|
||||||
|
}
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void teleportToPlot(Player player, Plot plot) {
|
||||||
|
try {
|
||||||
|
BukkitPlayer bPlayer = BukkitUtil.adapt(player);
|
||||||
|
plot.teleportPlayer(bPlayer, TeleportCause.PLUGIN, success -> {
|
||||||
|
if (Boolean.TRUE.equals(success)) {
|
||||||
|
player.sendRichMessage(Messages.RANDOM_PLOT.TELEPORT_SUCCESS,
|
||||||
|
Placeholder.parsed("plot_id", plot.getId().toSeparatedString(";")),
|
||||||
|
Placeholder.parsed("plot_owner", getOwner(plot)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to teleport {} to plot {}", player.getName(), plot.getId(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getOwner(Plot plot) {
|
||||||
|
String ownerName;
|
||||||
|
UUID owner = plot.getOwner();
|
||||||
|
if (owner == null) {
|
||||||
|
ownerName = "Unknown";
|
||||||
|
} else {
|
||||||
|
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(owner);
|
||||||
|
ownerName = offlinePlayer.getName();
|
||||||
|
if (ownerName == null) {
|
||||||
|
ownerName = "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ownerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Countdown ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
private void startCountdown(Player player, Plot plot) {
|
||||||
|
final Location origin = player.getLocation().clone();
|
||||||
|
final int[] secondsLeft = {Config.RANDOM_PLOT.COUNTDOWN_SECONDS};
|
||||||
|
|
||||||
|
new BukkitRunnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (!player.isOnline()) {
|
||||||
|
cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Movement check — cancel if player moved more than 0.5 blocks on any axis
|
||||||
|
Location current = player.getLocation();
|
||||||
|
if (Math.abs(current.getX() - origin.getX()) > 0.5
|
||||||
|
|| Math.abs(current.getY() - origin.getY()) > 0.5
|
||||||
|
|| Math.abs(current.getZ() - origin.getZ()) > 0.5) {
|
||||||
|
cancel();
|
||||||
|
player.sendRichMessage(Messages.RANDOM_PLOT.TELEPORT_CANCELLED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (secondsLeft[0] <= 0) {
|
||||||
|
cancel();
|
||||||
|
teleportToPlot(player, plot);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show countdown title for current second
|
||||||
|
String rawTitle = Config.RANDOM_PLOT.COUNTDOWN_TITLES
|
||||||
|
.getOrDefault(secondsLeft[0], String.valueOf(secondsLeft[0]));
|
||||||
|
Component title = miniMessage.deserialize(rawTitle);
|
||||||
|
Component subtitle = miniMessage.deserialize(Config.RANDOM_PLOT.COUNTDOWN_SUBTITLE);
|
||||||
|
|
||||||
|
player.showTitle(Title.title(
|
||||||
|
title,
|
||||||
|
subtitle,
|
||||||
|
Title.Times.times(Duration.ZERO, Duration.ofMillis(1200), Duration.ofMillis(200))
|
||||||
|
));
|
||||||
|
|
||||||
|
secondsLeft[0]--;
|
||||||
|
}
|
||||||
|
}.runTaskTimer(plugin, 0L, 20L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "randomplot";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getTabComplete(CommandSender commandSender, String[] args) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getHelpMessage() {
|
||||||
|
return Messages.HELP.RANDOM_PLOT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,18 +5,20 @@ import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@Slf4j public class Config extends AbstractConfig{
|
@Slf4j
|
||||||
|
public class Config extends AbstractConfig {
|
||||||
|
|
||||||
static Config config;
|
static Config config;
|
||||||
|
|
||||||
Config() {
|
Config() {
|
||||||
super(
|
super(
|
||||||
new File(File.separator
|
new File(File.separator
|
||||||
+ "mnt" + File.separator
|
+ "mnt" + File.separator
|
||||||
+ "configs" + File.separator
|
+ "configs" + File.separator
|
||||||
+ "PlayerUtils"),
|
+ "PlayerUtils"),
|
||||||
"config.yml");
|
"config.yml");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,4 +94,46 @@ import java.util.Set;
|
||||||
WAYPOINT_TRANSMIT_RANGE = config.getDouble(prefix, "waypoint_transmit_range", WAYPOINT_TRANSMIT_RANGE);
|
WAYPOINT_TRANSMIT_RANGE = config.getDouble(prefix, "waypoint_transmit_range", WAYPOINT_TRANSMIT_RANGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class RANDOM_PLOT {
|
||||||
|
private static final String prefix = "random-plot.";
|
||||||
|
|
||||||
|
// Command
|
||||||
|
public static List<String> ALLOWED_WORLDS = List.of("plotworld");
|
||||||
|
|
||||||
|
// Permissions
|
||||||
|
public static int COUNTDOWN_SECONDS = 3;
|
||||||
|
public static HashMap<Integer, String> COUNTDOWN_TITLES = new HashMap<>();
|
||||||
|
public static String COUNTDOWN_SUBTITLE = "<dark_grey>Preparing teleportation</dark_grey>";
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static void load() {
|
||||||
|
ALLOWED_WORLDS = config.getStringList(prefix, "allowed-worlds", ALLOWED_WORLDS);
|
||||||
|
|
||||||
|
COUNTDOWN_SECONDS = config.getInt(prefix + "countdown.", "seconds", COUNTDOWN_SECONDS);
|
||||||
|
COUNTDOWN_SUBTITLE = config.getString(prefix + "countdown.", "subtitle", COUNTDOWN_SUBTITLE);
|
||||||
|
|
||||||
|
// Countdown titles — integer keys map to display strings
|
||||||
|
COUNTDOWN_TITLES.clear();
|
||||||
|
ConfigurationSection titlesSection =
|
||||||
|
config.getConfigurationSection("random-plot.countdown.titles");
|
||||||
|
if (titlesSection != null) {
|
||||||
|
for (String key : titlesSection.getKeys(false)) {
|
||||||
|
try {
|
||||||
|
COUNTDOWN_TITLES.put(Integer.parseInt(key),
|
||||||
|
titlesSection.getString(key, key));
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
log.warn("Invalid countdown title key: {}", key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
config.yaml.addDefault("random-plot.countdown.titles.3", "<color:#08FBFF>Go!");
|
||||||
|
config.yaml.addDefault("random-plot.countdown.titles.2", "<color:#08FBFF>2");
|
||||||
|
config.yaml.addDefault("random-plot.countdown.titles.1", "<color:#08FBFF>1");
|
||||||
|
COUNTDOWN_TITLES.put(3, "<color:#08FBFF>2");
|
||||||
|
COUNTDOWN_TITLES.put(2, "<color:#08FBFF>1");
|
||||||
|
COUNTDOWN_TITLES.put(1, "<color:#08FBFF>Go!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
package com.alttd.playerutils.config;
|
package com.alttd.playerutils.config;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
@ -35,6 +33,7 @@ public class Messages extends AbstractConfig {
|
||||||
public static String KEY = "<green>Receive a key that you are owed: <gold>/pu key</gold></green>";
|
public static String KEY = "<green>Receive a key that you are owed: <gold>/pu key</gold></green>";
|
||||||
public static String GHAST_SPEED = "<green>Set the speed of a ghast: <gold>/pu ghastspeed <speed></gold></green>";
|
public static String GHAST_SPEED = "<green>Set the speed of a ghast: <gold>/pu ghastspeed <speed></gold></green>";
|
||||||
public static String RECOUNT_ARMOR_STANDS = "<green>Recount armor stands in current chunk: <gold>/pu recount</gold></green>";
|
public static String RECOUNT_ARMOR_STANDS = "<green>Recount armor stands in current chunk: <gold>/pu recount</gold></green>";
|
||||||
|
public static String RANDOM_PLOT = "<green>Get a random plot: <gold>/pu randomplot</gold></green>";
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private static void load() {
|
private static void load() {
|
||||||
|
|
@ -197,4 +196,25 @@ public class Messages extends AbstractConfig {
|
||||||
SUCCESS = config.getString(prefix, "success", SUCCESS);
|
SUCCESS = config.getString(prefix, "success", SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class RANDOM_PLOT {
|
||||||
|
private static final String prefix = "random-plot.";
|
||||||
|
|
||||||
|
public static String WORLD_NOT_ALLOWED = "<red>You must be in an allowed world to use this command.</red>";
|
||||||
|
public static String PLOT_SQUARED_NOT_ENABLED = "<red>PlotSquared is not available on this server.</red>";
|
||||||
|
public static String TELEPORT_START = "<green>Starting teleport countdown...</green>";
|
||||||
|
public static String TELEPORT_SUCCESS = "<gold>You have arrived at <plot_id> by <plot_owner> random plot!</gold>";
|
||||||
|
public static String TELEPORT_CANCELLED = "<red>Teleport cancelled! You moved.</red>";
|
||||||
|
public static String NO_PLOTS_FOUND = "<red>No plots found in this world.</red>";
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static void load() {
|
||||||
|
WORLD_NOT_ALLOWED = config.getString(prefix, "world-not-allowed", WORLD_NOT_ALLOWED);
|
||||||
|
PLOT_SQUARED_NOT_ENABLED = config.getString(prefix, "plotsquared-not-enabled", PLOT_SQUARED_NOT_ENABLED);
|
||||||
|
TELEPORT_START = config.getString(prefix, "teleport-start", TELEPORT_START);
|
||||||
|
TELEPORT_SUCCESS = config.getString(prefix, "teleport-success", TELEPORT_SUCCESS);
|
||||||
|
TELEPORT_CANCELLED = config.getString(prefix, "teleport-cancelled", TELEPORT_CANCELLED);
|
||||||
|
NO_PLOTS_FOUND = config.getString(prefix, "no-plots-found", NO_PLOTS_FOUND);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user