diff --git a/src/main/java/org/betterx/bclib/commands/arguments/BCLibArguments.java b/src/main/java/org/betterx/bclib/commands/arguments/BCLibArguments.java index 15b8f38c..1cb1fdae 100644 --- a/src/main/java/org/betterx/bclib/commands/arguments/BCLibArguments.java +++ b/src/main/java/org/betterx/bclib/commands/arguments/BCLibArguments.java @@ -19,5 +19,11 @@ public class BCLibArguments { Float3ArgumentType.class, new Float3ArgumentInfo() ); + + ArgumentTypeRegistry.registerArgumentType( + BCLib.makeID("connector"), + ConnectorArgument.class, + SingletonArgumentInfo.contextFree(ConnectorArgument::id) + ); } } diff --git a/src/main/java/org/betterx/bclib/commands/arguments/ConnectorArgument.java b/src/main/java/org/betterx/bclib/commands/arguments/ConnectorArgument.java new file mode 100644 index 00000000..2feffb4d --- /dev/null +++ b/src/main/java/org/betterx/bclib/commands/arguments/ConnectorArgument.java @@ -0,0 +1,49 @@ +package org.betterx.bclib.commands.arguments; + +import org.betterx.bclib.commands.PlaceCommand; + +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import net.minecraft.commands.SharedSuggestionProvider; +import net.minecraft.commands.arguments.ResourceLocationArgument; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import org.jetbrains.annotations.NotNull; + +public class ConnectorArgument extends ResourceLocationArgument { + private static final Collection EXAMPLES = Arrays.asList("-:entrance", "-:decoration", "-:street"); + + @Override + public Collection getExamples() { + return EXAMPLES; + } + + @Override + public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { + ResourceLocation pool = null; + try { + pool = context.getArgument(PlaceCommand.POOL, ResourceKey.class).location(); + } catch (Throwable t) { + pool = new ResourceLocation("-", ""); + } + return SharedSuggestionProvider.suggest(getStrings( + pool.getNamespace(), + List.of("bottom", "building_entrance", "street") + ), builder); + } + + @NotNull + private List getStrings(String namespace, List input) { + return input.stream().map(s -> namespace + ":" + s).toList(); + } + + public static ConnectorArgument id() { + return new ConnectorArgument(); + } +} diff --git a/src/main/java/org/betterx/bclib/commands/arguments/PlacementDirections.java b/src/main/java/org/betterx/bclib/commands/arguments/PlacementDirections.java index e059ad66..13447313 100644 --- a/src/main/java/org/betterx/bclib/commands/arguments/PlacementDirections.java +++ b/src/main/java/org/betterx/bclib/commands/arguments/PlacementDirections.java @@ -1,5 +1,6 @@ package org.betterx.bclib.commands.arguments; +import de.ambertation.wunderlib.math.Bounds; import de.ambertation.wunderlib.math.Float3; import com.mojang.serialization.Codec; @@ -7,28 +8,65 @@ import net.minecraft.core.BlockPos; import net.minecraft.util.StringRepresentable; public enum PlacementDirections implements StringRepresentable { - NORTH_OF("northOf", Float3.NORTH), - EAST_OF("eastOf", Float3.EAST), - SOUTH_OF("southOf", Float3.SOUTH), - WEST_OF("westOf", Float3.WEST), - ABOVE("above", Float3.UP), - BELOW("below", Float3.DOWN), - AT("at", null); + NORTH_OF("northOf", Float3.NORTH, PlacementDirections::resetStartNorthSouth), + EAST_OF("eastOf", Float3.EAST, PlacementDirections::resetStartEastWest), + SOUTH_OF("southOf", Float3.SOUTH, PlacementDirections::resetStartNorthSouth), + WEST_OF("westOf", Float3.WEST, PlacementDirections::resetStartEastWest), + ABOVE("above", Float3.UP, PlacementDirections::resetStartEastWest), + BELOW("below", Float3.DOWN, PlacementDirections::resetStartEastWest), + AT("at", null, null); public static final Codec CODEC = StringRepresentable.fromEnum(PlacementDirections::values); + interface ResetStart { + Float3 calculate(Bounds totalBounds, BlockPos lastStart, int offset); + } + + private static Float3 resetStartNorthSouth(Bounds totalBounds, BlockPos lastStart, int offset) { + return Float3.of(totalBounds.max.x + offset, lastStart.getY(), lastStart.getZ()); + } + + private static Float3 resetStartEastWest(Bounds totalBounds, BlockPos lastStart, int offset) { + return Float3.of(lastStart.getX(), lastStart.getY(), totalBounds.max.z + offset); + } + private final String name; public final Float3 dir; + private final ResetStart resetStart; - PlacementDirections(String name, Float3 dir) { + PlacementDirections(String name, Float3 dir, ResetStart resetStart) { this.name = name; this.dir = dir; + this.resetStart = resetStart; } public BlockPos getOffset() { return dir == null || dir == Float3.ZERO ? null : dir.toBlockPos(); } + public int sizeInDirection(Bounds totalBounds) { + return (int) totalBounds.getSize().mul(dir).length(); + } + + public BlockPos advanceStart(Bounds placedBound, BlockPos lastStart) { + return advanceStart(placedBound, lastStart, 1); + } + + public BlockPos advanceStart(Bounds placedBound, BlockPos lastStart, int offset) { + return lastStart.offset(dir.mul(sizeInDirection(placedBound) + offset).toBlockPos()); + } + + public BlockPos resetStart(Bounds totalBounds, BlockPos lastStart) { + return resetStart(totalBounds, lastStart, 3); + } + + public BlockPos resetStart(Bounds totalBounds, BlockPos lastStart, int offset) { + if (resetStart == null) { + return lastStart; + } + return this.resetStart.calculate(totalBounds, lastStart, offset).toBlockPos(); + } + @Override public String getSerializedName() { return name;