Add commands to set teleport and spawn locations from player position
New commands: - /lm setteleport <mine> - sets teleport location to current player position - /lm setspawn <mine> - sets safe spawn location for stuck players - /lm clearspawn <mine> - removes spawn location, falls back to teleport Features: - All commands use player's current location (X, Y, Z, yaw, pitch, world) - Auto-completion for mine names - Separate permissions: lomines.admin.setteleport, lomines.admin.setspawn - Permission lomines.admin includes all new permissions Updates: - AdminCommands.java - added three new command handlers - Mines.java - added getFileManager() getter - MineFileManager.java - added saveConfig() method - LoMinesTabCompleter.java - added tab completion for new commands - plugin.yml - added new permissions - MineEditGui.java - shows spawn status and command hints in teleport item Usage example: 1. Stand where you want players to teleport 2. Type: /lm setteleport mymine 3. Stand where stuck players should spawn 4. Type: /lm setspawn mymine
This commit is contained in:
parent
ed294bb78a
commit
cfaf638abf
6 changed files with 172 additions and 5 deletions
|
|
@ -3,6 +3,9 @@ package dev.loki.lomines.command;
|
||||||
import dev.loki.lomines.LoMinesPlugin;
|
import dev.loki.lomines.LoMinesPlugin;
|
||||||
import dev.loki.lomines.core.Mine;
|
import dev.loki.lomines.core.Mine;
|
||||||
import dev.loki.lomines.core.Mines;
|
import dev.loki.lomines.core.Mines;
|
||||||
|
import dev.loki.lomines.data.config.MineConfig;
|
||||||
|
import dev.loki.lomines.data.config.spawn.PlayerSpawnConfig;
|
||||||
|
import dev.loki.lomines.data.config.teleport.TeleportConfig;
|
||||||
import dev.loki.lomines.gui.MineEditGui;
|
import dev.loki.lomines.gui.MineEditGui;
|
||||||
import dev.loki.lomines.util.ErrorHandler;
|
import dev.loki.lomines.util.ErrorHandler;
|
||||||
import dev.loki.lomines.util.MessageFormatter;
|
import dev.loki.lomines.util.MessageFormatter;
|
||||||
|
|
@ -11,6 +14,7 @@ import dev.lolib.commands.annotation.Command;
|
||||||
import dev.lolib.commands.annotation.Subcommand;
|
import dev.lolib.commands.annotation.Subcommand;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
|
@ -152,6 +156,133 @@ public class AdminCommands {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the teleport location for players when mine resets.
|
||||||
|
* Usage: /lm setteleport <mine>
|
||||||
|
*/
|
||||||
|
@Subcommand(value = "setteleport", permission = "lomines.admin.setteleport")
|
||||||
|
public void setTeleport(CommandSender sender, @Arg("mine") String mineName) {
|
||||||
|
if (!(sender instanceof Player player)) {
|
||||||
|
sender.sendMessage(Component.text("This command can only be used by players!", NamedTextColor.RED));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Mine mine = mines.find(mineName).orElse(null);
|
||||||
|
if (mine == null) {
|
||||||
|
errorHandler.handleNotFound(sender, "Mine", mineName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current player location and update config
|
||||||
|
var config = mine.getConfig();
|
||||||
|
var newTeleport = TeleportConfig.at(player.getLocation());
|
||||||
|
|
||||||
|
var updatedConfig = MineConfig.builder(mineName)
|
||||||
|
.region(config.region())
|
||||||
|
.blocks(config.blocks())
|
||||||
|
.reset(config.reset())
|
||||||
|
.rewards(config.rewards())
|
||||||
|
.teleport(newTeleport)
|
||||||
|
.ui(config.ui())
|
||||||
|
.worldGuard(config.worldGuard())
|
||||||
|
.playerSpawn(config.playerSpawn())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
plugin.getMines().getFileManager().saveConfig(updatedConfig);
|
||||||
|
sender.sendMessage(MessageFormatter.success("Teleport location for mine '" + mineName + "' set to your current position"));
|
||||||
|
sender.sendMessage(Component.text("Location: " + formatLocation(player.getLocation()), NamedTextColor.GRAY));
|
||||||
|
} catch (Exception e) {
|
||||||
|
errorHandler.handleError(sender, "Failed to set teleport: " + e.getMessage(),
|
||||||
|
"Failed to set teleport for " + mineName, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the safe spawn location for stuck players after mine reset.
|
||||||
|
* Usage: /lm setspawn <mine>
|
||||||
|
*/
|
||||||
|
@Subcommand(value = "setspawn", permission = "lomines.admin.setspawn")
|
||||||
|
public void setSpawn(CommandSender sender, @Arg("mine") String mineName) {
|
||||||
|
if (!(sender instanceof Player player)) {
|
||||||
|
sender.sendMessage(Component.text("This command can only be used by players!", NamedTextColor.RED));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Mine mine = mines.find(mineName).orElse(null);
|
||||||
|
if (mine == null) {
|
||||||
|
errorHandler.handleNotFound(sender, "Mine", mineName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current player location and update config
|
||||||
|
var config = mine.getConfig();
|
||||||
|
var newSpawn = PlayerSpawnConfig.at(player.getLocation());
|
||||||
|
|
||||||
|
var updatedConfig = MineConfig.builder(mineName)
|
||||||
|
.region(config.region())
|
||||||
|
.blocks(config.blocks())
|
||||||
|
.reset(config.reset())
|
||||||
|
.rewards(config.rewards())
|
||||||
|
.teleport(config.teleport())
|
||||||
|
.ui(config.ui())
|
||||||
|
.worldGuard(config.worldGuard())
|
||||||
|
.playerSpawn(newSpawn)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
plugin.getMines().getFileManager().saveConfig(updatedConfig);
|
||||||
|
sender.sendMessage(MessageFormatter.success("Safe spawn location for mine '" + mineName + "' set to your current position"));
|
||||||
|
sender.sendMessage(Component.text("Location: " + formatLocation(player.getLocation()), NamedTextColor.GRAY));
|
||||||
|
sender.sendMessage(Component.text("Players stuck in blocks will be teleported here after reset", NamedTextColor.YELLOW));
|
||||||
|
} catch (Exception e) {
|
||||||
|
errorHandler.handleError(sender, "Failed to set spawn: " + e.getMessage(),
|
||||||
|
"Failed to set spawn for " + mineName, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the spawn location for stuck players.
|
||||||
|
* Usage: /lm clearspawn <mine>
|
||||||
|
*/
|
||||||
|
@Subcommand(value = "clearspawn", permission = "lomines.admin.setspawn")
|
||||||
|
public void clearSpawn(CommandSender sender, @Arg("mine") String mineName) {
|
||||||
|
try {
|
||||||
|
Mine mine = mines.find(mineName).orElse(null);
|
||||||
|
if (mine == null) {
|
||||||
|
errorHandler.handleNotFound(sender, "Mine", mineName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var config = mine.getConfig();
|
||||||
|
var updatedConfig = MineConfig.builder(mineName)
|
||||||
|
.region(config.region())
|
||||||
|
.blocks(config.blocks())
|
||||||
|
.reset(config.reset())
|
||||||
|
.rewards(config.rewards())
|
||||||
|
.teleport(config.teleport())
|
||||||
|
.ui(config.ui())
|
||||||
|
.worldGuard(config.worldGuard())
|
||||||
|
.playerSpawn(PlayerSpawnConfig.disabled())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
plugin.getMines().getFileManager().saveConfig(updatedConfig);
|
||||||
|
sender.sendMessage(MessageFormatter.success("Spawn location for mine '" + mineName + "' cleared"));
|
||||||
|
sender.sendMessage(Component.text("Players will use teleport location instead", NamedTextColor.GRAY));
|
||||||
|
} catch (Exception e) {
|
||||||
|
errorHandler.handleError(sender, "Failed to clear spawn: " + e.getMessage(),
|
||||||
|
"Failed to clear spawn for " + mineName, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats location for display.
|
||||||
|
*/
|
||||||
|
private String formatLocation(Location loc) {
|
||||||
|
return String.format("%.1f, %.1f, %.1f in %s",
|
||||||
|
loc.getX(), loc.getY(), loc.getZ(), loc.getWorld().getName());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats mine status information for display.
|
* Formats mine status information for display.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,8 @@ public class LoMinesTabCompleter implements TabCompleter {
|
||||||
|
|
||||||
// Static command lists for fast lookup
|
// Static command lists for fast lookup
|
||||||
private static final List<String> ADMIN_COMMANDS = List.of(
|
private static final List<String> ADMIN_COMMANDS = List.of(
|
||||||
"create", "delete", "reset", "reload", "list", "maskscan"
|
"create", "delete", "reset", "reload", "list", "maskscan",
|
||||||
|
"edit", "setteleport", "setspawn", "clearspawn"
|
||||||
);
|
);
|
||||||
|
|
||||||
private static final List<String> PLAYER_COMMANDS = List.of(
|
private static final List<String> PLAYER_COMMANDS = List.of(
|
||||||
|
|
@ -29,7 +30,8 @@ public class LoMinesTabCompleter implements TabCompleter {
|
||||||
|
|
||||||
private static final List<String> ALL_COMMANDS = List.of(
|
private static final List<String> ALL_COMMANDS = List.of(
|
||||||
"create", "delete", "reset", "reload", "list", "wand", "group",
|
"create", "delete", "reset", "reload", "list", "wand", "group",
|
||||||
"stats", "top", "maskscan", "help"
|
"stats", "top", "maskscan", "edit", "setteleport", "setspawn",
|
||||||
|
"clearspawn", "help"
|
||||||
);
|
);
|
||||||
|
|
||||||
public LoMinesTabCompleter(LoMinesPlugin plugin) {
|
public LoMinesTabCompleter(LoMinesPlugin plugin) {
|
||||||
|
|
@ -65,7 +67,7 @@ public class LoMinesTabCompleter implements TabCompleter {
|
||||||
String partial = args[1].toLowerCase();
|
String partial = args[1].toLowerCase();
|
||||||
|
|
||||||
switch (subcommand) {
|
switch (subcommand) {
|
||||||
case "delete", "reset", "maskscan" ->
|
case "delete", "reset", "maskscan", "edit", "setteleport", "setspawn", "clearspawn" ->
|
||||||
completions.addAll(getMineNames(partial));
|
completions.addAll(getMineNames(partial));
|
||||||
case "create" -> {
|
case "create" -> {
|
||||||
if (partial.isEmpty()) {
|
if (partial.isEmpty()) {
|
||||||
|
|
@ -106,8 +108,10 @@ public class LoMinesTabCompleter implements TabCompleter {
|
||||||
|
|
||||||
private boolean hasPermission(CommandSender sender, String command) {
|
private boolean hasPermission(CommandSender sender, String command) {
|
||||||
return switch (command) {
|
return switch (command) {
|
||||||
case "create", "delete", "reset", "reload", "list", "maskscan" ->
|
case "create", "delete", "reset", "reload", "list", "maskscan", "edit" ->
|
||||||
sender.hasPermission("lomines.admin");
|
sender.hasPermission("lomines.admin");
|
||||||
|
case "setteleport" -> sender.hasPermission("lomines.admin.setteleport");
|
||||||
|
case "setspawn", "clearspawn" -> sender.hasPermission("lomines.admin.setspawn");
|
||||||
case "wand", "group" -> sender.hasPermission("lomines.admin.wand");
|
case "wand", "group" -> sender.hasPermission("lomines.admin.wand");
|
||||||
case "stats" -> sender.hasPermission("lomines.stats");
|
case "stats" -> sender.hasPermission("lomines.stats");
|
||||||
case "top" -> sender.hasPermission("lomines.stats");
|
case "top" -> sender.hasPermission("lomines.stats");
|
||||||
|
|
|
||||||
|
|
@ -198,4 +198,11 @@ public final class Mines {
|
||||||
public WorldGuardRegionService getWorldGuardService() {
|
public WorldGuardRegionService getWorldGuardService() {
|
||||||
return worldGuardService;
|
return worldGuardService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the file manager for saving mine configurations.
|
||||||
|
*/
|
||||||
|
public MineFileManager getFileManager() {
|
||||||
|
return fileManager;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -134,6 +134,16 @@ public record MineFileManager(Path minesFolder, ConfigLoader configLoader) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a mine configuration to file.
|
||||||
|
*
|
||||||
|
* @param config the configuration to save
|
||||||
|
* @throws ConfigLoader.ConfigLoadException if saving fails
|
||||||
|
*/
|
||||||
|
public void saveConfig(MineConfig config) throws ConfigLoader.ConfigLoadException {
|
||||||
|
configLoader.save(config);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves mask positions for mask fill mode.
|
* Saves mask positions for mask fill mode.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -184,10 +184,17 @@ public final class MineEditGui {
|
||||||
if (meta != null) {
|
if (meta != null) {
|
||||||
meta.displayName(Component.text("§aТелепорт", NamedTextColor.GREEN));
|
meta.displayName(Component.text("§aТелепорт", NamedTextColor.GREEN));
|
||||||
boolean enabled = config.teleport().enabled();
|
boolean enabled = config.teleport().enabled();
|
||||||
|
boolean spawnEnabled = config.playerSpawn().enabled();
|
||||||
meta.lore(List.of(
|
meta.lore(List.of(
|
||||||
Component.text("Включено: " + (enabled ? "§aДа" : "§cНет"), NamedTextColor.GRAY),
|
Component.text("Включено: " + (enabled ? "§aДа" : "§cНет"), NamedTextColor.GRAY),
|
||||||
|
Component.text("Точка спавна (застрявших): " + (spawnEnabled ? "§aДа" : "§7Нет"), NamedTextColor.GRAY),
|
||||||
Component.empty(),
|
Component.empty(),
|
||||||
Component.text("§eНажмите для редактирования", NamedTextColor.YELLOW)
|
Component.text("§eНажмите для редактирования", NamedTextColor.YELLOW),
|
||||||
|
Component.empty(),
|
||||||
|
Component.text("§7Команды:", NamedTextColor.DARK_GRAY),
|
||||||
|
Component.text("§7/lm setteleport <mine>", NamedTextColor.GRAY),
|
||||||
|
Component.text("§7/lm setspawn <mine>", NamedTextColor.GRAY),
|
||||||
|
Component.text("§7/lm clearspawn <mine>", NamedTextColor.GRAY)
|
||||||
));
|
));
|
||||||
stack.setItemMeta(meta);
|
stack.setItemMeta(meta);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ permissions:
|
||||||
lomines.admin.wand: true
|
lomines.admin.wand: true
|
||||||
lomines.admin.maskscan: true
|
lomines.admin.maskscan: true
|
||||||
lomines.admin.edit: true
|
lomines.admin.edit: true
|
||||||
|
lomines.admin.setteleport: true
|
||||||
|
lomines.admin.setspawn: true
|
||||||
lomines.stats:
|
lomines.stats:
|
||||||
description: View mining stats and leaderboards (/lm stats, /lm top)
|
description: View mining stats and leaderboards (/lm stats, /lm top)
|
||||||
default: true
|
default: true
|
||||||
|
|
@ -46,3 +48,9 @@ permissions:
|
||||||
lomines.use:
|
lomines.use:
|
||||||
description: Basic LoMines usage
|
description: Basic LoMines usage
|
||||||
default: true
|
default: true
|
||||||
|
lomines.admin.setteleport:
|
||||||
|
description: Set teleport location for mine reset (/lm setteleport <mine>)
|
||||||
|
default: op
|
||||||
|
lomines.admin.setspawn:
|
||||||
|
description: Set safe spawn location for stuck players (/lm setspawn <mine>, /lm clearspawn <mine>)
|
||||||
|
default: op
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue