Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,8 @@ public static NationLevel getNationLevel(int levelNumber) {
}

public static NationLevel getNationLevel(Nation nation) {
return getNationLevel(nation.getLevelNumber());
int numResidents = getResidentCountForNationLevel(nation.getLevelNumber());
return getNationLevel(numResidents);
}

public static NationLevel getNationLevelWithModifier(int modifier) {
Expand All @@ -435,6 +436,21 @@ public static int getNationLevelFromGivenInt(int threshold) {
return 0;
}

/**
* Gets the number of residents required to look up the NationLevel in the SortedMap.
* @param level The number used to get the key from the keySet array.
* @return the number of residents which will get us the correct TownLevel in the NationLevel SortedMap.
*/
public static int getResidentCountForNationLevel(int level) {
Integer[] keys = configNationLevel.keySet().toArray(new Integer[] {});
// keys is always ordered from biggest to lowest (despite what the javadocs say
// about being sorted in Ascending order, this is not the case for a SortedMap.)
// We have to get it from lowest to largest.
Arrays.sort(keys);
level = Math.min(level, keys.length);
return keys[level];
}

public static int getNationLevelMax() {
return configNationLevel.size();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ public class TownyAdminCommand extends BaseCommand implements CommandExecutor {
"merge",
"transfer",
"forcemerge",
"recheck"
"recheck",
"setnationlevel"
);
private static final List<String> adminNationSetTabCompletes = Stream.concat(NationCommand.nationSetTabCompletes.stream(),
Stream.of("foundingdate")).collect(Collectors.toList());
Expand Down Expand Up @@ -587,6 +588,10 @@ else if (args.length == 6)
.map(Town::getName)
.collect(Collectors.toList()), args[4]);
break;
case "setnationlevel":
if (args.length == 4)
return NameUtil.filterByStart(StringMgmt.addToList(numbers, "unset"), args[3]);
break;
case "enemy":
case "ally":
if (args.length == 4)
Expand Down Expand Up @@ -1917,6 +1922,10 @@ public void parseAdminNationCommand(CommandSender sender, String[] split) throws
checkPermOrThrow(sender, PermissionNodes.TOWNY_COMMAND_TOWNYADMIN_NATION_ENEMY.getNode());
parseAdminNationEnemyCommand(sender, StringMgmt.remArgs(split, 2), nation);
break;
case "setnationlevel":
checkPermOrThrow(sender, PermissionNodes.TOWNY_COMMAND_TOWNYADMIN_NATION_SETNATIONLEVEL.getNode());
setNationLevel(sender, nation, StringMgmt.remArgs(split, 2));
break;
default:
if (TownyCommandAddonAPI.hasCommand(CommandType.TOWNYADMIN_NATION, split[1])) {
TownyCommandAddonAPI.getAddonCommand(CommandType.TOWNYADMIN_NATION, split[1]).execute(sender, split, nation);
Expand All @@ -1926,6 +1935,28 @@ public void parseAdminNationCommand(CommandSender sender, String[] split) throws
}
}

private void setNationLevel(CommandSender sender, Nation nation, String[] split) throws TownyException {
// The number is missing.
if (split.length == 0)
throw new TownyException("Eg: /townyadmin nation [nationname] setnationlevel 2");

// Handle un-setting the manual override.
if (split[0].equalsIgnoreCase("unset")) {
nation.setManualNationLevel(-1);
nation.save();
TownyMessaging.sendMsg(sender, Translatable.of("msg_nation_level_unset", nation, nation.getLevelNumber()));
return;
}

// Handle applying a manual override.
int level = MathUtil.getPositiveIntOrThrow(split[0]);
if (level > TownySettings.getNationLevelMax() - 1)
level = TownySettings.getNationLevelMax() - 1;
nation.setManualNationLevel(level);
nation.save();
TownyMessaging.sendMsg(sender, Translatable.of("msg_nation_level_overridden_with", nation, level));
}

private void parseAdminNewNationCommand(CommandSender sender, String[] split) throws TownyException {
if (split.length != 3)
throw new TownyException(Translatable.of("msg_err_not_enough_variables") + "/ta nation new [name] [capital]");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ private static List<ColumnData> getNationColumns(){
columns.add(new ColumnData("conqueredTax", "float NOT NULL"));
columns.add(new ColumnData("sanctionedTowns", "mediumtext DEFAULT NULL"));
columns.add(new ColumnData("hasActiveWar", "bool NOT NULL DEFAULT '0'"));
columns.add(new ColumnData("manualNationLevel", "BIGINT DEFAULT '-1'"));
return columns;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1297,6 +1297,10 @@ public boolean loadNation(Nation nation) {
if (line != null)
nation.setActiveWar(Boolean.parseBoolean(line));

line = keys.get("manualNationLevel");
if (line != null)
nation.setManualNationLevel(Integer.parseInt(line));

} catch (Exception e) {
plugin.getLogger().log(Level.WARNING, Translation.of("flatfile_err_reading_nation_file_at_line", nation.getName(), line, nation.getName()), e);
return false;
Expand Down Expand Up @@ -2365,6 +2369,8 @@ public boolean saveNation(Nation nation) {
list.add("sanctionedTowns=" + StringMgmt.join(nation.getSanctionedTownsForSaving(), "#"));
// Active War
list.add("hasActiveWar=" + nation.hasActiveWar());

list.add("manualNationLevel=" + nation.getManualNationLevel());
/*
* Make sure we only save in async
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1385,6 +1385,9 @@ private boolean loadNation(ResultSet rs) {
if (line != null && !line.isEmpty())
nation.setActiveWar(rs.getBoolean("hasActiveWar"));


nation.setManualNationLevel(rs.getInt("manualNationLevel"));

return true;
} catch (SQLException e) {
TownyMessaging.sendErrorMsg("SQL: Load Nation " + name + " SQL Error - " + e.getMessage());
Expand Down Expand Up @@ -2497,6 +2500,7 @@ public synchronized boolean saveNation(Nation nation) {
nat_hm.put("maxPercentTaxAmount", nation.getMaxPercentTaxAmount());
nat_hm.put("spawnCost", nation.getSpawnCost());
nat_hm.put("neutral", nation.isNeutral());
nat_hm.put("manualNationLevel", nation.getManualNationLevel());

final Position spawnPos = nation.spawnPosition();
nat_hm.put("nationSpawn", spawnPos != null ? String.join("#", spawnPos.serialize()) : "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public class Nation extends Government {
private boolean isTaxPercentage = TownySettings.getNationDefaultTaxPercentage();
private double maxPercentTaxAmount = TownySettings.getMaxNationTaxPercentAmount();
private double conqueredTax = TownySettings.getDefaultNationConqueredTaxAmount();
private int manualNationLevel = -1;

@ApiStatus.Internal
public Nation(String name, UUID uuid) {
Expand Down Expand Up @@ -649,7 +650,10 @@ public NationLevel getNationLevel() {
*/
public int getLevelNumber() {
int modifier = TownySettings.isNationLevelDeterminedByTownCount() ? getNumTowns() : getNumResidents();
int nationLevelNumber = TownySettings.getNationLevelFromGivenInt(modifier);
int nationLevelNumber = getManualNationLevel() > -1
? Math.min(getManualNationLevel(), TownySettings.getNationLevelMax())
: TownySettings.getNationLevelFromGivenInt(modifier);

NationCalculateNationLevelNumberEvent ncnle = new NationCalculateNationLevelNumberEvent(this, nationLevelNumber);
BukkitTools.fireEvent(ncnle);
return ncnle.getNationLevelNumber();
Expand Down Expand Up @@ -713,4 +717,11 @@ public void loadSanctionedTowns(String[] tokens) {
}


public int getManualNationLevel() {
return manualNationLevel;
}

public void setManualNationLevel(int manualNationLevel) {
this.manualNationLevel = manualNationLevel;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ public enum PermissionNodes {
TOWNY_COMMAND_TOWNYADMIN_NATION_BANKHISTORY("towny.command.townyadmin.nation.bankhistory"),
TOWNY_COMMAND_TOWNYADMIN_NATION_ENEMY("towny.command.townyadmin.nation.enemy"),
TOWNY_COMMAND_TOWNYADMIN_NATION_ALLY("towny.command.townyadmin.nation.ally"),
TOWNY_COMMAND_TOWNYADMIN_NATION_SETNATIONLEVEL("towny.command.townyadmin.nation.setnationlevel"),

TOWNY_COMMAND_TOWNYADMIN_TOGGLE("towny.command.townyadmin.toggle.*"),
TOWNY_COMMAND_TOWNYADMIN_TOGGLE_DEVMODE("towny.command.townyadmin.toggle.devmode"),
Expand Down
5 changes: 4 additions & 1 deletion Towny/src/main/resources/lang/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2689,4 +2689,7 @@ msg_nearby_town_nation: ' <aqua>[%s]'
msg_err_must_specify_days_to_be_conquered: "You must specify a number of days to be conquered for, ie: 1 or more, or -1 or unlimited for an indefinite conquering."
msg_conquered_status_granted: "You have set %s to have the conquered status for %s days."
msg_conquered_status_granted_unlimited: "You have set %s to have the conquered status for an indefinite amount of days."
msg_err_must_specify_on_or_off: "You must specify on or off."
msg_err_must_specify_on_or_off: "You must specify on or off."

msg_nation_level_overridden_with: 'The nation %s has had their nationlevel set to %s.'
msg_nation_level_unset: 'The nation %s has had their manually-set nationlevel unset. Current nationlevel is %s.'