command update

This commit is contained in:
Chipperfluff 2025-12-16 12:22:14 +01:00
parent 1c7d72d721
commit bfd39cd54b
8 changed files with 223 additions and 113 deletions

View File

@ -1,9 +1,14 @@
package net.Chipperfluff.chipi.command;
import com.mojang.brigadier.CommandDispatcher;
import net.Chipperfluff.chipi.world.gen.struct.ChipiStructures;
import net.minecraft.command.argument.BlockPosArgumentType;
import com.mojang.brigadier.arguments.BoolArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import net.Chipperfluff.chipi.world.gen.struct.ChipiStructures;
import net.minecraft.command.CommandSource;
import net.minecraft.command.argument.BlockPosArgumentType;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.world.ServerWorld;
@ -15,35 +20,57 @@ public class ChpCommand {
public static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
dispatcher.register(
CommandManager.literal("chp")
.then(CommandManager.argument("name", StringArgumentType.word())
.then(CommandManager.argument("pos", BlockPosArgumentType.blockPos())
.executes(ctx -> {
String name =
StringArgumentType.getString(ctx, "name");
BlockPos center =
BlockPosArgumentType.getBlockPos(ctx, "pos");
ServerWorld world =
ctx.getSource().getWorld();
var structure =
ChipiStructures.get(name);
if (structure == null) {
ctx.getSource().sendError(
Text.literal("Unknown structure: " + name)
);
return 0;
}
structure.place(world, center);
return 1;
})
)
CommandManager.literal("chp")
.then(CommandManager.argument("name", StringArgumentType.word())
// autocomplete structure names
.suggests((ctx, builder) ->
CommandSource.suggestMatching(
ChipiStructures.getNames(),
builder
)
)
.then(CommandManager.argument("pos", BlockPosArgumentType.blockPos())
// default: no marker
.executes(ctx -> execute(ctx, false))
// optional marker flag
.then(CommandManager.argument("marker", BoolArgumentType.bool())
.executes(ctx ->
execute(ctx, BoolArgumentType.getBool(ctx, "marker"))
)
)
)
)
);
}
private static int execute(
CommandContext<ServerCommandSource> ctx,
boolean marker
) {
ServerCommandSource source = ctx.getSource();
ServerWorld world = source.getWorld();
String name = StringArgumentType.getString(ctx, "name");
BlockPos pos = BlockPosArgumentType.getBlockPos(ctx, "pos");
var structure = ChipiStructures.get(name);
if (structure == null) {
source.sendError(Text.literal("Unknown structure: " + name));
return 0;
}
// SINGLE call structure decides everything
structure.placeCommand(world, pos, marker);
source.sendFeedback(
() -> Text.literal(
"Placed structure '" + name +
(marker ? "' with structure block" : "'")
),
false
);
return 1;
}
}

View File

@ -2,7 +2,12 @@ package net.Chipperfluff.chipi.world.gen;
import net.Chipperfluff.chipi.world.gen.struct.CorridorNSStructure;
import net.Chipperfluff.chipi.world.gen.struct.RoomBaseStructure;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.enums.BlockHalf;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.state.property.Properties;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.BlockPos;
public class ChipiDungeonGenerator {
@ -12,17 +17,18 @@ public class ChipiDungeonGenerator {
private static final int ROOM_EXTENT_NORTH = 8;
// Fixed Y-levels
private static final int ROOM_Y = 88;
private static final int ROOM_Y = 89;
private static final int CORRIDOR_Y = 89;
// Corridors are 10 long; place them with a 1-block gap from room walls (-1 overlap into each room)
private static final int GAP_TO_CORRIDOR = 1;
// Corridors are 10 long; they should overwrite 1 block into each room (-1 on both ends).
private static final int CORRIDOR_LENGTH = 10;
// Center-to-center step so corridors start 1 block after the room wall and end 1 block before the next
private static final int STEP_Z = ROOM_EXTENT_SOUTH + GAP_TO_CORRIDOR + CORRIDOR_LENGTH + ROOM_EXTENT_NORTH; // 27
// Center-to-center step so corridors start 1 block inside the north room and end 1 block inside the south room.
private static final int STEP_Z = ROOM_EXTENT_SOUTH + CORRIDOR_LENGTH + ROOM_EXTENT_NORTH - 1; // 25
private static final int STEP_X = STEP_Z; // symmetric spacing on X
private static final int ROWS_SOUTH = 40; // total rooms including the first fixed one
private static final int ROWS_SOUTH = 40; // rows of rooms south of spawn (spawn room itself is already placed)
private static final int COLS_EW = 40; // columns across X (split roughly evenly around center)
private static RoomBaseStructure getRoom() {
return new RoomBaseStructure();
@ -36,38 +42,108 @@ public class ChipiDungeonGenerator {
public static void generateInitialLayout(ServerWorld world, BlockPos portalSpawnPos) {
// Fixed anchors (not relative to portal): first corridor then the first room.
// Spawn is already placed. Fixed anchors (not relative to portal):
// first corridor origin, then the first generated room center is south of spawn.
BlockPos firstCorridorAnchor = new BlockPos(5, CORRIDOR_Y, 11);
BlockPos firstRoomCenter = new BlockPos(5, ROOM_Y, 11);
BlockPos firstGeneratedRoomCenter = new BlockPos(5, ROOM_Y, 24); // explicit first floor anchor
// First room/corridor use direct instances as requested.
RoomBaseStructure firstRoom = new RoomBaseStructure();
CorridorNSStructure firstCorridor = new CorridorNSStructure();
RoomBaseStructure room = getRoom();
CorridorNSStructure corridorNS = getTunnelNS();
// Place the fixed corridor and first room.
corridorNS.place(world, firstCorridorAnchor);
room.place(world, firstRoomCenter);
// Place the first room (absolute coordinates).
firstRoom.placeAt(world, firstGeneratedRoomCenter);
// Place remaining rooms strictly southward (Z never decreases).
for (int row = 1; row < ROWS_SOUTH; row++) {
BlockPos center = firstRoomCenter.add(
0,
0,
row * STEP_Z
);
room.place(world, center);
// Place the fixed corridor leaving spawn intact.
firstCorridor.placeAt(world, firstCorridorAnchor);
// Column range centered on x=5 for a 40-wide grid (approx. 20 each side).
int minCol = -(COLS_EW / 2) + 1; // -19 for 40 cols -> -19..20 inclusive
int maxCol = (COLS_EW / 2); // 20
// Place rooms strictly southward (Z never decreases), across X in both directions.
for (int row = 0; row < ROWS_SOUTH; row++) {
for (int col = minCol; col <= maxCol; col++) {
BlockPos center = new BlockPos(
firstGeneratedRoomCenter.getX() + (col * STEP_X),
ROOM_Y,
firstGeneratedRoomCenter.getZ() + (row * STEP_Z)
);
room.placeAt(world, center);
}
}
// Connect each room to the next one south with a corridor at fixed Y.
// Connect each room to the next one south with a corridor at fixed Y (no northward connections).
for (int row = 0; row < ROWS_SOUTH - 1; row++) {
BlockPos currentCenter = firstRoomCenter.add(0, 0, row * STEP_Z);
for (int col = minCol; col <= maxCol; col++) {
BlockPos currentCenter = new BlockPos(
firstGeneratedRoomCenter.getX() + (col * STEP_X),
ROOM_Y,
firstGeneratedRoomCenter.getZ() + (row * STEP_Z)
);
BlockPos anchorSouth = new BlockPos(
currentCenter.getX(),
CORRIDOR_Y,
currentCenter.getZ() + ROOM_EXTENT_SOUTH + GAP_TO_CORRIDOR
);
BlockPos anchorSouth = new BlockPos(
currentCenter.getX(),
CORRIDOR_Y,
currentCenter.getZ() + ROOM_EXTENT_SOUTH
);
corridorNS.place(world, anchorSouth);
corridorNS.placeAt(world, anchorSouth);
}
}
cleanUpEntrance(world);
}
/** Runs the post-placement cleanup/decoration around spawn and first room. */
private static void cleanUpEntrance(ServerWorld world) {
runInChipi(world, "fill 7 87 15 3 91 16 minecraft:air");
runInChipi(world, "setblock 4 88 15 minecraft:deepslate_tile_stairs[facing=west,waterlogged=true]");
runInChipi(world, "setblock 4 88 16 minecraft:deepslate_tile_stairs[facing=west,waterlogged=true]");
runInChipi(world, "setblock 6 88 15 minecraft:deepslate_tile_stairs[facing=east,waterlogged=true]");
runInChipi(world, "setblock 6 88 16 minecraft:deepslate_tile_stairs[facing=east,waterlogged=true]");
runInChipi(world, "fill 7 88 15 7 91 16 minecraft:deepslate_tiles");
runInChipi(world, "fill 3 88 16 3 91 15 minecraft:deepslate_tiles");
runInChipi(world, "setblock 4 90 15 minecraft:deepslate_tile_stairs[facing=west,half=top]");
runInChipi(world, "setblock 4 90 16 minecraft:deepslate_tile_stairs[facing=west,half=top]");
runInChipi(world, "setblock 6 90 15 minecraft:deepslate_tile_stairs[facing=east,half=top]");
runInChipi(world, "setblock 6 90 16 minecraft:deepslate_tile_stairs[facing=east,half=top]");
runInChipi(world, "fill 5 88 15 5 87 16 minecraft:deepslate_tile_slab[waterlogged=true]");
runInChipi(world, "fill 5 91 16 5 91 15 minecraft:deepslate_tiles");
}
private static void fillBox(ServerWorld world, int x1, int y1, int z1,
int x2, int y2, int z2, BlockState state) {
int minX = Math.min(x1, x2);
int maxX = Math.max(x1, x2);
int minY = Math.min(y1, y2);
int maxY = Math.max(y1, y2);
int minZ = Math.min(z1, z2);
int maxZ = Math.max(z1, z2);
for (int x = minX; x <= maxX; x++) {
for (int y = minY; y <= maxY; y++) {
for (int z = minZ; z <= maxZ; z++) {
world.setBlockState(new BlockPos(x, y, z), state, 3);
}
}
}
}
private static void runInChipi(ServerWorld world, String command) {
world.getServer()
.getCommandManager()
.executeWithPrefix(
world.getServer().getCommandSource(),
"execute in chipi:chipi_dimension run " + command
);
}
}

View File

@ -1,24 +1,48 @@
package net.Chipperfluff.chipi.world.gen;
import net.minecraft.block.Blocks;
import net.minecraft.block.entity.StructureBlockBlockEntity;
import net.minecraft.block.enums.StructureBlockMode;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.structure.StructurePlacementData;
import net.minecraft.structure.StructureTemplate;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import java.util.Optional;
public abstract class ChipiStructure {
protected final Identifier id;
protected ChipiStructure(Identifier id) {
/** Offset from STRUCTURE BLOCK → actual structure origin */
protected final int deltaX;
protected final int deltaY;
protected final int deltaZ;
protected ChipiStructure(Identifier id, int deltaX, int deltaY, int deltaZ) {
this.id = id;
this.deltaX = deltaX;
this.deltaY = deltaY;
this.deltaZ = deltaZ;
}
/** Override this per structure */
protected abstract BlockPos centerToOrigin(BlockPos center, StructureTemplate template);
/** REAL size from NBT */
public BlockPos getSize(ServerWorld world) {
Optional<StructureTemplate> opt =
world.getStructureTemplateManager().getTemplate(id);
public void place(ServerWorld world, BlockPos center) {
var opt = world.getStructureTemplateManager().getTemplate(id);
if (opt.isEmpty()) return BlockPos.ORIGIN;
Vec3i size = opt.get().getSize();
return new BlockPos(size.getX(), size.getY(), size.getZ());
}
/** Pure structure placement */
public void placeAt(ServerWorld world, BlockPos origin) {
Optional<StructureTemplate> opt =
world.getStructureTemplateManager().getTemplate(id);
if (opt.isEmpty()) {
System.out.println("[CHIPI] Missing structure: " + id);
@ -26,7 +50,6 @@ public abstract class ChipiStructure {
}
StructureTemplate template = opt.get();
BlockPos origin = centerToOrigin(center, template);
template.place(
world,
@ -36,8 +59,30 @@ public abstract class ChipiStructure {
world.getRandom(),
2
);
}
System.out.println("[CHIPI] Placed " + id + " at center " + center +
" (origin " + origin + ")");
/** Command placement (structure + optional marker) */
public void placeCommand(ServerWorld world, BlockPos placePos, boolean marker) {
BlockPos origin = placePos.add(
new BlockPos(deltaX, deltaY, deltaZ)
);
placeAt(world, origin);
if (!marker) return;
world.setBlockState(origin, Blocks.STRUCTURE_BLOCK.getDefaultState(), 3);
if (world.getBlockEntity(origin) instanceof StructureBlockBlockEntity be) {
be.setMode(StructureBlockMode.SAVE);
be.setTemplateName(id);
be.setSize(getSize(world));
be.setIgnoreEntities(false);
be.setShowAir(true);
be.setShowBoundingBox(true);
be.markDirty();
}
}
}

View File

@ -3,6 +3,7 @@ package net.Chipperfluff.chipi.world.gen.struct;
import net.Chipperfluff.chipi.world.gen.ChipiStructure; // <-- THIS WAS MISSING
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class ChipiStructures {
@ -15,6 +16,11 @@ public class ChipiStructures {
REGISTRY.put("corridor_ew", new CorridorEWStructure());
}
public static Set<String> getNames() {
return REGISTRY.keySet();
}
public static ChipiStructure get(String name) {
return REGISTRY.get(name);
}

View File

@ -9,17 +9,6 @@ import net.minecraft.util.math.Vec3i;
public class CorridorEWStructure extends ChipiStructure {
public CorridorEWStructure() {
super(new Identifier("chipi", "coridor_straight_ew"));
}
@Override
protected BlockPos centerToOrigin(BlockPos center, StructureTemplate template) {
Vec3i size = template.getSize();
// west side centered at (0,0,0)
return center.add(
0,
-2,
-2
);
super(new Identifier("chipi", "coridor_straight_ew"), 0, -2, -2);
}
}

View File

@ -9,17 +9,6 @@ import net.minecraft.util.math.Vec3i;
public class CorridorNSStructure extends ChipiStructure {
public CorridorNSStructure() {
super(new Identifier("chipi", "coridor_straight_ns"));
}
@Override
protected BlockPos centerToOrigin(BlockPos center, StructureTemplate template) {
Vec3i size = template.getSize();
//north side centered at (0,0,0)
return center.add(
-2,
-2,
0
);
super(new Identifier("chipi", "coridor_straight_ns"), -2, -2, 0);
}
}

View File

@ -9,17 +9,6 @@ import net.minecraft.util.math.Vec3i;
public class RoomBaseStructure extends ChipiStructure {
public RoomBaseStructure() {
super(new Identifier("chipi", "room_base"));
}
@Override
protected BlockPos centerToOrigin(BlockPos center, StructureTemplate template) {
Vec3i size = template.getSize();
return center.add(
-9,
-1,
-8
);
super(new Identifier("chipi", "room_base"), -9, -1, -8);
}
}

View File

@ -9,17 +9,6 @@ import net.minecraft.util.math.Vec3i;
public class SpawnStructure extends ChipiStructure {
public SpawnStructure() {
super(new Identifier("chipi", "spawn"));
}
@Override
protected BlockPos centerToOrigin(BlockPos center, StructureTemplate template) {
Vec3i size = template.getSize();
return center.add(
-5,
-9,
-6
);
super(new Identifier("chipi", "spawn"), -5, -9, -6);
}
}