diff --git a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java index d570836bd..42fffa9ea 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java @@ -271,8 +271,10 @@ public class IslandsManager { handler.deleteObject(island); // Remove players from island removePlayersFromIsland(island); - // Remove blocks from world - plugin.getIslandDeletionManager().getIslandChunkDeletionManager().add(new IslandDeletion(island)); + if (!plugin.getSettings().isKeepPreviousIslandOnReset()) { + // Remove blocks from world + plugin.getIslandDeletionManager().getIslandChunkDeletionManager().add(new IslandDeletion(island)); + } } } diff --git a/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java b/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java index 6fa08c7ee..e3afec118 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java @@ -27,300 +27,300 @@ import world.bentobox.bentobox.managers.BlueprintsManager; * */ public class NewIsland { - private final BentoBox plugin; - private Island island; - private final User user; - private final Reason reason; - private final World world; - private String name; - private final boolean noPaste; - private final GameModeAddon addon; + private final BentoBox plugin; + private Island island; + private final User user; + private final Reason reason; + private final World world; + private String name; + private final boolean noPaste; + private final GameModeAddon addon; - private NewIslandLocationStrategy locationStrategy; + private NewIslandLocationStrategy locationStrategy; - public NewIsland(Builder builder) throws IOException { - plugin = BentoBox.getInstance(); - this.user = builder.user2; - this.reason = builder.reason2; - this.world = builder.world2; - this.name = builder.name2; - this.noPaste = builder.noPaste2; - this.addon = builder.addon2; - this.locationStrategy = builder.locationStrategy2; + public NewIsland(Builder builder) throws IOException { + plugin = BentoBox.getInstance(); + this.user = builder.user2; + this.reason = builder.reason2; + this.world = builder.world2; + this.name = builder.name2; + this.noPaste = builder.noPaste2; + this.addon = builder.addon2; + this.locationStrategy = builder.locationStrategy2; - if (this.locationStrategy == null) { - this.locationStrategy = new DefaultNewIslandLocationStrategy(); - } - // Fire pre-create event - IslandBaseEvent event = IslandEvent.builder().involvedPlayer(user.getUniqueId()).reason(Reason.PRECREATE) - .build(); - if (event.getNewEvent().map(IslandBaseEvent::isCancelled).orElse(event.isCancelled())) { - // Do nothing - return; - } - newIsland(builder.oldIsland2); + if (this.locationStrategy == null) { + this.locationStrategy = new DefaultNewIslandLocationStrategy(); + } + // Fire pre-create event + IslandBaseEvent event = IslandEvent.builder().involvedPlayer(user.getUniqueId()).reason(Reason.PRECREATE) + .build(); + if (event.getNewEvent().map(IslandBaseEvent::isCancelled).orElse(event.isCancelled())) { + // Do nothing + return; + } + newIsland(builder.oldIsland2); + } + + /** + * @return the island that was created + */ + public Island getIsland() { + return island; + } + + /** + * Start building a new island + * + * @return New island builder object + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Build a new island for a player + * + * @author tastybento + */ + public static class Builder { + private Island oldIsland2; + private User user2; + private Reason reason2; + private World world2; + private String name2 = BlueprintsManager.DEFAULT_BUNDLE_NAME; + private boolean noPaste2; + private GameModeAddon addon2; + private NewIslandLocationStrategy locationStrategy2; + + public Builder oldIsland(Island oldIsland) { + this.oldIsland2 = oldIsland; + this.world2 = oldIsland.getWorld(); + return this; + } + + public Builder player(User player) { + this.user2 = player; + return this; } /** - * @return the island that was created - */ - public Island getIsland() { - return island; - } - - /** - * Start building a new island + * Sets the reason * - * @return New island builder object + * @param reason reason, can only be {@link Reason#CREATE} or + * {@link Reason#RESET}. */ - public static Builder builder() { - return new Builder(); + public Builder reason(Reason reason) { + if (!reason.equals(Reason.CREATE) && !reason.equals(Reason.RESET)) { + throw new IllegalArgumentException("Reason must be CREATE or RESET."); + } + this.reason2 = reason; + return this; } /** - * Build a new island for a player + * Set the addon * - * @author tastybento + * @param addon a game mode addon */ - public static class Builder { - private Island oldIsland2; - private User user2; - private Reason reason2; - private World world2; - private String name2 = BlueprintsManager.DEFAULT_BUNDLE_NAME; - private boolean noPaste2; - private GameModeAddon addon2; - private NewIslandLocationStrategy locationStrategy2; - - public Builder oldIsland(Island oldIsland) { - this.oldIsland2 = oldIsland; - this.world2 = oldIsland.getWorld(); - return this; - } - - public Builder player(User player) { - this.user2 = player; - return this; - } - - /** - * Sets the reason - * - * @param reason reason, can only be {@link Reason#CREATE} or - * {@link Reason#RESET}. - */ - public Builder reason(Reason reason) { - if (!reason.equals(Reason.CREATE) && !reason.equals(Reason.RESET)) { - throw new IllegalArgumentException("Reason must be CREATE or RESET."); - } - this.reason2 = reason; - return this; - } - - /** - * Set the addon - * - * @param addon a game mode addon - */ - public Builder addon(GameModeAddon addon) { - this.addon2 = addon; - this.world2 = addon.getOverWorld(); - return this; - } - - /** - * No blocks will be pasted - */ - public Builder noPaste() { - this.noPaste2 = true; - return this; - } - - /** - * @param name - name of Blueprint bundle - */ - public Builder name(String name) { - this.name2 = name; - return this; - } - - /** - * @param strategy - the location strategy to use - * @since 1.8.0 - */ - public Builder locationStrategy(NewIslandLocationStrategy strategy) { - this.locationStrategy2 = strategy; - return this; - } - - /** - * @return Island - * @throws IOException - if there are insufficient parameters, i.e., no user - */ - public Island build() throws IOException { - if (user2 != null) { - NewIsland newIsland = new NewIsland(this); - return newIsland.getIsland(); - } - throw new IOException("Insufficient parameters. Must have a user!"); - } + public Builder addon(GameModeAddon addon) { + this.addon2 = addon; + this.world2 = addon.getOverWorld(); + return this; } /** - * Makes an island. - * - * @param oldIsland old island that is being replaced, if any - * @throws IOException - if an island cannot be made. Message is the tag to show - * the user. + * No blocks will be pasted */ - public void newIsland(Island oldIsland) throws IOException { - // Find the new island location - Location next = checkReservedIsland(); - if (next == null) { - next = this.makeNextIsland(); - } - // Clean up the user - cleanUpUser(next); - // Fire event - IslandBaseEvent event = IslandEvent.builder().involvedPlayer(user.getUniqueId()).reason(reason).island(island) - .location(island.getCenter()) - .blueprintBundle(plugin.getBlueprintsManager().getBlueprintBundles(addon).get(name)) - .oldIsland(oldIsland).build(); - if (event.getNewEvent().map(IslandBaseEvent::isCancelled).orElse(event.isCancelled())) { - // Do nothing - return; - } - event = event.getNewEvent().orElse(event); - // Get the new BlueprintBundle if it was changed - switch (reason) { - case CREATE -> name = ((IslandCreateEvent) event).getBlueprintBundle().getUniqueId(); - case RESET -> name = ((IslandResetEvent) event).getBlueprintBundle().getUniqueId(); - default -> { - // Do nothing of other cases - } - } - // Set the player's primary island - plugin.getIslands().setPrimaryIsland(user.getUniqueId(), island); - // Run task to run after creating the island in one tick if island is not being - // pasted - if (noPaste) { - Bukkit.getScheduler().runTask(plugin, () -> postCreationTask(oldIsland)); - } else { - // Create islands, then run task - plugin.getBlueprintsManager().paste(addon, island, name, () -> postCreationTask(oldIsland)); - } - // Set default settings - island.setFlagsDefaults(); - // Register metrics - plugin.getMetrics().ifPresent(BStats::increaseIslandsCreatedCount); - // Save island - plugin.getIslands().save(island); + public Builder noPaste() { + this.noPaste2 = true; + return this; } /** - * Tasks to run after the new island has been created - * - * @param oldIsland - old island that will be deleted + * @param name - name of Blueprint bundle */ - private void postCreationTask(Island oldIsland) { - // Set initial spawn point if one exists - if (island.getSpawnPoint(Environment.NORMAL) != null) { - plugin.getIslands().setHomeLocation(user, island.getSpawnPoint(Environment.NORMAL)); - } - // Stop the player from falling or moving if they are - if (user.isOnline()) { - if (reason.equals(Reason.RESET) || (reason.equals(Reason.CREATE) - && plugin.getIWM().isTeleportPlayerToIslandUponIslandCreation(world))) { - user.getPlayer().setVelocity(new Vector(0, 0, 0)); - user.getPlayer().setFallDistance(0F); - // Teleport player after this island is built - plugin.getIslands().homeTeleportAsync(world, user.getPlayer(), true).thenRun(() -> tidyUp(oldIsland)); - return; - } else { - // let's send him a message so that he knows he can teleport to his island! - user.sendMessage("commands.island.create.you-can-teleport-to-your-island"); - } - } else { - // Remove the player again to completely clear the data - User.removePlayer(user.getPlayer()); - } - tidyUp(oldIsland); + public Builder name(String name) { + this.name2 = name; + return this; } /** - * Cleans up a user before moving them to a new island. Resets deaths. Checks - * range permissions and saves the player to the database. - * - * @param loc - the new island location + * @param strategy - the location strategy to use + * @since 1.8.0 */ - private void cleanUpUser(Location loc) { - // Reset deaths - if (plugin.getIWM().isDeathsResetOnNewIsland(world)) { - plugin.getPlayers().setDeaths(world, user.getUniqueId(), 0); - } - // Check if owner has a different range permission than the island size - island.setProtectionRange(user.getPermissionValue( - plugin.getIWM().getAddon(island.getWorld()).map(GameModeAddon::getPermissionPrefix).orElse("") - + "island.range", - island.getProtectionRange())); - // Save the player so that if the server crashes weird things won't happen - plugin.getPlayers().save(user.getUniqueId()); + public Builder locationStrategy(NewIslandLocationStrategy strategy) { + this.locationStrategy2 = strategy; + return this; } /** - * Get the next island location and add it to the island grid - * - * @return location of new island - * @throws IOException - if there are no unoccupied spots or the island could - * not be added to the grid + * @return Island + * @throws IOException - if there are insufficient parameters, i.e., no user */ - private Location makeNextIsland() throws IOException { - // If the reservation fails, then we need to make a new island anyway - Location next = this.locationStrategy.getNextLocation(world); - if (next == null) { - plugin.logError("Failed to make island - no unoccupied spot found."); - plugin.logError("If the world was imported, try multiple times until all unowned islands are known."); - throw new IOException("commands.island.create.cannot-create-island"); - } - // Add to the grid - island = plugin.getIslands().createIsland(next, user.getUniqueId()); - if (island == null) { - plugin.logError("Failed to make island! Island could not be added to the grid."); - throw new IOException("commands.island.create.unable-create-island"); - } - return next; + public Island build() throws IOException { + if (user2 != null) { + NewIsland newIsland = new NewIsland(this); + return newIsland.getIsland(); + } + throw new IOException("Insufficient parameters. Must have a user!"); + } + } + + /** + * Makes an island. + * + * @param oldIsland old island that is being replaced, if any + * @throws IOException - if an island cannot be made. Message is the tag to show + * the user. + */ + public void newIsland(Island oldIsland) throws IOException { + // Find the new island location + Location next = checkReservedIsland(); + if (next == null) { + next = this.makeNextIsland(); + } + // Clean up the user + cleanUpUser(next); + // Fire event + IslandBaseEvent event = IslandEvent.builder().involvedPlayer(user.getUniqueId()).reason(reason).island(island) + .location(island.getCenter()) + .blueprintBundle(plugin.getBlueprintsManager().getBlueprintBundles(addon).get(name)) + .oldIsland(oldIsland).build(); + if (event.getNewEvent().map(IslandBaseEvent::isCancelled).orElse(event.isCancelled())) { + // Do nothing + return; + } + event = event.getNewEvent().orElse(event); + // Get the new BlueprintBundle if it was changed + switch (reason) { + case CREATE -> name = ((IslandCreateEvent) event).getBlueprintBundle().getUniqueId(); + case RESET -> name = ((IslandResetEvent) event).getBlueprintBundle().getUniqueId(); + default -> { + // Do nothing of other cases + } + } + // Set the player's primary island + plugin.getIslands().setPrimaryIsland(user.getUniqueId(), island); + // Run task to run after creating the island in one tick if island is not being + // pasted + if (noPaste) { + Bukkit.getScheduler().runTask(plugin, () -> postCreationTask(oldIsland)); + } else { + // Create islands, then run task + plugin.getBlueprintsManager().paste(addon, island, name, () -> postCreationTask(oldIsland)); + } + // Set default settings + island.setFlagsDefaults(); + // Register metrics + plugin.getMetrics().ifPresent(BStats::increaseIslandsCreatedCount); + // Save island + plugin.getIslands().save(island); + } + + /** + * Tasks to run after the new island has been created + * + * @param oldIsland - old island that will be deleted + */ + private void postCreationTask(Island oldIsland) { + // Set initial spawn point if one exists + if (island.getSpawnPoint(Environment.NORMAL) != null) { + plugin.getIslands().setHomeLocation(user, island.getSpawnPoint(Environment.NORMAL)); + } + // Stop the player from falling or moving if they are + if (user.isOnline()) { + if (reason.equals(Reason.RESET) || (reason.equals(Reason.CREATE) + && plugin.getIWM().isTeleportPlayerToIslandUponIslandCreation(world))) { + user.getPlayer().setVelocity(new Vector(0, 0, 0)); + user.getPlayer().setFallDistance(0F); + // Teleport player after this island is built + plugin.getIslands().homeTeleportAsync(world, user.getPlayer(), true).thenRun(() -> tidyUp(oldIsland)); + return; + } else { + // let's send him a message so that he knows he can teleport to his island! + user.sendMessage("commands.island.create.you-can-teleport-to-your-island"); + } + } else { + // Remove the player again to completely clear the data + User.removePlayer(user.getPlayer()); + } + tidyUp(oldIsland); + } + + /** + * Cleans up a user before moving them to a new island. Resets deaths. Checks + * range permissions and saves the player to the database. + * + * @param loc - the new island location + */ + private void cleanUpUser(Location loc) { + // Reset deaths + if (plugin.getIWM().isDeathsResetOnNewIsland(world)) { + plugin.getPlayers().setDeaths(world, user.getUniqueId(), 0); + } + // Check if owner has a different range permission than the island size + island.setProtectionRange(user.getPermissionValue( + plugin.getIWM().getAddon(island.getWorld()).map(GameModeAddon::getPermissionPrefix).orElse("") + + "island.range", + island.getProtectionRange())); + // Save the player so that if the server crashes weird things won't happen + plugin.getPlayers().save(user.getUniqueId()); + } + + /** + * Get the next island location and add it to the island grid + * + * @return location of new island + * @throws IOException - if there are no unoccupied spots or the island could + * not be added to the grid + */ + private Location makeNextIsland() throws IOException { + // If the reservation fails, then we need to make a new island anyway + Location next = this.locationStrategy.getNextLocation(world); + if (next == null) { + plugin.logError("Failed to make island - no unoccupied spot found."); + plugin.logError("If the world was imported, try multiple times until all unowned islands are known."); + throw new IOException("commands.island.create.cannot-create-island"); + } + // Add to the grid + island = plugin.getIslands().createIsland(next, user.getUniqueId()); + if (island == null) { + plugin.logError("Failed to make island! Island could not be added to the grid."); + throw new IOException("commands.island.create.unable-create-island"); + } + return next; + } + + /** + * Get the reserved island location + * + * @return reserved island location, or null if none found + */ + private Location checkReservedIsland() { + if (plugin.getIslands().hasIsland(world, user)) { + // Island exists, it just needs pasting + island = plugin.getIslands().getIsland(world, user); + if (island != null && island.isReserved()) { + Location l = island.getCenter(); + // Clear the reservation + island.setReserved(false); + return l; + } + } + return null; + } + + private void tidyUp(Island oldIsland) { + // Delete old island + if (oldIsland != null) { + // Delete the old island + plugin.getIslands().deleteIsland(oldIsland, true, user.getUniqueId()); } - /** - * Get the reserved island location - * - * @return reserved island location, or null if none found - */ - private Location checkReservedIsland() { - if (plugin.getIslands().hasIsland(world, user)) { - // Island exists, it just needs pasting - island = plugin.getIslands().getIsland(world, user); - if (island != null && island.isReserved()) { - Location l = island.getCenter(); - // Clear the reservation - island.setReserved(false); - return l; - } - } - return null; - } + // Fire exit event + IslandEvent.builder().involvedPlayer(user.getUniqueId()) + .reason(reason == Reason.RESET ? Reason.RESETTED : Reason.CREATED).island(island) + .location(island.getCenter()).oldIsland(oldIsland).build(); - private void tidyUp(Island oldIsland) { - // Delete old island - if (oldIsland != null && !plugin.getSettings().isKeepPreviousIslandOnReset()) { - // Delete the old island - plugin.getIslands().deleteIsland(oldIsland, true, user.getUniqueId()); - } - - // Fire exit event - IslandEvent.builder().involvedPlayer(user.getUniqueId()) - .reason(reason == Reason.RESET ? Reason.RESETTED : Reason.CREATED).island(island) - .location(island.getCenter()).oldIsland(oldIsland).build(); - - } + } } \ No newline at end of file