diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/TownyFormatter.java b/Towny/src/main/java/com/palmergames/bukkit/towny/TownyFormatter.java index 68d004cdb9a..2b3a2dfa005 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/TownyFormatter.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/TownyFormatter.java @@ -113,6 +113,9 @@ public static StatusScreen getStatus(TownBlock townBlock, Player player) { if (townBlock.hasDistrict()) screen.addComponentOf("district", colourKey(translator.of("status_district_name_and_size", townBlock.getDistrict().getName(), townBlock.getDistrict().getTownBlocks().size()))); + if (townBlock.hasOutpostObject()) + screen.addComponentOf("outpost", colourKey(translator.of("status_outpost_name_and_size", townBlock.getOutpost().getName(), townBlock.getOutpost().getNumTownBlocks()))); + if (townBlock.hasPlotObjectGroup()) screen.addComponentOf("plotgroup", colourKey(translator.of("status_plot_group_name_and_size", townBlock.getPlotObjectGroup().getName(), townBlock.getPlotObjectGroup().getTownBlocks().size()))); diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/TownyMessaging.java b/Towny/src/main/java/com/palmergames/bukkit/towny/TownyMessaging.java index 043c1188cbb..aa4cdf7b2d6 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/TownyMessaging.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/TownyMessaging.java @@ -3,6 +3,7 @@ import com.palmergames.bukkit.towny.confirmations.Confirmation; import com.palmergames.bukkit.towny.invites.Invite; import com.palmergames.bukkit.towny.object.Nation; +import com.palmergames.bukkit.towny.object.Outpost; import com.palmergames.bukkit.towny.object.PlotGroup; import com.palmergames.bukkit.towny.object.Resident; import com.palmergames.bukkit.towny.object.Town; @@ -26,7 +27,6 @@ import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; import org.bukkit.ChatColor; -import org.bukkit.Location; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; import org.bukkit.entity.Player; @@ -588,7 +588,7 @@ public static void sendOutpostList(Player player, Town town, int page, int total Translator translator = Translator.locale(player); int outpostsCount = town.getAllOutpostSpawns().size(); int iMax = Math.min(page * 10, outpostsCount); - List outposts = town.getAllOutpostSpawns(); + List outpostObjects = town.getOutposts(); TextComponent[] outpostsFormatted; @@ -599,19 +599,19 @@ public static void sendOutpostList(Player player, Town town, int page, int total } for (int i = (page - 1) * 10; i < iMax; i++) { - Location outpost = outposts.get(i); - TownBlock tb = TownyAPI.getInstance().getTownBlock(outpost); - if (tb == null) + Outpost outpost = outpostObjects.get(i); + TownBlock tb = outpost.getSpawnTownBlock(); + if (outpost.getSpawn() == null || tb == null) continue; - String name = !tb.hasPlotObjectGroup() ? tb.getName() : tb.getPlotObjectGroup().getName(); + String name = outpost.getName(); TextComponent dash = Component.text(" - ", NamedTextColor.DARK_GRAY); TextComponent line = Component.text(Integer.toString(i + 1), NamedTextColor.GOLD) .clickEvent(ClickEvent.runCommand("/towny:town outpost " + (i + 1))) .append(dash); TextComponent outpostName = Component.text(name, NamedTextColor.GREEN); - TextComponent worldName = Component.text(Optional.ofNullable(outpost.getWorld()).map(w -> w.getName()).orElse("null"), NamedTextColor.BLUE); - TextComponent coords = Component.text("(" + outpost.getBlockX() + "," + outpost.getBlockZ()+ ")", NamedTextColor.BLUE); + TextComponent worldName = Component.text(Optional.ofNullable(outpost.getSpawn().world()).map(w -> w.getName()).orElse("null"), NamedTextColor.BLUE); + TextComponent coords = Component.text("(" + outpost.getSpawn().blockX() + "," + outpost.getSpawn().blockZ()+ ")", NamedTextColor.BLUE); if (!name.equalsIgnoreCase("")) { line = line.append(outpostName).append(dash); diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/command/PlotCommand.java b/Towny/src/main/java/com/palmergames/bukkit/towny/command/PlotCommand.java index 1bca505abfd..833b14beed3 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/command/PlotCommand.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/command/PlotCommand.java @@ -40,8 +40,10 @@ import com.palmergames.bukkit.towny.huds.HUDManager; import com.palmergames.bukkit.towny.object.Coord; import com.palmergames.bukkit.towny.object.District; +import com.palmergames.bukkit.towny.object.Outpost; import com.palmergames.bukkit.towny.object.PermissionData; import com.palmergames.bukkit.towny.object.PlotGroup; +import com.palmergames.bukkit.towny.object.Position; import com.palmergames.bukkit.towny.object.Resident; import com.palmergames.bukkit.towny.object.SpawnPointLocation; import com.palmergames.bukkit.towny.object.Town; @@ -735,7 +737,9 @@ public void parsePlotSetOutpost(Player player, Resident resident, TownBlock town if (!townBlock.isOutpost()) throw new TownyException(Translatable.of("msg_err_location_is_not_within_an_outpost_plot")); - town.addOutpostSpawn(player.getLocation()); + Outpost outpost = townBlock.getOutpost(); + outpost.setSpawn(Position.ofLocation(player.getLocation())); + outpost.save(); TownyMessaging.sendMsg(player, Translatable.of("msg_set_outpost_spawn")); return; } @@ -743,6 +747,9 @@ public void parsePlotSetOutpost(Player player, Resident resident, TownBlock town TownyWorld townyWorld = townBlock.getWorld(); Coord key = Coord.parseCoord(player.getLocation()); + if (townBlock.hasOutpostObject()) + throw new TownyException("msg_err_plot_already_part_of_outpost_group"); + // Throws a TownyException with message if outpost should not be set. OutpostUtil.OutpostTests(town, resident, townyWorld, key, resident.isAdmin(), true); diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/command/TownCommand.java b/Towny/src/main/java/com/palmergames/bukkit/towny/command/TownCommand.java index c560d80e344..187301cdeab 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/command/TownCommand.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/command/TownCommand.java @@ -3485,12 +3485,12 @@ private static void vetTownAllowedTheseClaims(Town town, boolean outpost, List outpostOptional = selection.get(0).getCardinallyAdjacentWorldCoords(false).stream() - .filter(wc -> wc.hasTownBlock() && wc.getTownBlockOrNull().hasOutpost()) + .filter(wc -> wc.hasTownBlock() && wc.getTownBlockOrNull().hasOutpostObject()) .map(wc -> wc.getTownBlockOrNull().getOutpost()) .findFirst(); if (outpostOptional.isPresent()) { Outpost outpostObject = outpostOptional.get(); - if (outpostObject.getNumTownBlock() > town.getMaxAllowedOutpostLandmass()) + if (outpostObject.getNumTownBlocks() > town.getMaxAllowedOutpostLandmass()) throw new TownyException("Your town is unable to make an outpost this large."); } } diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownyDataSource.java b/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownyDataSource.java index 7dca33dabfd..9f550451ca9 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownyDataSource.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownyDataSource.java @@ -56,7 +56,7 @@ public abstract class TownyDataSource { public boolean loadAll() { - return loadWorldList() && loadNationList() && loadTownList() && loadPlotGroupList() && loadDistrictList() && loadOutpostList() && loadJailList() && loadResidentList() && loadTownBlockList() && loadWorlds() && loadResidents() && loadTowns() && loadNations() && loadTownBlocks() && loadPlotGroups() && loadDistricts() && loadOutposts() && loadJails() && loadRegenList() && loadCooldowns(); + return loadWorldList() && loadNationList() && loadTownList() && loadPlotGroupList() && loadDistrictList() && loadOutpostList() && loadJailList() && loadResidentList() && loadTownBlockList() && loadWorlds() && loadResidents() && loadTowns() && loadNations() && loadOutposts() && loadTownBlocks() && loadPlotGroups() && loadDistricts() && loadJails() && loadRegenList() && loadCooldowns(); } public boolean saveAll() { 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 bbbc0b09dd9..57772edd9bc 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 @@ -88,6 +88,8 @@ public TownyFlatFileSource(Towny plugin, TownyUniverse universe) { dataFolderPath + File.separator + "plotgroups" + File.separator + "deleted", dataFolderPath + File.separator + "districts", dataFolderPath + File.separator + "districts" + File.separator + "deleted", + dataFolderPath + File.separator + "outposts", + dataFolderPath + File.separator + "outposts" + File.separator + "deleted", dataFolderPath + File.separator + "jails", dataFolderPath + File.separator + "jails" + File.separator + "deleted" )) { @@ -1755,7 +1757,7 @@ public boolean loadOutpost(Outpost outpost) { line = keys.get("spawn"); if (line != null) { - String[] tokens = line.split(","); + String[] tokens = line.split("#"); if (tokens.length >= 4) try { outpost.setSpawn(Position.deserialize(tokens)); @@ -1941,10 +1943,12 @@ else if (universe.getReplacementNameMap().containsKey(line.trim())) { } if (outpostID != null) { - Outpost outpost= universe.getOutpost(outpostID); + Outpost outpost = universe.getOutpost(outpostID); if (outpost != null) { outpost.addTownblock(townBlock); townBlock.setOutpostObject(outpost); + if (outpost.getNumTownBlocks() <= 1) + townBlock.getTownOrNull().addOutpost(outpost); } else { townBlock.removeOutpost(); } @@ -2304,7 +2308,8 @@ public boolean saveOutpost(Outpost outpost) { try { list.add("outpostName=" + outpost.getName()); - list.add("spawn=" + String.join(",", outpost.getSpawn().serialize())); + if (outpost.getSpawn() != null) + list.add("spawn=" + String.join("#", outpost.getSpawn().serialize())); list.add("metadata=" + serializeMetadata(outpost)); } catch (Exception e) { plugin.getLogger().log(Level.WARNING, "An exception occurred while saving outpost " + Optional.ofNullable(outpost).map(g -> g.getUUID().toString()).orElse("null") + ": ", e); @@ -2609,7 +2614,7 @@ public boolean saveTownBlock(TownBlock townBlock) { list.add("districtID=" + districtID); // Outpost ID - if (townBlock.hasOutpost()) + if (townBlock.hasOutpostObject()) list.add("outpostID=" + townBlock.getOutpostUUID()); list.add("trustedResidents=" + StringMgmt.join(toUUIDList(townBlock.getTrustedResidents()), ",")); diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownySQLSource.java b/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownySQLSource.java index 7d5b13038a6..7f61b57142f 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownySQLSource.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownySQLSource.java @@ -2017,6 +2017,8 @@ public boolean loadTownBlocks() { if (outpost != null) { outpost.addTownblock(townBlock); townBlock.setOutpostObject(outpost); + if (outpost.getNumTownBlocks() <= 1) + townBlock.getTownOrNull().addOutpost(outpost); } } catch (Exception ignored) { } @@ -2820,7 +2822,7 @@ public synchronized boolean saveTownBlock(TownBlock townBlock) { tb_hm.put("districtID", townBlock.getDistrict().getUUID().toString()); else tb_hm.put("districtID", ""); - if (townBlock.hasOutpost()) + if (townBlock.hasOutpostObject()) tb_hm.put("outpostID", townBlock.getOutpostUUID().toString()); else tb_hm.put("outpostID", ""); diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/huds/PermHUD.java b/Towny/src/main/java/com/palmergames/bukkit/towny/huds/PermHUD.java index e1e76e729a4..a2a89829cd2 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/huds/PermHUD.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/huds/PermHUD.java @@ -39,6 +39,7 @@ public class PermHUD { private static final String HUD_OBJECTIVE = "PERM_HUD_OBJ"; private static final String TEAM_PERMS_TITLE = "permsTitle"; private static final String TEAM_DISTRICT_NAME = "districtName"; + private static final String TEAM_OUTPOST_NAME = "outpostName"; private static final String TEAM_PLOT_NAME = "plot_name"; private static final String TEAM_PLOT_COST = "plot_cost"; private static final String TEAM_BUILD = "build"; @@ -65,7 +66,7 @@ public static String permHudTestKey() { public static void updatePerms(Player p, WorldCoord worldCoord) { Translator translator = Translator.locale(p); - String districtName, plotName, build, destroy, switching, item, type, pvp, explosions, firespread, mobspawn, title; + String districtName, outpostName, plotName, build, destroy, switching, item, type, pvp, explosions, firespread, mobspawn, title; Scoreboard board = p.getScoreboard(); // Due to tick delay (probably not confirmed), a HUD can actually be removed from the player. // Causing board to return null, and since we don't create a new board, a NullPointerException occurs. @@ -94,8 +95,11 @@ public static void updatePerms(Player p, WorldCoord worldCoord) { title = GOLD + owner.getName() + (townBlock.hasResident() ? " (" + townBlock.getTownOrNull().getName() + ")" : ""); // District name - districtName = townBlock.hasDistrict() ? townBlock.getDistrict().getFormattedName() : ""; - + districtName = townBlock.hasDistrict() ? DARK_GREEN + "District: " + townBlock.getDistrict().getFormattedName() : ""; + + // Outpost name + outpostName = townBlock.hasOutpostObject() ? DARK_GREEN + "Outpost: " + townBlock.getOutpost().getFormattedName() : ""; + // Plot Type type = townBlock.getType().equals(TownBlockType.RESIDENTIAL) ? " " : townBlock.getType().getName(); @@ -125,6 +129,7 @@ public static void updatePerms(Player p, WorldCoord worldCoord) { // Set the values to our Scoreboard's teams. board.getObjective(HUD_OBJECTIVE).setDisplayName(HUDManager.check(title)); board.getTeam(TEAM_DISTRICT_NAME).setSuffix(districtName); + board.getTeam(TEAM_OUTPOST_NAME).setSuffix(outpostName); board.getTeam(TEAM_PLOT_NAME).setSuffix(plotName); board.getTeam(TEAM_PLOT_TYPE).setSuffix(type); board.getTeam(TEAM_PLOT_COST).setSuffix(forSale); @@ -170,6 +175,7 @@ private static void clearPerms (Player p) { try { board.getObjective(HUD_OBJECTIVE).setDisplayName(HUDManager.check(getFormattedWildernessName(p.getWorld()))); board.getTeam(TEAM_DISTRICT_NAME).setSuffix(" "); + board.getTeam(TEAM_OUTPOST_NAME).setSuffix(" "); board.getTeam(TEAM_PLOT_NAME).setSuffix(" "); board.getTeam(TEAM_PLOT_TYPE).setSuffix(" "); board.getTeam(TEAM_PLOT_COST).setSuffix(" "); @@ -212,7 +218,8 @@ public static void toggleOn (Player p) { private static void initializeScoreboard(Translator translator, Scoreboard board) { String PERM_HUD_TITLE = GOLD + ""; - String districtName_entry = ""; + String districtName_entry = GOLD + ""; + String outpostName_entry = GOLD + ""; String plotName_entry = ""; String keyPlotType_entry = DARK_GREEN + translator.of("msg_perm_hud_plot_type"); String forSale_entry = DARK_GREEN + translator.of("msg_perm_hud_plot_for_sale") + GRAY; @@ -241,6 +248,7 @@ private static void initializeScoreboard(Translator translator, Scoreboard board obj.setDisplayName(PERM_HUD_TITLE); //register teams Team districtName = board.registerNewTeam(TEAM_DISTRICT_NAME); + Team outpostName = board.registerNewTeam(TEAM_OUTPOST_NAME); Team plotName = board.registerNewTeam(TEAM_PLOT_NAME); Team keyPlotType = board.registerNewTeam(TEAM_PLOT_TYPE); Team forSaleTitle = board.registerNewTeam(TEAM_PLOT_COST); @@ -263,6 +271,7 @@ private static void initializeScoreboard(Translator translator, Scoreboard board //add each team as an entry (this sets the prefix to each line of the HUD.) districtName.addEntry(districtName_entry); + outpostName.addEntry(outpostName_entry); plotName.addEntry(plotName_entry); keyPlotType.addEntry(keyPlotType_entry); forSaleTitle.addEntry(forSale_entry); @@ -283,24 +292,26 @@ private static void initializeScoreboard(Translator translator, Scoreboard board keyFriend.addEntry(keyNation_entry); keyAlly.addEntry(keyAlly_entry); + int i = 18; //set scores for positioning - obj.getScore(districtName_entry).setScore(17); - obj.getScore(plotName_entry).setScore(16); - obj.getScore(keyPlotType_entry).setScore(15); - obj.getScore(forSale_entry).setScore(14); - obj.getScore(permsTitle_entry).setScore(13); - obj.getScore(build_entry).setScore(12); - obj.getScore(destroy_entry).setScore(11); - obj.getScore(switching_entry).setScore(10); - obj.getScore(item_entry).setScore(9); - obj.getScore(pvp_entry).setScore(8); - obj.getScore(explosions_entry).setScore(7); - obj.getScore(firespread_entry).setScore(6); - obj.getScore(mobspawn_entry).setScore(5); - obj.getScore(keyTitle_entry).setScore(4); - obj.getScore(keyResident_entry).setScore(3); - obj.getScore(keyNation_entry).setScore(2); - obj.getScore(keyAlly_entry).setScore(1); + obj.getScore(districtName_entry).setScore(i--); + obj.getScore(outpostName_entry).setScore(i--); + obj.getScore(plotName_entry).setScore(i--); + obj.getScore(keyPlotType_entry).setScore(i--); + obj.getScore(forSale_entry).setScore(i--); + obj.getScore(permsTitle_entry).setScore(i--); + obj.getScore(build_entry).setScore(i--); + obj.getScore(destroy_entry).setScore(i--); + obj.getScore(switching_entry).setScore(i--); + obj.getScore(item_entry).setScore(i--); + obj.getScore(pvp_entry).setScore(i--); + obj.getScore(explosions_entry).setScore(i--); + obj.getScore(firespread_entry).setScore(i--); + obj.getScore(mobspawn_entry).setScore(i--); + obj.getScore(keyTitle_entry).setScore(i--); + obj.getScore(keyResident_entry).setScore(i--); + obj.getScore(keyNation_entry).setScore(i--); + obj.getScore(keyAlly_entry).setScore(i--); } private static String prettyMoney(double price) { diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/listeners/TownyCustomListener.java b/Towny/src/main/java/com/palmergames/bukkit/towny/listeners/TownyCustomListener.java index bf0e57cb8fe..57551e9d3e8 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/listeners/TownyCustomListener.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/listeners/TownyCustomListener.java @@ -251,9 +251,9 @@ public void onTownClaim(TownClaimEvent event) { CellSurface.getCellSurface(event.getTownBlock().getWorldCoord()).runClaimingParticleOverSurfaceAtPlayer(event.getResident().getPlayer())); // Add the outpost object to the newly claimed townblock, if it is part of an outpost's landmass. - if (!event.getTownBlock().hasOutpost()) { + if (!event.getTownBlock().hasOutpostObject()) { Optional outpost = event.getTownBlock().getWorldCoord().getCardinallyAdjacentWorldCoords(false).stream() - .filter(wc -> wc.hasTownBlock() && wc.getTownBlockOrNull().hasOutpost()) + .filter(wc -> wc.hasTownBlock() && wc.getTownBlockOrNull().hasOutpostObject()) .map(wc -> wc.getTownBlockOrNull().getOutpost()) .findFirst(); if (outpost.isPresent()) diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/Outpost.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/Outpost.java index 8a20a16f259..3c09be21d23 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/object/Outpost.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/Outpost.java @@ -1,15 +1,18 @@ package com.palmergames.bukkit.towny.object; +import java.util.HashSet; import java.util.Set; import java.util.UUID; +import org.jetbrains.annotations.Nullable; + import com.palmergames.bukkit.towny.TownyUniverse; import com.palmergames.bukkit.towny.object.SpawnPoint.SpawnPointType; public class Outpost extends ObjectGroup { private Town town; private Position spawn; - private Set townblocks; + private Set townblocks = new HashSet<>(); public Outpost(UUID id, String name) { super(id, name); @@ -40,7 +43,7 @@ public Position getSpawn() { public void setSpawn(Position spawn) { // Remove any previously set spawn's particles. if (this.spawn != null) - TownyUniverse.getInstance().removeSpawnPoint(spawn.asLocation()); + TownyUniverse.getInstance().removeSpawnPoint(this.spawn.asLocation()); this.spawn = spawn; TownyUniverse.getInstance().addSpawnPoint(new SpawnPoint(spawn, SpawnPointType.OUTPOST_SPAWN)); @@ -50,7 +53,7 @@ public boolean isOutpostHomeBlock(TownBlock tb) { return tb.getWorldCoord().equals(WorldCoord.parseWorldCoord(spawn.asLocation())); } - public int getNumTownBlock() { + public int getNumTownBlocks() { return townblocks.size(); } @@ -65,10 +68,20 @@ public void addTownblock(TownBlock townblock) { } public void removeTownblock(TownBlock townblock) { + if (isOutpostHomeBlock(townblock)) + TownyUniverse.getInstance().removeSpawnPoint(spawn.asLocation()); + this.townblocks.remove(townblock); } public boolean hasTownBlocks() { return townblocks.size() > 0; } + + @Nullable + public TownBlock getSpawnTownBlock() { + if (spawn == null) + return null; + return WorldCoord.parseWorldCoord(spawn.asLocation()).getTownBlockOrNull(); + } } diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/Position.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/Position.java index 0a00b520cb1..6535a2d4c88 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/object/Position.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/Position.java @@ -163,4 +163,9 @@ public static Position deserialize(@NotNull final String[] data) throws IllegalA return new Position(world, x, y, z, pitch, yaw); } + + @Override + public String toString() { + return String.format("%s - %s, %s, %s", this.world.getName(), x, y, z); + } } diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/Town.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/Town.java index 207a6c52f65..3e8a7dc5fec 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/object/Town.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/Town.java @@ -894,8 +894,8 @@ public void removeTownBlock(TownBlock townBlock) { if (hasTownBlock(townBlock)) { // Remove the spawn point for this outpost. - if (townBlock.hasOutpost()) - removeOutpost(townBlock.getOutpost()); + if (townBlock.hasOutpostObject()) + townBlock.getOutpost().removeTownblock(townBlock); if (townBlock.isJail()) { removeJail(townBlock.getJail()); @@ -949,12 +949,12 @@ public void setOutpostSpawns(List outpostSpawns) { public void addOutpostSpawn(Location location) { TownBlock townBlock = TownyAPI.getInstance().getTownBlock(location); - Outpost outpost = townBlock.hasOutpost() + Outpost outpost = townBlock.hasOutpostObject() ? townBlock.getOutpost() - : new Outpost(UUID.randomUUID(), townBlock.getName() != "" ? townBlock.getName() : String.valueOf(outposts.size() + 1)); + : new Outpost(UUID.randomUUID(), !townBlock.getName().isEmpty() ? townBlock.getName() : "UnnamedOutpost" + String.valueOf(outposts.size() + 1)); outpost.setSpawn(Position.ofLocation(location)); - if (outpost.getNumTownBlock() == 0) + if (outpost.getNumTownBlocks() == 0) outpost.addTownblock(townBlock); outpost.save(); } @@ -979,7 +979,7 @@ public int getMaxOutpostSpawn() { } public boolean hasOutpostSpawn() { - return getMaxOutpostSpawn() == 0; + return getMaxOutpostSpawn() > 0; } /** @@ -988,14 +988,14 @@ public boolean hasOutpostSpawn() { * @return List of outpostSpawns */ public List getAllOutpostSpawns() { - return outposts.stream().map(Outpost::getSpawn).map(Position::asLocation).collect(Collectors.toUnmodifiableList()); + return outposts.stream().filter(o -> o.getSpawn() != null).map(Outpost::getSpawn).map(Position::asLocation).collect(Collectors.toUnmodifiableList()); } /** * @return Similar to {@link #getAllOutpostSpawns()}, but with positions. */ public Collection getOutpostSpawns() { - return outposts.stream().map(Outpost::getSpawn).collect(Collectors.toUnmodifiableList()); + return outposts.stream().filter(o -> o.getSpawn() != null).map(Outpost::getSpawn).collect(Collectors.toUnmodifiableList()); } public void removeOutpost(Location loc) { @@ -1037,7 +1037,6 @@ public boolean addOutpost(Outpost outpost) { } public boolean removeOutpost(Outpost outpost) { - TownyUniverse.getInstance().removeSpawnPoint(outpost.getSpawn().asLocation()); return outposts.remove(outpost); } diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/TownBlock.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/TownBlock.java index 2dc5fcbd7c7..6484aad380f 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/object/TownBlock.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/TownBlock.java @@ -44,7 +44,6 @@ public class TownBlock extends TownyObject { private final WorldCoord worldCoord; private double plotPrice = -1; private boolean taxed = true; - private boolean outpost = false; private Outpost outpostObject = null; private PlotGroup plotGroup; private District district; @@ -298,19 +297,18 @@ public void setChanged(boolean isChanged) { } /** - * @return the outpost + * @return True if this townblock is home to the Outpost's spawn point. */ public boolean isOutpost() { - return outpost; + return hasOutpostObject() && getOutpost().isOutpostHomeBlock(this); } /** * @param outpost the outpost to set */ + @Deprecated public void setOutpost(boolean outpost) { - - this.outpost = outpost; } public Outpost getOutpost() { @@ -325,7 +323,7 @@ public void setOutpostObject(Outpost outpost) { this.outpostObject = outpost; } - public boolean hasOutpost() { + public boolean hasOutpostObject() { return outpostObject != null; } diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/LegacyOutpostConversionTask.java b/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/LegacyOutpostConversionTask.java index 1bd475e2789..a6ef3e8c7bb 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/LegacyOutpostConversionTask.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/LegacyOutpostConversionTask.java @@ -38,12 +38,14 @@ public void run() { return; } - String outpostName = townBlock.getName() != "" ? townBlock.getName() : String.valueOf(town.getMaxOutpostSpawn() + 1); + String outpostName = !townBlock.getName().isEmpty() ? townBlock.getName() : "UnnamedOutpost" + String.valueOf(town.getMaxOutpostSpawn()); Outpost outpost = new Outpost(UUID.randomUUID(), outpostName); + outpost.setSpawn(pos); outpost.addTownblock(townBlock); outpost.save(); townBlock.setOutpostObject(outpost); townBlock.save(); + town.addOutpost(outpost); WorldCoord coord = townBlock.getWorldCoord(); FloodfillResult result = null; @@ -68,6 +70,6 @@ else if (result.feedback() != null) } } - TownyMessaging.sendMsg(String.format("%s imported a legacy outpost located at %s, total size: %s.", town.getName(), pos.toString(), selection.size() + 1)); + TownyMessaging.sendMsg(String.format("%s imported a legacy outpost located at %s, total size: %s.", town.getName(), pos.toString(), selection.size())); } } \ No newline at end of file diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/utils/BorderUtil.java b/Towny/src/main/java/com/palmergames/bukkit/towny/utils/BorderUtil.java index cb703fc6e9a..bafb88dab1b 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/utils/BorderUtil.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/utils/BorderUtil.java @@ -271,19 +271,6 @@ public static boolean allowedMove(Block block, Block blockTo, @Nullable Player p if (coords.isEmpty()) return FloodfillResult.fail(null); - int minX = origin.getX(); - int maxX = origin.getX(); - int minZ = origin.getZ(); - int maxZ = origin.getZ(); - - // Establish a min and max X & Z to avoid possibly looking very far - for (final WorldCoord coord : coords) { - minX = Math.min(minX, coord.getX()); - maxX = Math.max(maxX, coord.getX()); - minZ = Math.min(minZ, coord.getZ()); - maxZ = Math.max(maxZ, coord.getZ()); - } - final Set valid = new HashSet<>(); final Set visited = new HashSet<>(); @@ -296,7 +283,6 @@ public static boolean allowedMove(Block block, Block blockTo, @Nullable Player p return FloodfillResult.success(valid); final WorldCoord current = queue.poll(); - valid.add(current); for (final int[] direction : DIRECTIONS) { @@ -305,21 +291,17 @@ public static boolean allowedMove(Block block, Block blockTo, @Nullable Player p final WorldCoord candidate = current.add(xOffset, zOffset); - if (!coords.contains(candidate) && (candidate.getX() >= maxX || candidate.getX() <= minX || candidate.getZ() >= maxZ || candidate.getZ() <= minZ)) { - return FloodfillResult.oob(); - } + if (visited.contains(candidate)) + continue; + visited.add(candidate); final TownBlock townBlock = candidate.getTownBlockOrNull(); - - // Fail if we're touching another town - if (townBlock == null || townBlock.hasTown() && !town.equals(townBlock.getTownOrNull())) { + // Fail if we're touching another town or the wilderness. + if (townBlock == null || !town.hasTownBlock(townBlock)) { continue; } - if (!visited.contains(candidate) && !coords.contains(candidate)) { - queue.offer(candidate); - visited.add(candidate); - } + queue.offer(candidate); } } diff --git a/Towny/src/main/resources/lang/en-US.yml b/Towny/src/main/resources/lang/en-US.yml index 12be5cf7019..51b03c322c2 100644 --- a/Towny/src/main/resources/lang/en-US.yml +++ b/Towny/src/main/resources/lang/en-US.yml @@ -2615,3 +2615,7 @@ msg_admin_eco_convert_success: "Economy conversion successful" msg_err_mode_does_not_exist: "The mode %s is not recognized." msg_err_not_allowed_to_switch: "You aren't allowed to Switch here." + +status_outpost_name_and_size: 'Townblock is part of Outpost: %s. Outpost has %s Townblocks total.' + +msg_err_plot_already_part_of_outpost_group: "You cannot create a new Outpost within an already existing Outpost." \ No newline at end of file