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; package net.Chipperfluff.chipi.command;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import net.Chipperfluff.chipi.world.gen.struct.ChipiStructures; import com.mojang.brigadier.arguments.BoolArgumentType;
import net.minecraft.command.argument.BlockPosArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType; 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.CommandManager;
import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
@ -17,33 +22,55 @@ public class ChpCommand {
dispatcher.register( dispatcher.register(
CommandManager.literal("chp") CommandManager.literal("chp")
.then(CommandManager.argument("name", StringArgumentType.word()) .then(CommandManager.argument("name", StringArgumentType.word())
// autocomplete structure names
.suggests((ctx, builder) ->
CommandSource.suggestMatching(
ChipiStructures.getNames(),
builder
)
)
.then(CommandManager.argument("pos", BlockPosArgumentType.blockPos()) .then(CommandManager.argument("pos", BlockPosArgumentType.blockPos())
.executes(ctx -> { // 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"))
)
)
)
)
);
}
String name = private static int execute(
StringArgumentType.getString(ctx, "name"); CommandContext<ServerCommandSource> ctx,
boolean marker
) {
ServerCommandSource source = ctx.getSource();
ServerWorld world = source.getWorld();
BlockPos center = String name = StringArgumentType.getString(ctx, "name");
BlockPosArgumentType.getBlockPos(ctx, "pos"); BlockPos pos = BlockPosArgumentType.getBlockPos(ctx, "pos");
ServerWorld world = var structure = ChipiStructures.get(name);
ctx.getSource().getWorld();
var structure =
ChipiStructures.get(name);
if (structure == null) { if (structure == null) {
ctx.getSource().sendError( source.sendError(Text.literal("Unknown structure: " + name));
Text.literal("Unknown structure: " + name)
);
return 0; return 0;
} }
structure.place(world, center); // SINGLE call structure decides everything
return 1; 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.CorridorNSStructure;
import net.Chipperfluff.chipi.world.gen.struct.RoomBaseStructure; 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.server.world.ServerWorld;
import net.minecraft.state.property.Properties;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
public class ChipiDungeonGenerator { public class ChipiDungeonGenerator {
@ -12,17 +17,18 @@ public class ChipiDungeonGenerator {
private static final int ROOM_EXTENT_NORTH = 8; private static final int ROOM_EXTENT_NORTH = 8;
// Fixed Y-levels // Fixed Y-levels
private static final int ROOM_Y = 88; private static final int ROOM_Y = 89;
private static final int CORRIDOR_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) // Corridors are 10 long; they should overwrite 1 block into each room (-1 on both ends).
private static final int GAP_TO_CORRIDOR = 1;
private static final int CORRIDOR_LENGTH = 10; 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 // 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 + GAP_TO_CORRIDOR + CORRIDOR_LENGTH + ROOM_EXTENT_NORTH; // 27 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() { private static RoomBaseStructure getRoom() {
return new RoomBaseStructure(); return new RoomBaseStructure();
@ -36,38 +42,108 @@ public class ChipiDungeonGenerator {
public static void generateInitialLayout(ServerWorld world, BlockPos portalSpawnPos) { 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 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(); RoomBaseStructure room = getRoom();
CorridorNSStructure corridorNS = getTunnelNS(); CorridorNSStructure corridorNS = getTunnelNS();
// Place the fixed corridor and first room. // Place the first room (absolute coordinates).
corridorNS.place(world, firstCorridorAnchor); firstRoom.placeAt(world, firstGeneratedRoomCenter);
room.place(world, firstRoomCenter);
// Place remaining rooms strictly southward (Z never decreases). // Place the fixed corridor leaving spawn intact.
for (int row = 1; row < ROWS_SOUTH; row++) { firstCorridor.placeAt(world, firstCorridorAnchor);
BlockPos center = firstRoomCenter.add(
0, // Column range centered on x=5 for a 40-wide grid (approx. 20 each side).
0, int minCol = -(COLS_EW / 2) + 1; // -19 for 40 cols -> -19..20 inclusive
row * STEP_Z 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.place(world, center); 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++) { 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( BlockPos anchorSouth = new BlockPos(
currentCenter.getX(), currentCenter.getX(),
CORRIDOR_Y, CORRIDOR_Y,
currentCenter.getZ() + ROOM_EXTENT_SOUTH + GAP_TO_CORRIDOR 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; 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.server.world.ServerWorld;
import net.minecraft.structure.StructurePlacementData; import net.minecraft.structure.StructurePlacementData;
import net.minecraft.structure.StructureTemplate; import net.minecraft.structure.StructureTemplate;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import java.util.Optional;
public abstract class ChipiStructure { public abstract class ChipiStructure {
protected final Identifier id; 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.id = id;
this.deltaX = deltaX;
this.deltaY = deltaY;
this.deltaZ = deltaZ;
} }
/** Override this per structure */ /** REAL size from NBT */
protected abstract BlockPos centerToOrigin(BlockPos center, StructureTemplate template); public BlockPos getSize(ServerWorld world) {
Optional<StructureTemplate> opt =
world.getStructureTemplateManager().getTemplate(id);
public void place(ServerWorld world, BlockPos center) { if (opt.isEmpty()) return BlockPos.ORIGIN;
var opt = world.getStructureTemplateManager().getTemplate(id);
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()) { if (opt.isEmpty()) {
System.out.println("[CHIPI] Missing structure: " + id); System.out.println("[CHIPI] Missing structure: " + id);
@ -26,7 +50,6 @@ public abstract class ChipiStructure {
} }
StructureTemplate template = opt.get(); StructureTemplate template = opt.get();
BlockPos origin = centerToOrigin(center, template);
template.place( template.place(
world, world,
@ -36,8 +59,30 @@ public abstract class ChipiStructure {
world.getRandom(), world.getRandom(),
2 2
); );
}
System.out.println("[CHIPI] Placed " + id + " at center " + center + /** Command placement (structure + optional marker) */
" (origin " + origin + ")"); 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 net.Chipperfluff.chipi.world.gen.ChipiStructure; // <-- THIS WAS MISSING
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
public class ChipiStructures { public class ChipiStructures {
@ -15,6 +16,11 @@ public class ChipiStructures {
REGISTRY.put("corridor_ew", new CorridorEWStructure()); REGISTRY.put("corridor_ew", new CorridorEWStructure());
} }
public static Set<String> getNames() {
return REGISTRY.keySet();
}
public static ChipiStructure get(String name) { public static ChipiStructure get(String name) {
return REGISTRY.get(name); return REGISTRY.get(name);
} }

View File

@ -9,17 +9,6 @@ import net.minecraft.util.math.Vec3i;
public class CorridorEWStructure extends ChipiStructure { public class CorridorEWStructure extends ChipiStructure {
public CorridorEWStructure() { public CorridorEWStructure() {
super(new Identifier("chipi", "coridor_straight_ew")); super(new Identifier("chipi", "coridor_straight_ew"), 0, -2, -2);
}
@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
);
} }
} }

View File

@ -9,17 +9,6 @@ import net.minecraft.util.math.Vec3i;
public class CorridorNSStructure extends ChipiStructure { public class CorridorNSStructure extends ChipiStructure {
public CorridorNSStructure() { public CorridorNSStructure() {
super(new Identifier("chipi", "coridor_straight_ns")); super(new Identifier("chipi", "coridor_straight_ns"), -2, -2, 0);
}
@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
);
} }
} }

View File

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

View File

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