diff --git a/Towny/pom.xml b/Towny/pom.xml
index 3f281d19d9..f32d9026f4 100644
--- a/Towny/pom.xml
+++ b/Towny/pom.xml
@@ -13,7 +13,7 @@
towny
jar
- 0.100.3.4
+ 0.100.3.5
@@ -210,13 +210,13 @@
org.junit.jupiter
junit-jupiter
- 5.10.2
+ 5.10.3
test
org.junit.jupiter
junit-jupiter-api
- 5.10.2
+ 5.10.3
test
@@ -423,7 +423,7 @@
org.apache.maven.plugins
maven-jar-plugin
- 3.4.1
+ 3.4.2
diff --git a/Towny/src/main/java/com/palmergames/bukkit/config/ConfigNodes.java b/Towny/src/main/java/com/palmergames/bukkit/config/ConfigNodes.java
index abbccf5c80..19d1adb2f9 100644
--- a/Towny/src/main/java/com/palmergames/bukkit/config/ConfigNodes.java
+++ b/Towny/src/main/java/com/palmergames/bukkit/config/ConfigNodes.java
@@ -534,7 +534,7 @@ public enum ConfigNodes {
"global_town_settings.peaceful_cooldown_time",
"30",
"",
- "# Number of seconds that must pass before peacfulness can be toggled by a town or nation."),
+ "# Number of seconds that must pass before peacefulness can be toggled by a town or nation."),
GTOWN_SETTINGS_TOWN_DELETE_COOLDOWN_TIMER(
"global_town_settings.town_delete_cooldown_time",
"0",
@@ -1690,6 +1690,13 @@ public enum ConfigNodes {
"",
"# Maximum length of Town and Nation names. Setting this to a number below your current max_name_length could result in",
"# safe mode if the new value is below of your existing town and nation name lengths."),
+ FILTERS_MAX_NAME_CAPITAL_LETTERS(
+ "filters_colour_chat.modify_chat.max_name_capital_letters",
+ "-1",
+ "",
+ "# Maximum number of capital letters that can be used in Town and Nation names. Set to -1 to disable this feature.",
+ "# This count does not include the first letter of a town, and does not count capitalized letters that come after a _ character.",
+ "# This means that a town named New_York would register 0 capitals. While McDonalds would register 1. COOLTOWN would register 7 capital letters."),
FILTERS_MAX_TAG_LENGTH(
"filters_colour_chat.modify_chat.max_tag_length",
"4",
diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/TownySettings.java b/Towny/src/main/java/com/palmergames/bukkit/towny/TownySettings.java
index be7a9610cc..518b6c1612 100644
--- a/Towny/src/main/java/com/palmergames/bukkit/towny/TownySettings.java
+++ b/Towny/src/main/java/com/palmergames/bukkit/towny/TownySettings.java
@@ -1458,6 +1458,11 @@ public static int getMaxNameLength() {
return getInt(ConfigNodes.FILTERS_MAX_NAME_LGTH);
}
+ public static int getMaxNameCapitalLetters() {
+
+ return getInt(ConfigNodes.FILTERS_MAX_NAME_CAPITAL_LETTERS);
+ }
+
public static long getDeleteTime() {
return getSeconds(ConfigNodes.RES_SETTING_DELETE_OLD_RESIDENTS_TIME);
diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/command/TownyAdminCommand.java b/Towny/src/main/java/com/palmergames/bukkit/towny/command/TownyAdminCommand.java
index 50db6569d0..ba5896ac12 100644
--- a/Towny/src/main/java/com/palmergames/bukkit/towny/command/TownyAdminCommand.java
+++ b/Towny/src/main/java/com/palmergames/bukkit/towny/command/TownyAdminCommand.java
@@ -1179,7 +1179,7 @@ public void parseAdminTownCommand(CommandSender sender, String[] split) throws T
// Special case where we can create a new Town before we use split[0] to get a Town.
if (split[0].equalsIgnoreCase("new")) {
- parseAdminNewTownCommand(sender, split);
+ parseAdminNewTownCommand(sender, StringMgmt.remFirstArg(split));
return;
}
@@ -1398,25 +1398,27 @@ public void parseAdminTownCommand(CommandSender sender, String[] split) throws T
}
private void parseAdminNewTownCommand(CommandSender sender, String[] split) throws TownyException {
- if (split.length != 3)
+ if (split.length < 2)
throw new TownyException(Translatable.of("msg_err_not_enough_variables") + "/ta town new [townname] [mayor]");
checkPermOrThrow(sender, PermissionNodes.TOWNY_COMMAND_TOWNYADMIN_TOWN_NEW.getNode());
+ String mayorName = split[split.length - 1];
+ String townName = StringMgmt.join(StringMgmt.remLastArg(split), "_");
Player player = sender instanceof Player p ? p : null;
Resident resident;
- if ("npc".equalsIgnoreCase(split[2]) && player != null) // Avoid creating a new npc resident if command is ran from console.
+ if ("npc".equalsIgnoreCase(mayorName) && player != null) // Avoid creating a new npc resident if command is ran from console.
resident = ResidentUtil.createAndGetNPCResident();
else
- resident = getResidentOrThrow(split[2]);
+ resident = getResidentOrThrow(mayorName);
// If the command is being run from console, try to sub in the specfied player.
if (player == null) {
if (!resident.isOnline())
- throw new TownyException(Translatable.of("msg_player_is_not_online", split[2]));
+ throw new TownyException(Translatable.of("msg_player_is_not_online", mayorName));
player = resident.getPlayer();
}
- TownCommand.newTown(player, split[1], resident, true, true);
+ TownCommand.newTown(player, townName, resident, true, true);
}
private void parseAdminTownSet(CommandSender sender, Town town, String[] split) throws TownyException {
diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownyFlatFileSource.java b/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownyFlatFileSource.java
index 678e90dfb7..793784e098 100644
--- a/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownyFlatFileSource.java
+++ b/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownyFlatFileSource.java
@@ -1647,7 +1647,7 @@ public boolean loadTownBlocks() {
String line = "";
String path;
-
+ List toSave = new ArrayList<>();
for (TownBlock townBlock : universe.getTownBlocks().values()) {
path = getTownBlockFilename(townBlock);
@@ -1655,7 +1655,7 @@ public boolean loadTownBlocks() {
if (fileTownBlock.exists() && fileTownBlock.isFile()) {
try {
- HashMap keys = FileMgmt.loadFileIntoHashMap(fileTownBlock);
+ HashMap keys = FileMgmt.loadFileIntoHashMap(fileTownBlock);
line = keys.get("town");
if (line != null) {
@@ -1668,8 +1668,10 @@ public boolean loadTownBlocks() {
Town town = null;
if (universe.hasTown(line.trim()))
town = universe.getTown(line.trim());
- else if (universe.getReplacementNameMap().containsKey(line.trim()))
- town = universe.getTown(universe.getReplacementNameMap().get(line).trim());
+ else if (universe.getReplacementNameMap().containsKey(line.trim())) {
+ town = universe.getTown(universe.getReplacementNameMap().get(line.trim()));
+ toSave.add(townBlock);
+ }
if (town == null) {
TownyMessaging.sendErrorMsg(Translation.of("flatfile_err_townblock_file_contains_unregistered_town_delete", line, path));
@@ -1832,6 +1834,10 @@ else if (universe.getReplacementNameMap().containsKey(line.trim()))
}
}
+ // Some townblocks have had their town name change. Save the townblocks.
+ if (!toSave.isEmpty())
+ toSave.forEach(TownBlock::save);
+
return true;
}
diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/event/teleport/SuccessfulTownyTeleportEvent.java b/Towny/src/main/java/com/palmergames/bukkit/towny/event/teleport/SuccessfulTownyTeleportEvent.java
index e4a36ebfe6..3386b6534f 100644
--- a/Towny/src/main/java/com/palmergames/bukkit/towny/event/teleport/SuccessfulTownyTeleportEvent.java
+++ b/Towny/src/main/java/com/palmergames/bukkit/towny/event/teleport/SuccessfulTownyTeleportEvent.java
@@ -17,13 +17,15 @@
public class SuccessfulTownyTeleportEvent extends Event {
private static final HandlerList handlers = new HandlerList();
- private Resident resident;
- private Location teleportLocation;
+ private final Resident resident;
+ private final Location teleportLocation;
+ private final double teleportCost;
- public SuccessfulTownyTeleportEvent(Resident resident, Location loc) {
+ public SuccessfulTownyTeleportEvent(Resident resident, Location loc, double cost) {
super(!Bukkit.isPrimaryThread());
this.resident = resident;
this.teleportLocation = loc;
+ this.teleportCost = cost;
}
@NotNull
@@ -44,4 +46,10 @@ public Location getTeleportLocation() {
return teleportLocation;
}
+ /**
+ * @return The price that the player paid to teleport.
+ */
+ public double getTeleportCost() {
+ return this.teleportCost;
+ }
}
diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/listeners/TownyEntityListener.java b/Towny/src/main/java/com/palmergames/bukkit/towny/listeners/TownyEntityListener.java
index b122424baf..851d6a3299 100644
--- a/Towny/src/main/java/com/palmergames/bukkit/towny/listeners/TownyEntityListener.java
+++ b/Towny/src/main/java/com/palmergames/bukkit/towny/listeners/TownyEntityListener.java
@@ -208,14 +208,14 @@ public void onEntityDeath(EntityDeathEvent event) {
}
/**
- * Prevent block explosions and lightning from hurting entities.
+ * Prevent entity and block explosions and lightning from hurting entities.
*
* Doesn't stop damage to vehicles or hanging entities.
*
* @param event - EntityDamageEvent
*/
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
- public void onEntityTakesBlockExplosionDamage(EntityDamageEvent event) {
+ public void onEntityTakesExplosionDamage(EntityDamageEvent event) {
if (plugin.isError()) {
event.setCancelled(true);
return;
@@ -224,12 +224,19 @@ public void onEntityTakesBlockExplosionDamage(EntityDamageEvent event) {
if (!TownyAPI.getInstance().isTownyWorld(event.getEntity().getWorld()))
return;
- if ((event.getCause() == DamageCause.BLOCK_EXPLOSION || event.getCause() == DamageCause.LIGHTNING) && entityProtectedFromExplosiveDamageHere(event.getEntity(), event.getCause())) {
+ if (causeIsExplosive(event.getCause()) && entityProtectedFromExplosiveDamageHere(event.getEntity(), event.getCause())) {
event.setDamage(0);
event.setCancelled(true);
}
}
+ private boolean causeIsExplosive(DamageCause cause) {
+ return switch(cause) {
+ case ENTITY_EXPLOSION, BLOCK_EXPLOSION, LIGHTNING -> true;
+ default -> false;
+ };
+ }
+
/**
* Removes dragon fireball AreaEffectClouds when they would spawn somewhere with PVP disabled.
*
diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/listeners/TownyPlayerListener.java b/Towny/src/main/java/com/palmergames/bukkit/towny/listeners/TownyPlayerListener.java
index 14dff9bc89..76e75cfe92 100644
--- a/Towny/src/main/java/com/palmergames/bukkit/towny/listeners/TownyPlayerListener.java
+++ b/Towny/src/main/java/com/palmergames/bukkit/towny/listeners/TownyPlayerListener.java
@@ -306,9 +306,10 @@ public void onPlayerBucketFill(PlayerBucketFillEvent event) {
if (!TownyAPI.getInstance().isTownyWorld(event.getPlayer().getWorld()))
return;
-
- // Bail if we're filling air, usually a milked cow.
- if (event.getBlockClicked().getType().equals(Material.AIR))
+
+ // Bail if we're milking a cow, goat, or if we're filling air.
+ if (event.getItemStack().getType().equals(Material.MILK_BUCKET)
+ || event.getBlockClicked().getType().equals(Material.AIR))
return;
// Test whether we can fill the bucket by testing if they would be able to destroy the liquid it is picking up.
@@ -663,9 +664,10 @@ public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
actionType = ActionType.SWITCH;
} else if (EntityLists.DYEABLE.contains(entityType) && ItemLists.DYES.contains(item))
mat = item;
- else if (item != null && item == Material.BUCKET && EntityLists.MILKABLE.contains(entityType))
+ else if (item != null && item == Material.BUCKET && EntityLists.MILKABLE.contains(entityType)) {
mat = EntityTypeUtil.parseEntityToMaterial(entityType);
- else if (item != null && item == Material.COOKIE && EntityType.PARROT.equals(entityType))
+ actionType = ActionType.ITEM_USE;
+ } else if (item != null && item == Material.COOKIE && EntityType.PARROT.equals(entityType))
mat = EntityTypeUtil.parseEntityToMaterial(entityType);
else if (EntityLists.RIGHT_CLICK_PROTECTED.contains(entityType))
mat = EntityTypeUtil.parseEntityToMaterial(entityType);
diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/TeleportWarmupTimerTask.java b/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/TeleportWarmupTimerTask.java
index 9ae34fc28f..e30707d4a3 100644
--- a/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/TeleportWarmupTimerTask.java
+++ b/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/TeleportWarmupTimerTask.java
@@ -68,7 +68,7 @@ public void run() {
PaperLib.teleportAsync(player, request.destinationLocation(), TeleportCause.COMMAND);
- BukkitTools.fireEvent(new SuccessfulTownyTeleportEvent(resident, request.destinationLocation()));
+ BukkitTools.fireEvent(new SuccessfulTownyTeleportEvent(resident, request.destinationLocation(), request.teleportCost()));
if (request.cooldown() > 0)
CooldownTimerTask.addCooldownTimer(resident.getName(), "teleport", request.cooldown());
diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/utils/SpawnUtil.java b/Towny/src/main/java/com/palmergames/bukkit/towny/utils/SpawnUtil.java
index fed2f94fd0..d92b483db5 100644
--- a/Towny/src/main/java/com/palmergames/bukkit/towny/utils/SpawnUtil.java
+++ b/Towny/src/main/java/com/palmergames/bukkit/towny/utils/SpawnUtil.java
@@ -672,7 +672,7 @@ private static void initiateSpawn(Player player, Location spawnLoc, int cooldown
if (player.getVehicle() != null)
player.getVehicle().eject();
PaperLib.teleportAsync(player, spawnLoc, TeleportCause.COMMAND);
- BukkitTools.fireEvent(new SuccessfulTownyTeleportEvent(resident, spawnLoc));
+ BukkitTools.fireEvent(new SuccessfulTownyTeleportEvent(resident, spawnLoc, cost));
if (cooldown > 0 && !hasPerm(player, PermissionNodes.TOWNY_SPAWN_ADMIN_NOCOOLDOWN))
CooldownTimerTask.addCooldownTimer(player.getName(), "teleport", cooldown);
}
diff --git a/Towny/src/main/java/com/palmergames/bukkit/util/NameValidation.java b/Towny/src/main/java/com/palmergames/bukkit/util/NameValidation.java
index b1a117e3f5..dfe52334a7 100644
--- a/Towny/src/main/java/com/palmergames/bukkit/util/NameValidation.java
+++ b/Towny/src/main/java/com/palmergames/bukkit/util/NameValidation.java
@@ -80,6 +80,8 @@ public static String checkAndFilterTownNameOrThrow(String name) throws InvalidNa
testForImproperNameAndThrow(out);
+ testCapitalization(out);
+
testForSubcommand(out);
if (out.startsWith(TownySettings.getTownAccountPrefix()))
@@ -104,6 +106,8 @@ public static String checkAndFilterNationNameOrThrow(String name) throws Invalid
testForImproperNameAndThrow(out);
+ testCapitalization(out);
+
testForSubcommand(out);
if (out.startsWith(TownySettings.getNationAccountPrefix()))
@@ -283,6 +287,40 @@ private static void testAllUnderscores(String name) throws InvalidNameException
throw new InvalidNameException(Translatable.of("msg_err_name_validation_is_all_underscores", name));
}
+ /**
+ * Stops objects being named with too many capital letters.
+ *
+ * @param name String submitted for testing.
+ * @throws InvalidNameException when the name uses too many capital letters.
+ */
+ private static void testCapitalization(String name) throws InvalidNameException {
+ int maxCapitals = TownySettings.getMaxNameCapitalLetters();
+ if (maxCapitals == -1)
+ return;
+
+ int capitals = 0;
+ boolean skip = true;
+ for (char letter : name.toCharArray()) {
+ if (skip) { // First character of the name or character after a _.
+ skip = false;
+ continue;
+ }
+
+ if (letter == '_') { // Next character will be allowed to be capitalized.
+ skip = true;
+ continue;
+ }
+
+ if (Character.isLowerCase(letter)) // Not a capital.
+ continue;
+
+ capitals++;
+ }
+
+ if (capitals > maxCapitals)
+ throw new InvalidNameException(Translatable.of("msg_err_name_validation_too_many_capitals", name, capitals, maxCapitals));
+ }
+
/**
* Stops escape characters being used, something that could harm mysql if things weren't sanitized.
*
diff --git a/Towny/src/main/resources/ChangeLog.txt b/Towny/src/main/resources/ChangeLog.txt
index df29e0761e..2682ccacc3 100644
--- a/Towny/src/main/resources/ChangeLog.txt
+++ b/Towny/src/main/resources/ChangeLog.txt
@@ -9845,4 +9845,22 @@ v0.92.0.11:
withdraw from the bank anyways, but it might keep towns from being deleted for not paying their upkeep.
- Fix potential NPEs in PlotGroup, courtesy of galacticwarrior9 with PR #7483.
0.100.3.4:
- - Fix town plot permissions changing not causing the town to save.
\ No newline at end of file
+ - Fix town plot permissions changing not causing the town to save.
+ - Improve /ta town new TOWNNAME MAYORNAME, to support town names entered with spaces in them.
+ - Fix milking animals sometimes being able to get cancelled by the PlayerBucketFillEvent.
+ - Expose cost in successful teleport event, courtesy of Warrior with PR #7487.
+ - Closes #7486.
+ - Bump org.junit.jupiter:junit-jupiter from 5.10.2 to 5.10.3.
+ - Bump org.junit.jupiter:junit-jupiter-api from 5.10.2 to 5.10.3.
+ - Bump org.apache.maven.plugins:maven-jar-plugin from 3.4.1 to 3.4.2.
+0.100.3.5:
+ - Fix TownBlocks which load replacement town names save the new town name in the database.
+ - Make more explosive entities throw TownyExplosionDamagesEntityEvent events when they explode and damage entities.
+ - Add the ability to limit the number of capital letters used in Town and Nation names.
+ - Closes 7497.
+ - New Config Option: filters_colour_chat.modify_chat.max_name_capital_letters
+ - Default: -1
+ - Maximum number of capital letters that can be used in Town and Nation names.
+ - This count does not include the first letter of a town, and does not count capitalized letters that come after a _ character.
+ - This means that a town named New_York would register 0 capitals. While McDonalds would register 1. COOLTOWN would register 7 capital letters.
+ - Fix config typo, courtesy of auriasmc with PR #7498. (First-Time Contributor!)
\ No newline at end of file
diff --git a/Towny/src/main/resources/lang/en-US.yml b/Towny/src/main/resources/lang/en-US.yml
index 7f74bec6fa..91213e1970 100644
--- a/Towny/src/main/resources/lang/en-US.yml
+++ b/Towny/src/main/resources/lang/en-US.yml
@@ -2461,6 +2461,8 @@ msg_err_name_validation_is_not_permitted: "%s is not permitted."
msg_err_name_validation_is_all_underscores: "%s is entirely underscores."
+msg_err_name_validation_too_many_capitals: "%s contains %s capital letters which were not allowed, use less than %s."
+
msg_err_name_validation_contains_harmful_characters: "%s contains symbols that could be harmful."
msg_err_name_validation_contains_numbers: "%s contains numbers which aren't allowed in names."
diff --git a/Towny/src/main/resources/lang/es-CL.yml b/Towny/src/main/resources/lang/es-CL.yml
index 5ff2eb0792..408983b082 100644
--- a/Towny/src/main/resources/lang/es-CL.yml
+++ b/Towny/src/main/resources/lang/es-CL.yml
@@ -3,8 +3,7 @@ name: Towny
language: es-cl
author: GNosii
website: 'https://townyadvanced.github.io/'
-description: >
- Language file for all game messages for this Locale.
+description: Language file for all game messages for this Locale.
#A note on editing this file.
#----------------------------
#Do not alter this file if it is in the reference folder.
@@ -2125,3 +2124,5 @@ msg_town_being_deleted_because_no_residents: "%s está siendo eliminado porque p
outlawed_in: "Excluido en"
msg_warning_town_deposit_hint: "Para depositar dinero en tu banco de ciudad utiliza /town deposit [amount]."
msg_warning_nation_deposit_hint: "Para depositar dinero en tu banco de nación usa /nation deposit [amount]."
+teleport_warmup_title_dont_move: "&6¡No te muevas!"
+teleport_warmup_subtitle_seconds_remaining: "&c%s &7segundos restantes para teletransportarse."
diff --git a/Towny/src/main/resources/lang/es-ES.yml b/Towny/src/main/resources/lang/es-ES.yml
index 95652c47db..1b00b49ad3 100644
--- a/Towny/src/main/resources/lang/es-ES.yml
+++ b/Towny/src/main/resources/lang/es-ES.yml
@@ -18,6 +18,10 @@ help_6: 'Ayuda del comando nation.'
help_7: 'Ayuda del comando plot.'
help_8: 'Ayuda del comando towny.'
help_9: 'Ayuda del comando townyadmin.'
+towny_help_0: "Ayuda general para Towny"
+towny_help_1: "Muestra un mapa de los poblados cercanos"
+towny_help_2: "Mostrar los precios utilizados con Economía"
+towny_help_3: "Mostrar puntuaciones altas"
town_help_1: 'Estado de tu ciudad'
town_help_2: '[alcalde]'
town_help_3: 'Estado de la ciudad seleccionada'
diff --git a/Towny/src/main/resources/lang/it-IT.yml b/Towny/src/main/resources/lang/it-IT.yml
index ac71426119..61c90987b2 100644
--- a/Towny/src/main/resources/lang/it-IT.yml
+++ b/Towny/src/main/resources/lang/it-IT.yml
@@ -67,6 +67,9 @@ town_list_help_2: "Elenca le città che sono aperte, con la pagina specificata."
town_list_help_3: "Elenca le città usando il saldo bancario, con la pagina specificata."
town_list_help_4: "Elenca le città in ordine alfabetico, con la pagina specificata."
town_list_help_5: "Elenca le città per terra reclamata, con la pagina specificata."
+town_set_help_7: "Imposta il costo per usare /t spawn."
+town_set_help_8: "Imposta il nome della tua città."
+town_jail_help_0: "Elenca le prigioni della città."
mayor_help_3: 'Claima una zona non confinante con la città'
mayor_help_4: 'Claima intorno a te in un raggio X'
mayor_help_5: 'Claima per il raggio massimo'
@@ -82,6 +85,10 @@ nation_help_6: 'Crea una nuova nazione'
nation_help_7: 'Elenca i comandi del leader della nazione'
nation_help_8: 'Crea una nuova nazione'
nation_help_9: 'Elenca tutti i residenti online nella nazione'
+nation_help_11: "Elenca le città della nazione."
+nation_help_12: "Elenca le nazioni alleate della nazione."
+nation_help_13: "Elenca le nazioni nemiche della nazione."
+nation_help_14: "Utilizzato per unirsi alle nazioni aperte."
king_help_1: 'Guida del Re della nazione'
king_help_2: 'Scegli le tue alleanze.'
king_help_3: 'Scegli i tuoi nemici.'
@@ -89,6 +96,7 @@ res_1: 'Il tuo stato'
res_2: '[residente]'
res_3: 'Stato del giocatore specificato'
res_4: 'Elenca tutti i giocatori attivi'
+res_jail_help_0: "Paga il costo della cauzione per uscire di prigione."
mode_1: 'Mostra la mappa tra ogni lotto di città'
mode_2: 'Prova a claimare camminando'
mode_3: 'Prova ad unclaimare i lotti camminando'
diff --git a/Towny/src/main/resources/lang/pt-BR.yml b/Towny/src/main/resources/lang/pt-BR.yml
index 0875da6498..cbc0f7b967 100644
--- a/Towny/src/main/resources/lang/pt-BR.yml
+++ b/Towny/src/main/resources/lang/pt-BR.yml
@@ -181,6 +181,8 @@ res_toggle_help_11: "Espie canais de bate-papo."
res_toggle_help_12: "Alterne a capacidade de adicionar gráficos a um grupo de gráficos que você iniciou."
res_toggle_help_13: "Alterna a capacidade de ver mensagens de título quando você mudar de quarteirão."
res_toggle_help_14: "Alterna a habilidade de desfazer a reivindicação por onde você anda."
+res_toggle_help_15: "."
+res_toggle_help_16: "Alterne a habilidade de desativar seus contornos de administrador."
mode_1: 'Mostra o mapa entre cada terreno da cidade'
mode_2: 'Tentar reivindicar terreno ao andar'
mode_3: 'Tentar abandonar terreno ao andar'
diff --git a/Towny/src/main/resources/lang/tr-TR.yml b/Towny/src/main/resources/lang/tr-TR.yml
index 4130bdd5d5..6201ec86f2 100644
--- a/Towny/src/main/resources/lang/tr-TR.yml
+++ b/Towny/src/main/resources/lang/tr-TR.yml
@@ -129,6 +129,8 @@ nation_list_help_4: "Kasabaları banka bakiyelerine göre listelenmiş sayfada g
nation_list_help_5: "Ulusları belirtilen sayfayla birlikte alfabetik sırayla listeleyin."
nation_list_help_6: "Talep edilen bölgeye göre kasabaları listeleyin"
nation_list_help_7: "Kasabaları çevrim içi sayılarına göre listele."
+nation_set_help_0: "Ulusunuzun liderini değiştirin."
+nation_set_help_1: "Ulusunuzun başkentini değiştirin."
nation_set_help_2: "Kasabaların ödeyeceği vergi miktarını belirleyin."
nation_set_help_3: "Fethedilen kasabaların ödeyeceği vergi miktarını ayarlayın."
nation_set_help_4: "Ulusun ismini düzenle."
@@ -139,6 +141,12 @@ nation_set_help_8: "Ulusun spawn noktasını ayarlayın."
nation_set_help_9: "/n spawn komutunu kullanmanın ücretini belirleyin."
nation_set_help_10: "Haritalama eklentilerinde kullanılan harita rengini ayarlayın."
nation_toggle_help_0: "Ulusun barışçıl durumunu değiştirir."
+nation_toggle_help_1: "Herkese açık durumu değiştirir, üyelerinizden başkasının /n spawn komutunu kullanmasını engeller."
+nation_toggle_help_2: "Herkese açık katılım durumunu değiştirir, davete ihtiyaç duymadan kasabanıza üye olabilirler."
+nation_toggle_help_3: "Vergi miktarını değiştirir, kasabaların normal vergiden farklı bir ödeme yapmasını sağlar."
+nation_sanction_help_1: "Bir kasabayı, AmbargoKasabaları listesine ekler."
+nation_sanction_help_2: "Bir kasabayı, AmbargoKasabaları listesinden kaldırır."
+nation_sanction_help_3: "Ulusunuzdaki AmbargoKasabalarını listeler."
king_help_1: 'Ulus Lideri Yardımı'
king_help_2: 'İttifakınızı kurun.'
king_help_3: 'Düşmanlarınızı ayarlayın.'
diff --git a/Towny/src/main/resources/lang/vi-VN.yml b/Towny/src/main/resources/lang/vi-VN.yml
index ae6dd74eaf..21cc69a171 100644
--- a/Towny/src/main/resources/lang/vi-VN.yml
+++ b/Towny/src/main/resources/lang/vi-VN.yml
@@ -96,6 +96,7 @@ town_towntrust_help_0: "Thêm một thị trấn là đáng tin cậy trong th
town_towntrust_help_1: "Loại bỏ một thị trấn là đáng tin cậy trong thị trấn."
town_towntrust_help_2: "Liệt kê các thị trấn đáng tin cậy của một thị trấn."
town_buy_help: "Mua thêm các khối thị trấn để tăng giới hạn yêu cầu của thị trấn."
+town_cede_help: ""
mayor_help_3: 'Chiếm khu vực không thuộc thị trấn'
mayor_help_4: 'Chiếm khu vực xung quanh bạn trong bán kính X'
mayor_help_5: 'Chiếm theo bán kính lớn nhất'
@@ -128,6 +129,10 @@ nation_list_help_5: "Liệt kê các quốc gia theo thứ tự bảng chữ cá
nation_list_help_6: "Liệt kê các quốc gia theo vùng đất được tuyên bố chủ quyền, với trang được chỉ định."
nation_list_help_7: "Liệt kê các quốc gia theo số lượng trực tuyến, với trang được chỉ định."
nation_set_help_0: "Thay đổi người lãnh đạo đất nước."
+nation_set_help_1: ""
+nation_set_help_2: ""
+nation_set_help_3: "."
+nation_set_help_4: "."
king_help_1: 'Trợ giúp dành cho lãnh đạo quốc gia'
king_help_2: 'Đặt liên minh của bạn.'
king_help_3: 'Đặt kẻ thù của bạn.'
diff --git a/Towny/src/main/resources/lang/zh-CN.yml b/Towny/src/main/resources/lang/zh-CN.yml
index 9058a4a860..c9666b4638 100644
--- a/Towny/src/main/resources/lang/zh-CN.yml
+++ b/Towny/src/main/resources/lang/zh-CN.yml
@@ -71,7 +71,7 @@ town_help_15: "参见该镇被放逐者名单。"
town_help_16: "参见该镇地皮组的清单。"
town_help_17: "参见该镇的地皮类型清单。"
town_help_18: "向该镇成员发送一条消息"
-town_help_19: "将您的城镇设置为出售,供其他玩家购买。"
+town_help_19: "将您的城镇设置为出售,可供其他玩家购买。"
town_help_20: "设置您的城镇状态为不供出售"
town_help_21: "购买给定的城镇(只要它是出售的)。"
town_help_22: "向您的城镇银行存钱。"
@@ -83,7 +83,7 @@ town_help_27: "离开你所在的城镇。"
town_help_28: "从您的城镇银行取钱。"
town_help_29: "使用指令/t claim ?以获得帮助。"
town_help_30: "用来取消声明你城镇的土地。"
-town_help_31: "添加或者移除居民。"
+town_help_31: "添加或移除一个居民。"
town_help_32: "使用指令/t set ?以获得帮助。"
town_help_33: "使用指令/t buy ?以获得帮助。"
town_help_34: "使用指令/t toggle ?以获得帮助。"
@@ -256,7 +256,7 @@ world_toggle_help_11: "打开/关闭这个世界中的区块-无索赔-删除-
townyadmin_help_1: '放弃声明这个城镇区块'
townyadmin_help_2: '放弃声明你附近的城镇区块.'
admin_panel_1: "查看/ta set ?以获得帮助。"
-admin_panel_2: '重载城镇'
+admin_panel_2: '重载Towny插件'
admin_panel_3: '执行新一天指令'
admin_panel_4: "取消对你所处区块的宣称。"
admin_panel_5: "查看/ta plot ?以获得帮助。"
@@ -417,7 +417,7 @@ msg_plot_fs_radius: '出售你输入的半径的地皮'
#+------------------------------------------------------+ #
############################################################
msg_buy: '&b用 %s 购买了 %d %s .'
-msg_buy_resident_plot: '&b%s 花费了 %s 购买了 %s 的土地!'
+msg_buy_resident_plot: '&b%1$s花费%$3s购买了%$2s的土地!'
msg_buy_resident_plot_group: '&b%s为%s购买了%s的区块。'
msg_couldnt_pay_taxes: '&b%s 因为交不起税而被踢出了 %s.'
msg_couldnt_pay_plot_taxes: '&b%s 交不起税而失去了他的土地所有权.'
@@ -492,8 +492,8 @@ msg_abandoned_area_1: '&b你的城镇放弃了这片区域'
msg_no_money_purchase_plot: '&c你没有足够的钱来购买这块土地.'
msg_town_no_money_purchase_plot: '&c城镇没有足够的钱来买回这块土地.'
msg_no_funds_new_town: '&c%s 没有足够的建城资金.'
-msg_no_funds_claim: '&c城镇现在没有足够的资金来声明%s个城镇区块,因为这需要%s。您捐些钱到城镇银行吧。'
-msg_no_funds_to_buy: '&c城镇现在没有足够的资金来购买%s %s,因为这需要花费%s。您捐些钱到城镇银行吧。'
+msg_no_funds_claim: '&c城镇现在没有足够的资金来声明%s个城镇区块,因为这需要%s。捐些钱到城镇银行吧。'
+msg_no_funds_to_buy: '&c城镇现在没有足够的资金来购买%s %s,因为这需要花费%s。捐些钱到城镇银行吧。'
msg_annexed_area: '&2被吞并的区域 %s'
msg_max_plot_own: '&c你不能拥有多于 %s 块的土地.'
msg_max_outposts_own: '&c你不能声明多余 %s 个的前哨.'
@@ -539,8 +539,8 @@ msg_reloaded: '&2城镇设置已重载.'
msg_undo_complete: '&2成功撤销操作.'
msg_give_total: '&b给予 %s 奖励区块上限. (总共: %s)'
mag_backup_success: '&2完成备份.'
-msg_xx_withdrew_xx: '&b%s 从城镇银行取出了 %s.'
-msg_xx_deposited_xx: '&b%s 捐赠了 %s 元到 %s 银行内.'
+msg_xx_withdrew_xx: '&b%1$s从%3$s银行取出了%2$s。'
+msg_xx_deposited_xx: '&b%1$s向%3$s银行捐赠了%2$s。'
msg_insuf_funds: '&c你没有这么多钱.'
msg_err_withdraw_disabled: '取款功能已关闭!'
msg_err_deposit_capped: '无法捐款. 银行资金上限为 %s.'
@@ -666,7 +666,7 @@ msg_admin_only_create_town: '&c只有管理员能够创建城镇!'
msg_err_not_enough_residents_new_nation: '&c你的城镇居民数不足以建国.'
msg_err_not_enough_residents_join_nation: '&b城镇 %s 没有足够的居民数所以无法加入国家.'
msg_not_enough_residents_no_longer_capital: '&b国家旧都居民数不足所以不再是首都.新的首都将在 %s.'
-msg_town_not_enough_residents_left_nation: '&b因为城镇 %s 不再有有足够的居民来成为国家的一员,所以它被赶出了国家。'
+msg_town_not_enough_residents_left_nation: '&b城镇%s被赶出了国家,因为它不再有足够的居民来成为国家的一员。'
msg_nation_disbanded_town_not_enough_residents: '&b城镇 %s 没有足够的居民数来形成国家以至于国家灭亡.'
msg_not_enough_residents_refunded: '&b你的国家由于居民数不足而灭亡了,因此你获得了 $%s .'
msg_not_enough_residents_capital: '&b城镇 %s 没有足够的居民来作为首都.'
@@ -844,7 +844,7 @@ tc_err_you_dont_have_unmute_perm: '您没有解除禁言的权限'
tc_err_no_channel_called_channel: '没有名为&f%s的频道'
tc_err_no_muted_players_in_channel_players: '解除禁言玩家 &f%s'
tc_players_muted_in_channel: '[城镇聊天] &f%n &2玩家被禁言了 &f%s&2: &f%s'
-tc_err_no_online_players_with_name: '没有在线玩家的名字是&f%s'
+tc_err_no_online_players_with_name: '没有在线玩家名为&f%s'
tc_err_you_dont_have_mute_perms: '您没有禁言权限'
tc_err_you_cant_mute_admin: '你不能禁言一个城镇管理员.'
tc_err_you_cant_mute_chat_mod: '你不能禁言聊天管理者.'
@@ -1199,7 +1199,7 @@ msg_cache_block_error_plot_outsiders: '外来者'
msg_cache_block_error_plot_town_members: '城镇居民'
msg_err_invalid_nation_map_color: '&c未知的地图颜色. 可用颜色有%s.'
msg_nation_map_color_changed: '&b国家地图颜色已更改为%s.'
-msg_err_unable_to_add_more_residents_without_nation: '在第一次加入其他国家或建国前,你的城镇无法邀请多于%s位居民。'
+msg_err_unable_to_add_more_residents_without_nation: '在加入其他国家或建国前,你的城镇无法邀请多于%s位居民。'
msg_the_following_towns_were_deleted_for_having_0_claims: '城镇%s已被删除,因为这些城镇没有声明任何土地。'
msg_spawn_warn: '传送价格为%s. 你确认继续传送? 提示: 加上 -ignore 跳过确认传送.'
msg_confirm_purchase: '这样做将消耗%s. 你确认?'
@@ -1439,7 +1439,7 @@ msg_err_outlawed_players_no_teleport: '&4你被你所在的城镇列为被放逐
msg_err_you_cannot_use_command_while_in_outlaw_town: '&4你不能在把你列为被放逐者的城镇里使用此命令。'
#Added in 0.110
msg_safe_mode: "[Error] 已锁定安全模式!"
-msg_safe_mode_base: '[Error] Towny因产生了一个错误而被锁定于安全模式下!'
+msg_safe_mode_base: '[Error] 由于错误,Towny被锁定在安全模式下! '
msg_safe_mode_player: '告诉管理员去检查服务器后台。'
msg_safe_mode_admin: '查看服务器后台以获取详细信息。'
msg_err_you_can_only_claim_outposts_in_your_homeblocks_world: '你只能在中心区块所在的世界里声明前哨。'
@@ -1645,31 +1645,31 @@ msg_jailed_outlaw: '作为被放逐者杀死。'
#Jail causes
msg_jailed_war: '作为战俘监禁。'
#Jail handbook messages
-msg_jailed_handbook_1: '看起来你因为%s而被监禁了。'
+msg_jailed_handbook_1: '看起来你因%s而被监禁。'
#Jail handbook messages
-msg_jailed_handbook_2: '啊……太糟糕了。但是你能怎么办?这有一些被监禁时的小贴士,读一读吧,这或许可以帮你。'
+msg_jailed_handbook_2: '很遗憾,但你该当如何?这些小贴士或许有用,看一看吧。'
#Jail handbook messages
-msg_jailed_handbook_3: '你已经被监禁%s小时了,服刑后你将得到自由。'
+msg_jailed_handbook_3: '你被监禁了%s小时,服刑后你将自由。'
#Jail handbook messages
-msg_jailed_handbook_4_can: '你可以通过使用“/town leave”离开城镇来逃离监狱。'
+msg_jailed_handbook_4_can: '你可使用“/town leave”离开城镇来逃离监狱。'
#Jail handbook messages
-msg_jailed_handbook_4_cant: '监禁期间你不能通过离开城镇来逃离城镇。'
+msg_jailed_handbook_4_cant: '监禁期间你不能靠离开城镇来越狱。'
#Jail handbook messages
-msg_jailed_handbook_bail_1: '你可以使用“/res jail paybail”缴纳保释金来离开监狱。'
+msg_jailed_handbook_bail_1: '你可以使用“/res jail paybail”缴纳保释金来获释。'
#Jail handbook messages
msg_jailed_handbook_bail_2: '保释费用为%s。'
#Jail handbook messages
-msg_jailed_handbook_5: '如果你坚持逃离到了城镇外的野地,你将获得自由。'
+msg_jailed_handbook_5: '若你坚持逃离到达野地,你将获得自由。'
#Jail handbook messages
msg_jailed_handbook_6: '但是在到达野地之前不要死亡,否则你将被送回监狱。'
#Jail handbook messages
-msg_jailed_teleport: '但幸运的是——如果你有末影珍珠或是紫颂果,那么你可以使用它们来帮助你越狱。'
+msg_jailed_teleport: '幸运的是,你可以用末影珍珠或紫颂果来帮助你越狱,现在你只需弄到一些。'
#Jail handbook messages
msg_jailed_war_prisoner: '作为战俘,如果你的国家攻陷了监狱(HP降为0)或城镇退出了战争,你将获得自由。'
#Jail handbook title
msg_jailed_title: '所以,你被监禁了:('
#Jail handbook author
-msg_jailed_author: 'Towny Jailco。'
+msg_jailed_author: 'Towny Jailco.'
#Added in 0.130
#Message shown when there are no allies to list in /town allylist.
msg_error_town_has_no_allies: '此城镇没有同盟。'
@@ -2025,7 +2025,7 @@ msg_err_cannot_claim_the_following_worldcoords_because_of_ocean_biome: "以下
msg_err_cannot_begin_town_in_this_biome: "你不能在这个生物群落中创建一个城镇"
msg_err_cannot_overclaim_this_town_because_they_arent_your_enemy: "你不能领地掠夺这个城镇,因为你的国家不认为对方是一个敌人"
msg_err_unable_to_command_outside_of_town: '你不能在你的城镇之外使用这个指令'
-msg_err_unable_to_use_bank_outside_bank_plot_no_homeblock: '您不能在银行区块之外使用该命令'
+msg_err_unable_to_use_bank_outside_bank_plot_no_homeblock: '您不能在银行(Bank)区块之外使用此命令。'
msg_err_you_cannot_outlaw_your_mayor: "你不能放逐你的镇长"
msg_err_you_cannot_outlaw_because_of_rank: "你不能放逐%s, 因为它持有一些城镇头衔"
status_nation_sanctioned_towns: "受制裁的城镇"
@@ -2043,8 +2043,8 @@ msg_err_name_validation_contains_numbers: "%s包含数字,而数字不允许
msg_err_name_validation_used_in_command_structure: "%s 在指令结构中被使用,所以你不能用它作为名称"
msg_town_being_deleted_because_no_residents: "%s 将要被删除,因为它的最后一个居民也离开了"
outlawed_in: "放逐于"
-msg_warning_town_deposit_hint: "如果要把钱存入城镇银行,请使用/town deposit [amount]"
-msg_warning_nation_deposit_hint: "若要将钱放入您的国家银行,请使用/nation deposit [amount]。"
+msg_warning_town_deposit_hint: "使用/town deposit [amount]把钱存入城镇银行。"
+msg_warning_nation_deposit_hint: "使用/nation deposit [amount]把钱存入国家银行。"
teleport_warmup_title_dont_move: ""
teleport_warmup_subtitle_seconds_remaining: "&7离开始传送还有&c%s&7秒。"
msg_ruined_town_plot_permissions_allowed_on_x_plots: "因为你的城镇已经被毁, %s 区块许可线已经改变,故不再提供对城镇的任何保护。"
@@ -2053,8 +2053,20 @@ msg_err_town_cede_you_cannot_cede_a_plot_to_your_own_town: "你不能把一块
msg_err_town_cede_you_cannot_cede_your_homeblock: "你不能割让你城镇的home区块。"
msg_err_town_cede_the_mayor_is_not_online: "%s的市长%s不在线,因此无法接受您的地皮。"
msg_err_town_no_longer_owns_this_plot: "%s不再拥有此区块。"
+msg_err_town_cede_town_cannot_cede_their_homeblock: "%s不能割让他们的Home区块。"
msg_town_cede_plot_confirmation_give_plot: "你确定你要把这个区块给%s吗?"
msg_town_cede_plot_confirmation_accept_plot: "%s想要将在%s的区块割让给你的城镇。你接受吗?"
msg_town_cede_plot_accepted: "%s已接受你所割让的区块。"
+msg_town_cede_plot_denied: "%s 拒绝了您的报价。"
+msg_town_cede_plot_unable_to_accept: "%s 无法接受您的报价。"
+msg_town_cede_plot_you_have_accepted: "你已经在 %s 获得了对地皮的控制。"
+msg_err_cannot_claim_plot_join_date_too_low: "你不能拥有这块地皮,直到你已经成为一个城镇居民了 %s 天。"
+msg_err_cannot_claim_plot_join_date_too_high: "你不能领取这块地皮,它是给城镇成员少于 %s 天的居民。"
+msg_townblock_min_join_days_removed: "此 TownBlock 已经删除了它的最小加入日要求。"
+msg_townblock_max_join_days_removed: "此 TownBlock 已经删除了其最大加入日要求。"
+msg_townblock_min_join_days_set_to: "此 TownBlock 已将其最小加入日要求设置为 %s。 只有加入的玩家超过了这个天数,才能使用 /绘图认领。"
+msg_townblock_max_join_days_set_to: "此 TownBlock 已将其最大加入日要求设置为 %s。 只有加入的玩家少于这个天数,才能使用 /绘图认领。"
+msg_new_resident_spawn_to_town_prompt: "你想传送到你刚刚加入的城镇吗?"
+msg_recieved_refund_for_deleted_object: "您收到了您已删除的城镇或民族的银行余额,金额为 %s。"
msg_err_you_already_own_this_plot: "你已经拥有这个区块。"
msg_err_you_cannot_delete_this_nation: "您已被阻止删除这个国家。"