Merge pull request #2620 from BentoBoxWorld/blueprint_sink

Add sinking option for blueprints.
This commit is contained in:
tastybento 2025-02-22 17:23:54 -08:00 committed by GitHub
commit 683aa91f14
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 108 additions and 5 deletions

View File

@ -40,6 +40,7 @@ public class AdminBlueprintCommand extends ConfirmableCommand {
clipboards = new HashMap<>();
displayClipboards = new HashMap<>();
// Sub commands
new AdminBlueprintLoadCommand(this);
new AdminBlueprintPasteCommand(this);
new AdminBlueprintOriginCommand(this);
@ -50,6 +51,7 @@ public class AdminBlueprintCommand extends ConfirmableCommand {
new AdminBlueprintPos1Command(this);
new AdminBlueprintPos2Command(this);
new AdminBlueprintListCommand(this);
new AdminBlueprintSinkCommand(this);
}
@Override

View File

@ -1,16 +1,24 @@
package world.bentobox.bentobox.api.commands.admin.blueprints;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.managers.BlueprintClipboardManager;
import world.bentobox.bentobox.managers.BlueprintsManager;
import world.bentobox.bentobox.util.Util;
public class AdminBlueprintLoadCommand extends CompositeCommand {
private static final FilenameFilter BLUEPRINT_FILTER = (File dir, String name) -> name
.endsWith(BlueprintsManager.BLUEPRINT_SUFFIX);
public AdminBlueprintLoadCommand(AdminBlueprintCommand parent) {
super(parent, "load");
}
@ -43,9 +51,12 @@ public class AdminBlueprintLoadCommand extends CompositeCommand {
@Override
public Optional<List<String>> tabComplete(User user, String alias, List<String> args) {
List<String> options = new ArrayList<>();
options.add("island");
options.add("nether-island");
options.add("end-island");
AdminBlueprintCommand parent = (AdminBlueprintCommand) getParent();
File folder = parent.getBlueprintsFolder();
if (folder.exists()) {
options = Arrays.asList(folder.list(BLUEPRINT_FILTER)).stream().map(n -> n.substring(0, n.length() - 4)) // remove .blu from filename
.toList();
}
String lastArg = !args.isEmpty() ? args.get(args.size()-1) : "";
return Optional.of(Util.tabLimit(options, lastArg));

View File

@ -0,0 +1,57 @@
package world.bentobox.bentobox.api.commands.admin.blueprints;
import java.util.List;
import java.util.Optional;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.blueprints.BlueprintClipboard;
public class AdminBlueprintSinkCommand extends CompositeCommand
{
public AdminBlueprintSinkCommand(AdminBlueprintCommand parent)
{
super(parent, "sink");
}
@Override
public void setup()
{
setPermission("admin.blueprint.sink");
setDescription("commands.admin.blueprint.sink.description");
}
@Override
public boolean execute(User user, String label, List<String> args)
{
AdminBlueprintCommand parent = (AdminBlueprintCommand) getParent();
if (args.isEmpty()) {
BlueprintClipboard clipboard = parent.getClipboards().computeIfAbsent(user.getUniqueId(),
v -> new BlueprintClipboard());
if (clipboard.isFull()) {
// Clipboard loaded - toggle sink
clipboard.getBlueprint().setSink(!clipboard.getBlueprint().isSink());
user.sendMessage("commands.admin.blueprint.sink.status", "[status]",
clipboard.getBlueprint().isSink() ? user.getTranslation("commands.admin.blueprint.sink.sink")
: user.getTranslation("commands.admin.blueprint.sink.not-sink"));
return true;
} else {
user.sendMessage("commands.admin.blueprint.sink.no-clipboard");
return false;
}
} else {
this.showHelp(this, user);
return false;
}
}
@Override
public Optional<List<String>> tabComplete(User user, String alias, List<String> args)
{
return Optional.of(List.of("air", "biome", "nowater", "sink"));
}
}

View File

@ -45,6 +45,8 @@ public class Blueprint {
private int zSize;
@Expose
private Vector bedrock;
@Expose
private boolean sink;
/**
* @return the name
*/
@ -199,4 +201,20 @@ public class Blueprint {
this.bedrock = bedrock;
}
/**
* Check if the blueprint should sink or not
* @return the sink
*/
public boolean isSink() {
return sink;
}
/**
* Set if the blueprint should sink or not
* @param sink the sink to set
*/
public void setSink(boolean sink) {
this.sink = sink;
}
}

View File

@ -13,6 +13,7 @@ import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import org.bukkit.Bukkit;
import org.bukkit.HeightMap;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.scheduler.BukkitTask;
@ -68,6 +69,7 @@ public class BlueprintPaster {
private BukkitTask pastingTask;
private BlueprintClipboard clipboard;
private CompletableFuture<Void> currentTask = CompletableFuture.completedFuture(null);
private boolean sink;
/**
* The Blueprint to paste.
@ -79,7 +81,7 @@ public class BlueprintPaster {
* The Location to paste to.
*/
@NonNull
private final Location location;
private Location location;
/**
* Island related to this paste, may be null.
@ -316,6 +318,13 @@ public class BlueprintPaster {
if (duration > chunkLoadTime) {
chunkLoadTime = duration;
}
// Adjust location if this is a sinking blueprint to put it on the ocean floor
// Mayday! Mayday! We are sinking! ... What are you sinking about? https://youtu.be/gmOTpIVxji8?si=DC-u4qWRTN5fdWd8
if (this.blueprint.isSink() && !sink) {
sink = true; // Flag, just do this once
location = new Location(location.getWorld(), location.getX(),
location.getWorld().getHighestBlockYAt(location, HeightMap.OCEAN_FLOOR), location.getZ());
}
});
}

View File

@ -374,6 +374,12 @@ commands:
parameters: '[air] [biome] [nowater]'
description: copy the clipboard set by pos1 and pos2 and optionally the air,
biome, and water blocks
sink:
description: "set this blueprint to sink to the ocean floor when pasted"
status: "&a Blueprint will [status] &a when pasted"
sink: "&c sink"
not-sink: "&b not sink"
no-clipboard: "&c There is no blueprint in the clipboard. Load or copy something."
delete:
parameters: <name>
description: delete the blueprint

View File

@ -208,7 +208,7 @@ public class AdminBlueprintLoadCommandTest {
public void testTabCompleteUserStringListOfStringIsland() {
Optional<List<String>> o = abcc.tabComplete(user, "", List.of("e"));
assertTrue(o.isPresent());
assertEquals("end-island", o.get().get(0));
assertTrue(o.get().isEmpty());
}
}