Extended /bclib place nbt command to place all files from a directory

This commit is contained in:
Frank 2023-05-31 23:19:13 +02:00
parent 28af68b906
commit 9f327308a5
2 changed files with 129 additions and 17 deletions

View file

@ -23,6 +23,12 @@ import com.google.common.collect.Maps;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jetbrains.annotations.Nullable;
@ -109,6 +115,7 @@ public class StructureNBT {
String ns = resource.getNamespace();
String nm = resource.getPath();
allResourcesFrom(resource);
try {
InputStream inputstream = MinecraftServer.class.getResourceAsStream("/data/" + ns + "/structures/" + nm + ".nbt");
return readStructureFromStream(inputstream);
@ -119,6 +126,61 @@ public class StructureNBT {
return null;
}
public static List<StructureNBT> allResourcesFrom(ResourceLocation resource) {
String ns = resource.getNamespace();
String nm = resource.getPath();
final URL url = MinecraftServer.class.getClassLoader().getResource("data/" + ns + "/structures/" + nm);
if (url != null) {
final URI uri;
try {
uri = url.toURI();
} catch (URISyntaxException e) {
BCLib.LOGGER.error("Unable to load Resources: ", e);
return null;
}
Path myPath;
if (uri.getScheme().equals("jar")) {
FileSystem fileSystem = null;
try {
fileSystem = FileSystems.newFileSystem(uri, new HashMap<>());
} catch (IOException e) {
BCLib.LOGGER.error("Unable to load Resources: ", e);
return null;
}
myPath = fileSystem.getPath("/resources");
} else {
myPath = Paths.get(uri);
}
if (myPath.toFile().isDirectory()) {
try {
return Files.walk(myPath, 1)
.filter(p -> p.toFile().isFile())
.map(p -> p.getFileName().toFile())
.filter(f -> f.toString().endsWith(".nbt"))
.map(f -> f.toString())
.map(s -> new ResourceLocation(
ns,
(nm.isEmpty() ? "" : (nm + "/")) + s.substring(0, s.length() - 4)
))
.map(r -> {
BCLib.LOGGER.info("Loading Structure: " + r);
try {
return StructureNBT.create(r);
} catch (Exception e) {
BCLib.LOGGER.error("Unable to load Structure " + r, e);
}
return null;
}).toList();
} catch (IOException e) {
BCLib.LOGGER.error("Unable to load Resources: ", e);
return null;
}
}
}
return null;
}
private static StructureTemplate readStructureFromStream(InputStream stream) throws IOException {
CompoundTag nbttagcompound = NbtIo.readCompressed(stream);

View file

@ -1,5 +1,6 @@
package org.betterx.bclib.commands;
import de.ambertation.wunderlib.math.Bounds;
import de.ambertation.wunderlib.math.Float3;
import org.betterx.bclib.api.v2.levelgen.structures.StructureNBT;
import org.betterx.bclib.commands.arguments.Float3ArgumentType;
@ -128,6 +129,7 @@ class PlaceCommandBuilder {
) throws CommandSyntaxException;
}
// /bclib place nbt betternether:city southOf 0 -59 0 controller
protected static int placeNBT(
CommandContext<CommandSourceStack> ctx,
boolean border,
@ -136,18 +138,64 @@ class PlaceCommandBuilder {
final ResourceLocation id = ResourceLocationArgument.getId(ctx, PATH);
final PlacementDirections searchDir = TemplatePlacementArgument.getPlacement(ctx, PLACEMENT);
final BlockInput blockInput = border ? BlockStateArgument.getBlock(ctx, BORDER) : null;
final BlockPos pos = BlockPosArgument.getLoadedBlockPos(ctx, POS);
var structures = StructureNBT.allResourcesFrom(id);
if (structures != null) {
Bounds b = Bounds.of(pos);
Bounds all = Bounds.of(pos);
BlockPos pNew = pos;
for (var s : structures) {
Bounds bb = Bounds.of(PlaceCommand.placeBlocks(
ctx.getSource(),
pNew,
searchDir.getOffset(),
blockInput,
controlBlocks,
s.location,
(p) -> s.getBoundingBox(p, Rotation.NONE, Mirror.NONE),
(level, p) -> s.generateAt(level, p, Rotation.NONE, Mirror.NONE)
));
b = b.encapsulate(bb);
all = all.encapsulate(bb);
if (searchDir == PlacementDirections.NORTH_OF || searchDir == PlacementDirections.SOUTH_OF) {
if (b.getSize().z > 10 * 16) {
pNew = new BlockPos((int) b.max.x + 3, pNew.getY(), pNew.getZ());
b = Bounds.of(pNew);
}
} else if (searchDir == PlacementDirections.EAST_OF || searchDir == PlacementDirections.WEST_OF) {
if (b.getSize().x > 10 * 16) {
pNew = new BlockPos(pNew.getX(), pNew.getY(), (int) b.max.z + 3);
b = Bounds.of(pNew);
}
} else {
if (b.getSize().y > 10 * 16) {
pNew = new BlockPos(pNew.getX(), pNew.getY(), (int) b.max.z + 3);
b = Bounds.of(pNew);
}
}
}
Bounds finalAll = all;
ctx.getSource()
.sendSuccess(() -> Component.literal("Placed " + structures.size() + " NBTs: " + finalAll.toString())
.setStyle(Style.EMPTY.withColor(ChatFormatting.LIGHT_PURPLE)), true);
return 0;
} else {
final StructureNBT structureNBT = StructureNBT.create(id);
return PlaceCommand.placeBlocks(
ctx.getSource(),
BlockPosArgument.getLoadedBlockPos(ctx, POS),
pos,
searchDir.getOffset(),
blockInput,
controlBlocks,
structureNBT.location,
(p) -> structureNBT.getBoundingBox(p, Rotation.NONE, Mirror.NONE),
(level, p) -> structureNBT.generateAt(level, p, Rotation.NONE, Mirror.NONE)
);
) == null ? Command.SINGLE_SUCCESS : -1;
}
}
protected static int placeEmpty(
@ -182,7 +230,7 @@ class PlaceCommandBuilder {
);
}
}
);
) == null ? Command.SINGLE_SUCCESS : -1;
}
}
@ -320,7 +368,7 @@ public class PlaceCommand {
}
static int placeBlocks(
static BoundingBox placeBlocks(
CommandSourceStack stack,
BlockPos pos,
BlockPos searchDir,
@ -340,7 +388,6 @@ public class PlaceCommand {
structureBlock
)
)) {
pos = pos.offset(searchDir);
tries--;
}
@ -348,16 +395,19 @@ public class PlaceCommand {
if (tries <= 0) {
stack.sendFailure(Component.literal("Failed to find free space")
.setStyle(Style.EMPTY.withColor(ChatFormatting.RED)));
return -1;
return null;
}
}
final BoundingBox bbNBT = getBounds.apply(pos);
final BoundingBox bb;
if (blockInput != null) {
final BoundingBox bb = bbNBT.inflatedBy(1);
bb = bbNBT.inflatedBy(1);
outline(stack.getLevel(), bb, blockInput.getState());
stack.sendSuccess(() -> Component.literal("Placed border: " + bb.toString())
.setStyle(Style.EMPTY.withColor(ChatFormatting.GREEN)), true);
} else {
bb = adapt(bbNBT, false, structureBlock);
}
generate.accept(stack.getLevel(), pos);
@ -369,7 +419,7 @@ public class PlaceCommand {
if (structureBlock) {
createControlBlocks(stack, location, bbNBT);
}
return Command.SINGLE_SUCCESS;
return bb;
}
}