diff --git a/src/main/java/me/azenet/UHPlugin/UHBorderManager.java b/src/main/java/me/azenet/UHPlugin/UHBorderManager.java new file mode 100644 index 0000000..1731a19 --- /dev/null +++ b/src/main/java/me/azenet/UHPlugin/UHBorderManager.java @@ -0,0 +1,169 @@ +package me.azenet.UHPlugin; + +import java.util.HashSet; + +import me.azenet.UHPlugin.task.BorderWarningTask; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +public class UHBorderManager { + + private UHPlugin p = null; + private Integer currentBorderDiameter = null; + + private Integer warningSize = 0; + private BukkitRunnable warningTask = null; + + public UHBorderManager(UHPlugin p) { + this.p = p; + this.currentBorderDiameter = p.getConfig().getInt("map.size"); + } + + public boolean isInsideBorder(Location location, int diameter) { + if(!location.getWorld().equals(Bukkit.getWorlds().get(0))) { // The nether is not limited. + return true; + } + + Integer halfMapSize = (int) Math.floor(diameter/2); + Integer x = location.getBlockX(); + Integer z = location.getBlockZ(); + + Location spawn = Bukkit.getWorlds().get(0).getSpawnLocation(); + Integer limitXInf = spawn.add(-halfMapSize, 0, 0).getBlockX(); + + spawn = Bukkit.getWorlds().get(0).getSpawnLocation(); + Integer limitXSup = spawn.add(halfMapSize, 0, 0).getBlockX(); + + spawn = Bukkit.getWorlds().get(0).getSpawnLocation(); + Integer limitZInf = spawn.add(0, 0, -halfMapSize).getBlockZ(); + + spawn = Bukkit.getWorlds().get(0).getSpawnLocation(); + Integer limitZSup = spawn.add(0, 0, halfMapSize).getBlockZ(); + + if (x < limitXInf || x > limitXSup || z < limitZInf || z > limitZSup) { + return false; + } + else { + return true; + } + } + + public boolean isInsideBorder(Location location) { + return this.isInsideBorder(location, getCurrentBorderDiameter()); + } + + /** + * Return the distance from the location to the border, if the location is outside this border. + * If it is inside, returns 0. + * + * @param location + * @param diameter + * @return + */ + public int getDistanceToBorder(Location location, int diameter) { + if(!location.getWorld().equals(Bukkit.getWorlds().get(0))) { // The nether is not limited. + return 0; + } + if(isInsideBorder(location, diameter)) { + return 0; + } + + Integer halfMapSize = (int) Math.floor(diameter/2); + Integer x = location.getBlockX(); + Integer z = location.getBlockZ(); + + Location spawn = Bukkit.getWorlds().get(0).getSpawnLocation(); + Integer limitXInf = spawn.add(-halfMapSize, 0, 0).getBlockX(); + + spawn = Bukkit.getWorlds().get(0).getSpawnLocation(); + Integer limitXSup = spawn.add(halfMapSize, 0, 0).getBlockX(); + + spawn = Bukkit.getWorlds().get(0).getSpawnLocation(); + Integer limitZInf = spawn.add(0, 0, -halfMapSize).getBlockZ(); + + spawn = Bukkit.getWorlds().get(0).getSpawnLocation(); + Integer limitZSup = spawn.add(0, 0, halfMapSize).getBlockZ(); + + if((x > limitXSup || x < limitXInf) && z < limitZSup && z > limitZInf) { // east or west of the border + return Math.abs(x - limitXSup); + } + else if((z > limitZSup || z < limitZInf) && x < limitXSup && x > limitXInf) { // north or south of the border + return Math.abs(z - limitZSup); + } + else if(x > limitXSup && z < limitZInf) { // N-E + return (int) location.distance(new Location(location.getWorld(), limitXSup, location.getBlockY(), limitZInf)); + } + else if(x > limitXSup && z > limitZSup) { // S-E + return (int) location.distance(new Location(location.getWorld(), limitXSup, location.getBlockY(), limitZSup)); + } + else if(x < limitXInf && z > limitZSup) { // S-O + return (int) location.distance(new Location(location.getWorld(), limitXInf, location.getBlockY(), limitZSup)); + } + else if(x < limitXInf && z < limitZInf) { // N-O + return (int) location.distance(new Location(location.getWorld(), limitXInf, location.getBlockY(), limitZInf)); + } + else { + return 0; // Should never happen. + } + } + + + + public HashSet getPlayersOutside(int diameter) { + HashSet playersOutside = new HashSet(); + + for(final String playerS : p.getGameManager().getAlivePlayers()) { + Player player = Bukkit.getPlayer(playerS); + if(player == null) { // offline + continue; + } + if(!isInsideBorder(player.getLocation(), diameter)) { + playersOutside.add(player); + } + } + + return playersOutside; + } + + public HashSet getPlayersOutside() { + return this.getPlayersOutside(getCurrentBorderDiameter()); + } + + public int getWarningSize() { + return this.warningSize; + } + + public void setWarningSize(int diameter) { + cancelWarning(); + + this.warningSize = diameter; + + warningTask = new BorderWarningTask(p); + warningTask.runTaskTimer(p, 20L, 20L * p.getConfig().getInt("map.border.warningInterval", 90)); + } + + public void cancelWarning() { + if(warningTask != null) { + try { + warningTask.cancel(); + } catch(IllegalStateException e) { + + } + } + } + + public int getCurrentBorderDiameter() { + return this.currentBorderDiameter; + } + + public void setCurrentBorderDiameter(int diameter) { + cancelWarning(); + this.currentBorderDiameter = diameter; + + p.getWorldBorderIntegration().setupBorders(); // Update the WB border if needed + } + +} diff --git a/src/main/java/me/azenet/UHPlugin/UHGameManager.java b/src/main/java/me/azenet/UHPlugin/UHGameManager.java index 96a22fc..bf872fe 100644 --- a/src/main/java/me/azenet/UHPlugin/UHGameManager.java +++ b/src/main/java/me/azenet/UHPlugin/UHGameManager.java @@ -577,6 +577,10 @@ private ArrayList getAliveTeams() { } return aliveTeams; } + + public HashSet getAlivePlayers() { + return this.alivePlayers; + } public UHScoreboardManager getScoreboardManager() { return scoreboardManager; diff --git a/src/main/java/me/azenet/UHPlugin/UHPlugin.java b/src/main/java/me/azenet/UHPlugin/UHPlugin.java index 5834620..5720277 100644 --- a/src/main/java/me/azenet/UHPlugin/UHPlugin.java +++ b/src/main/java/me/azenet/UHPlugin/UHPlugin.java @@ -29,6 +29,7 @@ public final class UHPlugin extends JavaPlugin { private UHTeamManager teamManager = null; private UHGameManager gameManager = null; private UHPluginCommand commandManager = null; + private UHBorderManager borderManager = null; private UHWorldBorderIntegration wbintegration = null; private UHSpectatorPlusIntegration spintegration = null; @@ -51,6 +52,7 @@ public void onEnable() { teamManager = new UHTeamManager(this); gameManager = new UHGameManager(this); + borderManager = new UHBorderManager(this); wbintegration = new UHWorldBorderIntegration(this); spintegration = new UHSpectatorPlusIntegration(this); @@ -219,6 +221,10 @@ public UHPluginCommand getCommandManager() { return commandManager; } + public UHBorderManager getBorderManager() { + return borderManager; + } + public UHWorldBorderIntegration getWorldBorderIntegration() { return wbintegration; } diff --git a/src/main/java/me/azenet/UHPlugin/UHPluginCommand.java b/src/main/java/me/azenet/UHPlugin/UHPluginCommand.java index e8961c7..25d8092 100644 --- a/src/main/java/me/azenet/UHPlugin/UHPluginCommand.java +++ b/src/main/java/me/azenet/UHPlugin/UHPluginCommand.java @@ -20,15 +20,10 @@ public class UHPluginCommand implements CommandExecutor { private UHPlugin p = null; - private ChatColor ce = ChatColor.RED; // error - private ChatColor ci = ChatColor.WHITE; // info - private ChatColor cc = ChatColor.GOLD; // command - private ChatColor cs = ChatColor.GREEN; // success message - private ChatColor cst = ChatColor.GRAY; // status - private ArrayList commands = new ArrayList(); private ArrayList teamCommands = new ArrayList(); private ArrayList specCommands = new ArrayList(); + private ArrayList borderCommands = new ArrayList(); private I18n i = null; @@ -42,6 +37,7 @@ public UHPluginCommand(UHPlugin p) { commands.add("team"); commands.add("addspawn"); commands.add("generatewalls"); + commands.add("border"); commands.add("heal"); commands.add("healall"); commands.add("resurrect"); @@ -58,6 +54,11 @@ public UHPluginCommand(UHPlugin p) { specCommands.add("add"); specCommands.add("remove"); specCommands.add("list"); + + borderCommands.add("current"); + borderCommands.add("set"); + borderCommands.add("warning"); + borderCommands.add("check"); } @SuppressWarnings("rawtypes") @@ -134,6 +135,7 @@ private void help(CommandSender sender, boolean error) { sender.sendMessage(i.t("cmd.helpAddspawnXZ")); sender.sendMessage(i.t("cmd.helpSpec")); sender.sendMessage(i.t("cmd.helpWall")); + sender.sendMessage(i.t("cmd.helpBorder")); sender.sendMessage(i.t("cmd.titleBugCmd")); sender.sendMessage(i.t("cmd.helpHeal")); @@ -710,6 +712,125 @@ else if(subcommand.equalsIgnoreCase("list")) { } + /** + * This command manages borders (gets current, checks if players are out, sets a new size, warnings players + * about the futur size). + * + * @param sender + * @param command + * @param label + * @param args + */ + @SuppressWarnings("unused") + private void doBorder(CommandSender sender, Command command, String label, String[] args) { + if(args.length == 1) { // /uh border + sender.sendMessage(i.t("cmd.borderHelpAvailable")); + sender.sendMessage(i.t("cmd.borderHelpCurrent")); + sender.sendMessage(i.t("cmd.borderHelpSet")); + sender.sendMessage(i.t("cmd.borderHelpWarning")); + sender.sendMessage(i.t("cmd.borderHelpWarningCancel")); + sender.sendMessage(i.t("cmd.borderHelpCheck")); + } + else { + String subcommand = args[1]; + + if(subcommand.equalsIgnoreCase("current")) { // /uh border current + sender.sendMessage(i.t("borders.current.message", String.valueOf(p.getBorderManager().getCurrentBorderDiameter()))); + } + + else if(subcommand.equalsIgnoreCase("set")) { // /uh border set + if(args.length == 2) { // /uh border set + sender.sendMessage(i.t("borders.syntaxError")); + } + else if(args.length == 3) { // /uh border set + try { + Integer newDiameter = Integer.valueOf(args[2]); + + if(p.getBorderManager().getPlayersOutside(newDiameter).size() != 0) { // Some players are outside + sender.sendMessage(i.t("borders.set.playersOutsideCanceled")); + sender.sendMessage(i.t("borders.set.playersOutsideCanceledCmd", args[2])); + if(!p.getWorldBorderIntegration().isWBIntegrationEnabled()) { + sender.sendMessage(i.t("borders.set.playersOutsideCanceledWarnWorldBorder")); + } + } + else { + p.getBorderManager().setCurrentBorderDiameter(newDiameter); + p.getServer().broadcastMessage(i.t("borders.set.broadcast", args[2])); + } + + } catch(NumberFormatException e) { + sender.sendMessage(i.t("borders.NaN", args[2])); + } + } + else if(args.length == 4 && args[3].equalsIgnoreCase("force")) { // /uh border set force + try { + Integer newDiameter = Integer.valueOf(args[2]); + + p.getBorderManager().setCurrentBorderDiameter(newDiameter); + p.getServer().broadcastMessage(i.t("borders.set.broadcast", args[2])); + + } catch(NumberFormatException e) { + sender.sendMessage(i.t("borders.NaN", args[2])); + } + } + } + + else if(subcommand.equalsIgnoreCase("warning")) { // /uh border warning + if(args.length == 2) { // /uh border warning + sender.sendMessage(i.t("borders.syntaxError")); + } + else if(args[2].equalsIgnoreCase("cancel")) { // /uh border warning cancel + p.getBorderManager().cancelWarning(); + sender.sendMessage(i.t("borders.warning.canceled")); + } + else { // /uh border warning + try { + Integer warnDiameter = Integer.valueOf(args[2]); + p.getBorderManager().setWarningSize(warnDiameter); + sender.sendMessage(i.t("borders.warning.set", p.getConfig().getString("map.border.warningInterval", "90"))); + + } catch(NumberFormatException e) { + sender.sendMessage(i.t("borders.NaN", args[2])); + } + } + } + else if(subcommand.equalsIgnoreCase("check")) { + if(args.length == 2) { // /uh border check + sender.sendMessage(i.t("borders.syntaxError")); + } + else { // /uh border check + try { + Integer checkDiameter = Integer.valueOf(args[2]); + HashSet playersOutside = p.getBorderManager().getPlayersOutside(checkDiameter); + + if(playersOutside.size() == 0) { + sender.sendMessage(i.t("borders.check.allPlayersInside")); + } + else { + sender.sendMessage(i.t("borders.check.countPlayersOutside", String.valueOf(playersOutside.size()))); + for(Player player : p.getBorderManager().getPlayersOutside(checkDiameter)) { + int distance = p.getBorderManager().getDistanceToBorder(player.getLocation(), checkDiameter); + if(distance > 150) { + sender.sendMessage(i.t("borders.check.itemPlayerFar", player.getName())); + } + else if(distance > 25) { + sender.sendMessage(i.t("borders.check.itemPlayerClose", player.getName())); + } + else { + sender.sendMessage(i.t("borders.check.itemPlayerVeryClose", player.getName())); + } + } + } + + } catch(NumberFormatException e) { + sender.sendMessage(i.t("borders.NaN", args[2])); + } + } + } + } + + } + public ArrayList getCommands() { @@ -723,4 +844,8 @@ public ArrayList getTeamCommands() { public ArrayList getSpecCommands() { return specCommands; } + + public ArrayList getBorderCommands() { + return borderCommands; + } } diff --git a/src/main/java/me/azenet/UHPlugin/UHPluginListener.java b/src/main/java/me/azenet/UHPlugin/UHPluginListener.java index 5066d4a..295ac4c 100644 --- a/src/main/java/me/azenet/UHPlugin/UHPluginListener.java +++ b/src/main/java/me/azenet/UHPlugin/UHPluginListener.java @@ -284,25 +284,7 @@ public void onPlayerMove(PlayerMoveEvent ev) { } if(!p.getWorldBorderIntegration().isWBIntegrationEnabled()) { - Location l = ev.getTo(); - Integer mapSize = p.getConfig().getInt("map.size"); - Integer halfMapSize = (int) Math.floor(mapSize/2); - Integer x = l.getBlockX(); - Integer z = l.getBlockZ(); - - Location spawn = ev.getPlayer().getWorld().getSpawnLocation(); - Integer limitXInf = spawn.add(-halfMapSize, 0, 0).getBlockX(); - - spawn = ev.getPlayer().getWorld().getSpawnLocation(); - Integer limitXSup = spawn.add(halfMapSize, 0, 0).getBlockX(); - - spawn = ev.getPlayer().getWorld().getSpawnLocation(); - Integer limitZInf = spawn.add(0, 0, -halfMapSize).getBlockZ(); - - spawn = ev.getPlayer().getWorld().getSpawnLocation(); - Integer limitZSup = spawn.add(0, 0, halfMapSize).getBlockZ(); - - if (x < limitXInf || x > limitXSup || z < limitZInf || z > limitZSup) { + if(!p.getBorderManager().isInsideBorder(ev.getTo())) { ev.setCancelled(true); } } diff --git a/src/main/java/me/azenet/UHPlugin/UHTabCompleter.java b/src/main/java/me/azenet/UHPlugin/UHTabCompleter.java index d324db0..e6fd0f0 100644 --- a/src/main/java/me/azenet/UHPlugin/UHTabCompleter.java +++ b/src/main/java/me/azenet/UHPlugin/UHTabCompleter.java @@ -14,6 +14,7 @@ public class UHTabCompleter implements TabCompleter { private ArrayList commands = null; private ArrayList teamCommands = null; private ArrayList specCommands = null; + private ArrayList borderCommands = null; private ArrayList colors = new ArrayList(); @@ -24,6 +25,7 @@ public UHTabCompleter(UHPlugin plugin) { this.commands = p.getCommandManager().getCommands(); this.teamCommands = p.getCommandManager().getTeamCommands(); this.specCommands = p.getCommandManager().getSpecCommands(); + this.borderCommands = p.getCommandManager().getBorderCommands(); this.colors.add("aqua"); this.colors.add("black"); @@ -124,6 +126,28 @@ else if(args[0].equalsIgnoreCase("tpback")) { } } + /** Autocompletion for /uh border **/ + else if(args[0].equalsIgnoreCase("border")) { + + // /uh border + if(args.length == 2) { + return getAutocompleteSuggestions(args[1].toLowerCase(), this.borderCommands); + } + + else if(args[1].equalsIgnoreCase("warning") && args.length == 3) { // /uh border warning + ArrayList commandSuggested = new ArrayList(); + commandSuggested.add("cancel"); + return this.getAutocompleteSuggestions(args[2].toLowerCase(), commandSuggested); + } + + else if(args[1].equalsIgnoreCase("set") && args.length == 4) { // /uh border set + ArrayList commandSuggested = new ArrayList(); + commandSuggested.add("force"); + return this.getAutocompleteSuggestions(args[3].toLowerCase(), commandSuggested); + } + + } + return null; } diff --git a/src/main/java/me/azenet/UHPlugin/UHWallGenerator.java b/src/main/java/me/azenet/UHPlugin/UHWallGenerator.java index a5b98f2..e335c55 100644 --- a/src/main/java/me/azenet/UHPlugin/UHWallGenerator.java +++ b/src/main/java/me/azenet/UHPlugin/UHWallGenerator.java @@ -28,7 +28,7 @@ public UHWallGenerator(UHPlugin p, World w) { * @throws Exception */ public boolean build() { - Integer halfMapSize = (int) Math.floor(p.getConfig().getInt("map.size")/2); + Integer halfMapSize = (int) Math.floor(p.getBorderManager().getCurrentBorderDiameter()/2); Integer wallHeight = p.getConfig().getInt("map.wall.height"); this.wallBlockAir = Material.matchMaterial(p.getConfig().getString("map.wall.block.replaceAir")); diff --git a/src/main/java/me/azenet/UHPlugin/integration/UHWorldBorderIntegration.java b/src/main/java/me/azenet/UHPlugin/integration/UHWorldBorderIntegration.java index bcac3b5..2e58b29 100644 --- a/src/main/java/me/azenet/UHPlugin/integration/UHWorldBorderIntegration.java +++ b/src/main/java/me/azenet/UHPlugin/integration/UHWorldBorderIntegration.java @@ -48,7 +48,11 @@ public UHWorldBorderIntegration(UHPlugin p) { p.getLogger().info("Successfully hooked into WorldBorder."); } - private void setupBorders() { + public void setupBorders() { + if(!isWBIntegrationEnabled()) { + return; + } + /** General configuration **/ Config.setPortalRedirection(true); // Because the nether is border-less. @@ -68,7 +72,7 @@ private void setupBorders() { borderOverworld.setX(overworld.getSpawnLocation().getX()); // A border centered on the spawn point borderOverworld.setZ(overworld.getSpawnLocation().getZ()); - borderOverworld.setRadius((int) Math.floor(p.getConfig().getInt("map.size")/2)); + borderOverworld.setRadius((int) Math.floor(p.getBorderManager().getCurrentBorderDiameter()/2)); Config.setBorder(overworld.getName(), borderOverworld); diff --git a/src/main/java/me/azenet/UHPlugin/task/BorderWarningTask.java b/src/main/java/me/azenet/UHPlugin/task/BorderWarningTask.java new file mode 100644 index 0000000..520c6e3 --- /dev/null +++ b/src/main/java/me/azenet/UHPlugin/task/BorderWarningTask.java @@ -0,0 +1,32 @@ +package me.azenet.UHPlugin.task; + +import me.azenet.UHPlugin.UHPlugin; +import me.azenet.UHPlugin.i18n.I18n; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +public class BorderWarningTask extends BukkitRunnable { + + private UHPlugin p = null; + private I18n i = null; + + public BorderWarningTask(UHPlugin p) { + this.p = p; + this.i = p.getI18n(); + } + + @Override + public void run() { + + for(Player player : p.getBorderManager().getPlayersOutside(p.getBorderManager().getWarningSize())) { + int distance = p.getBorderManager().getDistanceToBorder(player.getLocation(), p.getBorderManager().getWarningSize()); + + player.sendMessage(i.t("borders.warning.message", String.valueOf(p.getBorderManager().getWarningSize()))); + player.sendMessage(i.t("borders.warning.messageDistance", String.valueOf(distance))); + } + + } + +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index de31c4a..65f37c3 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -14,6 +14,8 @@ map: # The replaceSolid one, where there was an other kind of block. replaceAir: GLASS replaceSolid: BEDROCK + border: + warningInterval: 90 # seconds daylightCycle: do: false diff --git a/src/main/resources/i18n/en_US.yml b/src/main/resources/i18n/en_US.yml index 0943d64..a244100 100644 --- a/src/main/resources/i18n/en_US.yml +++ b/src/main/resources/i18n/en_US.yml @@ -36,6 +36,7 @@ keys: helpAddspawnXZ: "{cc}/uh addspawn {ci}: adds a spawn point for a team or a player, at the provided coordinates." helpSpec: "{cc}/uh spec {ci}: manages the spectators. Execute /uh spec for details." helpWall: "{cc}/uh generatewalls {ci}: generates the walls according to the configuration." + helpBorder: "{cc}/uh border {ci}: manages borders. Execute /uh border for details." titleBugCmd: "{aqua}------ Bugs-related commands ------" helpHeal: "{cc}/uh heal [half-hearts=20] {ci}: heals a player to the number of half-hearts provided (default 20)." @@ -57,6 +58,14 @@ keys: specHelpAdd: "{cc}/uh spec add {ci}: adds a spectator." specHelpRemove: "{cc}/uh spec remove {ci}: removes a spectator." specHelpList: "{cc}/uh spec list{ci}: lists the spectators." + + borderHelpAvailable: "{ci}Available options are listed below." + borderHelpCurrent: "{cc}/uh border current{ci}: returns the current size of the map." + borderHelpSet: "{cc}/uh border set [force]{ci}: change the size of the map. If force is not given, the operation will be canceled if there is a player outside the border." + borderHelpWarning: "{cc}/uh border warning {ci}: warns all players outside the given future diameter. It's just a notice, nothing else." + borderHelpWarningCancel: "{cc}/uh border warning cancel{ci}: cancels a previously-set warning." + borderHelpCheck: "{cc}/uh border check {ci}: returns a list of the players outside the given border size." + start: already: "{ce}The game is already started! Reload or restart the server to restart the game." @@ -196,3 +205,33 @@ keys: countSpectators: "{ci}{0} registered spectator(s)." countOnlyInitial: "{ci}This count includes only the initial spectators." itemSpec: "{lightpurple} - {0}" + + borders: + syntaxError: "{ce}Syntax error, see /uh border." + NaN: "{ce}“{0}” is not a number..." + + current: + message: "{ci}The current map size is {0}*{0}." + + set: + playersOutsideCanceled: "{ce}Some players are outside the future border, so this operation was cancelled." + playersOutsideCanceledCmd: "{ci}Use {cc}/uh border set {0} force{ci} to resize the border regardless to this point." + playersOutsideCanceledWarnWorldBorder: "{ce}WARNING: {ci}because WorldBorder is not installed, players out of the border will be frozen!" + + broadcast: "{lightpurple}The size of the map is now {0}*{0}" + + warning: + canceled: "{cs}Warning canceled." + + set: "{cs}Future size saved. All players outside this future border will be warned every {0} seconds." + + message: "{ce}You are currently out of the future border of {0}*{0} blocks." + messageDistance: "{ci}You have {0} blocks to go before being inside." + + check: + allPlayersInside: "{cs}All players are inside the given border." + countPlayersOutside: "{ci}There are {0} players outside the given border." + + itemPlayerFar: "{lightpurple} - {red}{0}{ci} (far away from the border)" + itemPlayerClose: "{lightpurple} - {yellow}{0}{ci} (close to the border)" + itemPlayerVeryClose: "{lightpurple} - {green}{0}{ci} (very close to the border)" \ No newline at end of file diff --git a/src/main/resources/i18n/fr_FR.yml b/src/main/resources/i18n/fr_FR.yml index a79ca60..de1c170 100644 --- a/src/main/resources/i18n/fr_FR.yml +++ b/src/main/resources/i18n/fr_FR.yml @@ -36,6 +36,7 @@ keys: helpAddspawnXZ: "{cc}/uh addspawn {ci}: ajoute un point de démarrage pour une équipe ou un joueur, aux coordonnées données." helpSpec: "{cc}/uh spec {ci}: gère les spectateurs. Exécutez /uh spec pour plus de détails." helpWall: "{cc}/uh generatewalls {ci}: génère les murs suivant la configuration." + helpBorder: "{cc}/uh border {ci}: gère la bordure. Exécutez /uh border pour plus de détails." titleBugCmd: "{aqua}------ Commandes liées aux bugs ------" helpHeal: "{cc}/uh heal [half-hearts=20] {ci}: change la vie d'un joueur avec le nombre de demi-coeurs donné (par défaut, 20)." @@ -57,6 +58,13 @@ keys: specHelpAdd: "{cc}/uh spec add {ci}: ajoute un spectateur." specHelpRemove: "{cc}/uh spec remove {ci}: supprime un spectateur." specHelpList: "{cc}/uh spec list{ci}: liste les spectateurs." + + borderHelpAvailable: "{ci}Les options disponibles sont listées ci-dessous." + borderHelpCurrent: "{cc}/uh border current{ci}: retourne la taille actuelle de la carte." + borderHelpSet: "{cc}/uh border set [force]{ci}: change la taille de la carte. Si le paramètre “force” n'est pas donné, l'opération sera annulée s'il existe des joueurs hors de la bordure." + borderHelpWarning: "{cc}/uh border warning {ci}: avertit tous les joueurs hors de la future bordure donnée. Ce n'est qu'un avertissement, rien de plus." + borderHelpWarningCancel: "{cc}/uh border warning cancel{ci}: annule un précédent avertissement." + borderHelpCheck: "{cc}/uh border check {ci}: retourne la liste des joueurs hors de la bordure." start: already: "{ce}Le jeu est déjà démarré ! Rechargez ou redémarrez le serveur pour redémarrer." @@ -196,3 +204,34 @@ keys: countSpectators: "{ci}{0} spectateur(s) enregistré(s)." countOnlyInitial: "{ci}Ce compte inclue uniquement les spectateurs initiaux." itemSpec: "{lightpurple} - {0}" + + borders: + syntaxError: "{ce}Erreur de syntaxe, consultez /uh border." + NaN: "{ce}“{0}” n'est pas un nombre..." + + current: + message: "{ci}La taille actuelle de la carte est {0}*{0}." + + set: + playersOutsideCanceled: "{ce}Certains joueurs étant hors de cette nouvelle bordure, l'opération a été annulée." + playersOutsideCanceledCmd: "{ci}Utilisez {cc}/uh border set {0} force{ci} pour changer la taille de la carte malgré tout." + playersOutsideCanceledWarnWorldBorder: "{ce}ATTENTION: {ci}WorldBorder n'étant pas installé, les joueurs hors de la bordure seront immobilisés !" + + broadcast: "{lightpurple}La taille de la carte est désormais de {0}*{0}" + + warning: + canceled: "{cs}Avertissement annulé." + + set: "{cs}Future taille enregistrée. Les joueurs hors de la bordure vont être avertis toutes les {0} secondes." + + message: "{ce}Vous êtes hors de la future bordure de {0}*{0} blocs." + messageDistance: "{ci}Il vous reste {0} blocs à parcourir avant d'y être." + + check: + allPlayersInside: "{cs}Tous les joueurs sont à l'intérieur de cette bordure." + countPlayersOutside: "{ci}Il y a {0} joueurs hors de cette bordure." + + itemPlayerFar: "{lightpurple} - {red}{0}{ci} (loin de la bordure)" + itemPlayerClose: "{lightpurple} - {yellow}{0}{ci} (proche de la bordure)" + itemPlayerVeryClose: "{lightpurple} - {green}{0}{ci} (très proche de la bordure)" + diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 3ab3f85..be88bbd 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -48,6 +48,9 @@ permissions: uh.generatewalls: description: Allows an user to generate the walls around the map default: op + uh.border: + description: Allows an user to manage the border using /uh border * + default: op uh.heal: description: Allows an user to heal a player using /uh heal [half-hearts] default: op @@ -61,5 +64,5 @@ permissions: description: Allows an user to teleport back a player to his spawn point with /uh tpback [force] default: op uh.spec: - description: Alows an user to manage spectators using /uh spec * + description: Allows an user to manage spectators using /uh spec * default: op