diff --git a/resources/lang/en-US.yml b/resources/lang/en-US.yml index b4a51f0042..da70f9624e 100644 --- a/resources/lang/en-US.yml +++ b/resources/lang/en-US.yml @@ -1781,4 +1781,11 @@ msg_x_has_been_withdrawn_for_upkeep_of_prisoner_x: '%s withdrawn from Town bank msg_x_has_been_withdrawn_for_jailing_of_prisoner_x: '%s withdrawn from Town bank to pay for jailing of %s.' #Message shown in the confirmation for /ta resetbanks {amount}. -confirmation_are_you_sure_you_want_to_reset_all_banks: 'Are you sure you want to reset all town and nation banks to %s?' \ No newline at end of file +confirmation_are_you_sure_you_want_to_reset_all_banks: 'Are you sure you want to reset all town and nation banks to %s?' + +#Message shown when a nation cannot add a town because of the max-residents-limit. +msg_err_cannot_add_nation_over_resident_limit: '&cYour nation has reached the maximum number of allowed residents-per-nation, %s, and cannot add %s.' +#Message shown to a town when they cannot join a nation because of the max-residents-limit. +msg_err_cannot_join_nation_over_resident_limit: '&cYou cannot join this nation as it would be over the residents-per-nation limit of %s.' +#Message shown to a town because the nation has hit their max-towns-limit. +msg_err_cannot_join_nation_over_town_limit: '&cYou cannot join this nation, it has reached the maximum number of allowed towns-per-nation: %s.' \ No newline at end of file diff --git a/src/com/palmergames/bukkit/config/ConfigNodes.java b/src/com/palmergames/bukkit/config/ConfigNodes.java index ec13bfdbb4..6a1a4f057b 100644 --- a/src/com/palmergames/bukkit/config/ConfigNodes.java +++ b/src/com/palmergames/bukkit/config/ConfigNodes.java @@ -1099,6 +1099,13 @@ public enum ConfigNodes { "", "# If higher than 0, it will limit how many towns can be joined into a nation.", "# Does not affect existing nations that are already over the limit."), + GNATION_SETTINGS_MAX_RESIDENTS_PER_NATION( + "global_nation_settings.max_residents_per_nation", + "0", + "", + "# If higher than 0, it will limit how many residents can join a nation.", + "# Does not affect existing nations that are already over the limit." + ), GNATION_SETTINGS_ALLOWED_NATION_COLORS( "global_nation_settings.allowed_map_colors", "aqua:00ffff, azure:f0ffff, beige:f5f5dc, black:000000, blue:0000ff, brown:a52a2a, cyan:00ffff, darkblue:00008b, darkcyan:008b8b, darkgrey:a9a9a9, darkgreen:006400, darkkhaki:bdb76b, darkmagenta:8b008b, darkolivegreen:556b2f, darkorange:ff8c00, darkorchid:9932cc, darkred:8b0000, darksalmon:e9967a, darkviolet:9400d3, fuchsia:ff00ff, gold:ffd700, green:008000, indigo:4b0082, khaki:f0e68c, lightblue:add8e6, lightcyan:e0ffff, lightgreen:90ee90, lightgrey:d3d3d3, lightpink:ffb6c1, lightyellow:ffffe0, lime:00ff00, magenta:ff00ff, maroon:800000, navy:000080, olive:808000, orange:ffa500, pink:ffc0cb, purple:800080, violet:800080, red:ff0000, silver:c0c0c0, white:ffffff, yellow:ffff00", diff --git a/src/com/palmergames/bukkit/towny/TownySettings.java b/src/com/palmergames/bukkit/towny/TownySettings.java index d46988f871..ca7a782892 100644 --- a/src/com/palmergames/bukkit/towny/TownySettings.java +++ b/src/com/palmergames/bukkit/towny/TownySettings.java @@ -2876,6 +2876,10 @@ public static boolean isNationSpawnOnlyAllowedInCapital() { public static int getMaxTownsPerNation() { return getInt(ConfigNodes.GNATION_SETTINGS_MAX_TOWNS_PER_NATION); } + + public static int getMaxResidentsPerNation() { + return getInt(ConfigNodes.GNATION_SETTINGS_MAX_RESIDENTS_PER_NATION); + } public static double getSpawnTravelCost() { return getDouble(ConfigNodes.ECO_PRICE_TOWN_SPAWN_TRAVEL_PUBLIC); diff --git a/src/com/palmergames/bukkit/towny/command/NationCommand.java b/src/com/palmergames/bukkit/towny/command/NationCommand.java index da39fe6f8d..8a6613db17 100644 --- a/src/com/palmergames/bukkit/towny/command/NationCommand.java +++ b/src/com/palmergames/bukkit/towny/command/NationCommand.java @@ -662,12 +662,14 @@ private void parseNationJoin(Player player, String[] args) { if (!nation.isOpen()) throw new TownyException(Translatable.of("msg_err_nation_not_open", nation.getFormattedName())); - if ((TownySettings.getNumResidentsJoinNation() > 0) && (town.getNumResidents() < TownySettings.getNumResidentsJoinNation())) + if (!testTownHasEnoughResidents(town)) throw new TownyException(Translatable.of("msg_err_not_enough_residents_join_nation", town.getName())); - if (TownySettings.getMaxTownsPerNation() > 0) - if (nation.getTowns().size() >= TownySettings.getMaxTownsPerNation()) - throw new TownyException(Translatable.of("msg_err_nation_over_town_limit", TownySettings.getMaxTownsPerNation())); + if (!testNationMaxTowns(nation)) + throw new TownyException(Translatable.of("msg_err_nation_over_town_limit", TownySettings.getMaxTownsPerNation())); + + if (!testNationMaxResidents(nation, town)) + throw new TownyException(Translatable.of("msg_err_cannot_add_nation_over_resident_limit", TownySettings.getMaxResidentsPerNation())); if (TownySettings.getNationRequiresProximity() > 0) { Coord capitalCoord = nation.getCapital().getHomeBlock().getCoord(); @@ -1189,7 +1191,7 @@ public void nationAdd(Player player, String[] names) throws TownyException { Nation nation = getNationFromPlayerOrThrow(player); - if (TownySettings.getMaxTownsPerNation() > 0 && nation.getTowns().size() >= TownySettings.getMaxTownsPerNation()) + if (testNationMaxTowns(nation)) throw new TownyException(Translatable.of("msg_err_nation_over_town_limit", TownySettings.getMaxTownsPerNation())); // The list of valid invites. @@ -1203,11 +1205,28 @@ public void nationAdd(Player player, String[] names) throws TownyException { continue; } - if (nation.hasTown(townname)) { + Town town = null; + try { + town = getTownOrThrow(townname); + } catch (NotRegisteredException e) { + // The Town doesn't actually exist or was mis-spelled. + removeinvites.add(townname); + continue; + } + + if (nation.hasTown(town) || town.hasNation()) { // Town is already part of the nation. removeinvites.add(townname); continue; } + + if (testNationMaxResidents(nation, town)) { + // Town has too many residents to join the nation + removeinvites.add(townname); + TownyMessaging.sendErrorMsg(player, Translatable.of("msg_err_cannot_join_nation_over_resident_limit", TownySettings.getMaxResidentsPerNation(), townname)); + continue; + } + // add them to adding. newtownlist.add(townname); } @@ -1247,7 +1266,7 @@ public static void nationAdd(Player player, Nation nation, List invited) t continue; } - if (TownySettings.getNumResidentsJoinNation() > 0 && town.getNumResidents() < TownySettings.getNumResidentsJoinNation()) { + if (!testTownHasEnoughResidents(town)) { remove.add(town); TownyMessaging.sendErrorMsg(player, Translatable.of("msg_err_not_enough_residents_join_nation", town.getName())); continue; @@ -1305,6 +1324,27 @@ public static void nationAdd(Player player, Nation nation, List invited) t public static void nationAdd(Nation nation, List towns) throws AlreadyRegisteredException { for (Town town : towns) { if (!town.hasNation()) { + if (!testNationMaxTowns(nation)) { + // Nation has hit the max-towns limit. + TownyMessaging.sendPrefixedNationMessage(nation, Translatable.of("msg_err_nation_over_town_limit", TownySettings.getMaxTownsPerNation())); + TownyMessaging.sendPrefixedTownMessage(town, Translatable.of("msg_err_cannot_join_nation_over_town_limit", TownySettings.getMaxTownsPerNation())); + continue; + } + + if (!testTownHasEnoughResidents(town)) { + // Town has dropped below min.-residents-to-join-nation limit. + TownyMessaging.sendPrefixedNationMessage(nation, Translatable.of("msg_err_not_enough_residents_join_nation", town.getName())); + TownyMessaging.sendPrefixedTownMessage(town, Translatable.of("msg_err_not_enough_residents_join_nation", town.getName())); + continue; + } + + if (!testNationMaxResidents(nation, town)) { + // Nation has hit the max-residents limit. + TownyMessaging.sendPrefixedNationMessage(nation, Translatable.of("msg_err_cannot_add_nation_over_resident_limit", TownySettings.getMaxResidentsPerNation(), town.getName())); + TownyMessaging.sendPrefixedTownMessage(town, Translatable.of("msg_err_cannot_join_nation_over_resident_limit", TownySettings.getMaxResidentsPerNation())); + continue; + } + town.setNation(nation); town.save(); TownyMessaging.sendPrefixedNationMessage(nation, Translatable.of("msg_join_nation", town.getName())); @@ -1316,6 +1356,22 @@ public static void nationAdd(Nation nation, List towns) throws AlreadyRegi } + private static boolean testNationMaxResidents(Nation nation, Town town) { + int maxResidentPerNation = TownySettings.getMaxResidentsPerNation(); + if (maxResidentPerNation < 1) + return true; + return nation.getResidents().size() + town.getResidents().size() > maxResidentPerNation; + + } + + private static boolean testTownHasEnoughResidents(Town town) { + return TownySettings.getNumResidentsJoinNation() > 0 && town.getNumResidents() < TownySettings.getNumResidentsJoinNation(); + } + + private static boolean testNationMaxTowns(Nation nation) { + return TownySettings.getMaxTownsPerNation() > 0 && nation.getTowns().size() >= TownySettings.getMaxTownsPerNation(); + } + private static void nationRevokeInviteTown(CommandSender sender, Nation nation, List towns) { for (Town town : towns) {