From 8b2ebafe5694daf455231cfb1af05ac4d2253b07 Mon Sep 17 00:00:00 2001 From: lordlogo2002 Date: Fri, 19 Dec 2025 01:01:33 +0100 Subject: [PATCH] refactor: update structure handling and context management in dungeon generation --- .../java/net/Chipperfluff/chipi/ChipiMod.java | 141 +++++++++++------- .../world/gen/ChipiDungeonGenerator.java | 16 +- .../chipi/world/gen/ChipiStructure.java | 68 ++++++--- .../chipi/world/gen/DungeonContext.java | 24 +-- .../chipi/world/gen/WorldMaster.java | 14 +- 5 files changed, 176 insertions(+), 87 deletions(-) diff --git a/src/main/java/net/Chipperfluff/chipi/ChipiMod.java b/src/main/java/net/Chipperfluff/chipi/ChipiMod.java index 3c8c6c2..3fdbf2c 100644 --- a/src/main/java/net/Chipperfluff/chipi/ChipiMod.java +++ b/src/main/java/net/Chipperfluff/chipi/ChipiMod.java @@ -16,26 +16,37 @@ import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.biome.v1.BiomeModifications; import net.fabricmc.fabric.api.biome.v1.BiomeSelectors; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents; import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryKeys; +import net.minecraft.server.MinecraftServer; +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.world.GameRules; +import net.minecraft.world.World; import net.minecraft.world.gen.GenerationStep; public class ChipiMod implements ModInitializer { public static final String MOD_ID = "chipi"; - private static final Identifier CHIPI_DIM = new Identifier("chipi", "chipi_dimension"); + public static final RegistryKey CHIPI_DIMENSION_KEY = + RegistryKey.of( + RegistryKeys.WORLD, + new Identifier("chipi", "chipi_dimension") + ); - private static final Identifier SPAWN_STRUCTURE = new Identifier("chipi", "spawn"); + private static final Identifier SPAWN_STRUCTURE = + new Identifier("chipi", "spawn"); + + private static MinecraftServer SERVER; @Override public void onInitialize() { @@ -49,72 +60,102 @@ public class ChipiMod implements ModInitializer { ChipiBlessingEvents.register(); ChipiHungerHandler.register(); - FabricDefaultAttributeRegistry.register(ModEntities.MEP, MepEntity.createMepAttributes()); + FabricDefaultAttributeRegistry.register( + ModEntities.MEP, + MepEntity.createMepAttributes() + ); BiomeModifications.addFeature( - BiomeSelectors.foundInOverworld(), - GenerationStep.Feature.UNDERGROUND_ORES, - RegistryKey.of( - RegistryKeys.PLACED_FEATURE, new Identifier("chipi", "chipper_ore"))); + BiomeSelectors.foundInOverworld(), + GenerationStep.Feature.UNDERGROUND_ORES, + RegistryKey.of( + RegistryKeys.PLACED_FEATURE, + new Identifier("chipi", "chipper_ore") + ) + ); CommandRegistrationCallback.EVENT.register( - (dispatcher, registryAccess, environment) -> ChpCommand.register(dispatcher)); + (dispatcher, registryAccess, environment) -> { + ChpCommand.register(dispatcher); + } + ); - ServerTickEvents.END_WORLD_TICK.register( - world -> { - if (!world.getRegistryKey().getValue().equals(CHIPI_DIM)) return; + ServerLifecycleEvents.SERVER_STARTED.register(server -> { + SERVER = server; + }); - for (PlayerEntity player : world.getPlayers()) { - if (player.getBlockY() >= 50) continue; + ServerTickEvents.END_WORLD_TICK.register(world -> { + if (!world.getRegistryKey().equals(CHIPI_DIMENSION_KEY)) { + return; + } - ChipperPortalBlock.teleportToChipiSpawn(world, player); - } - }); + for (PlayerEntity player : world.getPlayers()) { + if (player.getBlockY() >= 50) { + continue; + } - ServerWorldEvents.LOAD.register( - (server, world) -> { - if (!world.getRegistryKey().getValue().equals(CHIPI_DIM)) return; + ChipperPortalBlock.teleportToChipiSpawn(world, player); + } + }); - world.setTimeOfDay(18000); - world.getGameRules().get(GameRules.DO_DAYLIGHT_CYCLE).set(false, server); + ServerWorldEvents.LOAD.register((server, world) -> { + if (!world.getRegistryKey().equals(CHIPI_DIMENSION_KEY)) { + return; + } - SpawnPlacedState state = - world.getPersistentStateManager() - .getOrCreate( - SpawnPlacedState::fromNbt, - SpawnPlacedState::new, - "chipi_spawn"); + world.setTimeOfDay(18000); + world.getGameRules() + .get(GameRules.DO_DAYLIGHT_CYCLE) + .set(false, server); - if (state.placed) return; + SpawnPlacedState state = + world.getPersistentStateManager().getOrCreate( + SpawnPlacedState::fromNbt, + SpawnPlacedState::new, + "chipi_spawn" + ); - StructureTemplate spawnTemplate = - world.getStructureTemplateManager() - .getTemplate(SPAWN_STRUCTURE) - .orElse(null); + if (state.placed) { + return; + } - if (spawnTemplate == null) { - System.err.println("[CHIPI] spawn.nbt not found!"); - return; - } + StructureTemplate spawnTemplate = + world.getStructureTemplateManager() + .getTemplate(SPAWN_STRUCTURE) + .orElse(null); - BlockPos spawnCenter = new BlockPos(0, 80, 0); + if (spawnTemplate == null) { + System.err.println("[CHIPI] spawn.nbt not found!"); + return; + } - spawnTemplate.place( - world, - spawnCenter, - spawnCenter, - new StructurePlacementData(), - world.getRandom(), - 2); + BlockPos spawnCenter = new BlockPos(0, 80, 0); - world.setSpawnPos(spawnCenter.up(), 0.0f); + spawnTemplate.place( + world, + spawnCenter, + spawnCenter, + new StructurePlacementData(), + world.getRandom(), + 2 + ); - ChipiDungeonGenerator.generateInitialLayout(world, spawnCenter); + world.setSpawnPos(spawnCenter.up(), 0.0f); - state.placed = true; - state.markDirty(); + ChipiDungeonGenerator.generateInitialLayout(world, spawnCenter); - System.out.println("[CHIPI] Spawn + initial dungeon generated"); - }); + state.placed = true; + state.markDirty(); + + System.out.println("[CHIPI] Spawn + initial dungeon generated"); + }); + } + + public static ServerWorld getChipiWorld() { + if (SERVER == null) { + return null; + } + + return SERVER.getWorld(CHIPI_DIMENSION_KEY); } } diff --git a/src/main/java/net/Chipperfluff/chipi/world/gen/ChipiDungeonGenerator.java b/src/main/java/net/Chipperfluff/chipi/world/gen/ChipiDungeonGenerator.java index a68296b..1830a92 100644 --- a/src/main/java/net/Chipperfluff/chipi/world/gen/ChipiDungeonGenerator.java +++ b/src/main/java/net/Chipperfluff/chipi/world/gen/ChipiDungeonGenerator.java @@ -71,9 +71,9 @@ public class ChipiDungeonGenerator { ROOM_Y, firstGeneratedRoomCenter.getZ() + (row * STEP_Z)); - RoomBaseStructure room = WorldMaster.resolveRoom(ctx(gridX, gridY, center, null)); + RoomBaseStructure room = WorldMaster.resolveRoom(ctx(world, gridX, gridY, center, null)); room.placeAt(world, center); - WorldMaster.afterPlaceRoom(ctx(gridX, gridY, center, room)); + WorldMaster.afterPlaceRoom(ctx(world, gridX, gridY, center, room)); } } @@ -97,9 +97,9 @@ public class ChipiDungeonGenerator { currentCenter.getZ() + ROOM_EXTENT_SOUTH); CorridorNSStructure corridorNS = - WorldMaster.resolveCorridorNS(ctx(gridX, gridY, anchorSouth, null)); + WorldMaster.resolveCorridorNS(ctx(world, gridX, gridY, anchorSouth, null)); corridorNS.placeAt(world, anchorSouth); - WorldMaster.afterPlaceCorridorNS(ctx(gridX, gridY, anchorSouth, corridorNS)); + WorldMaster.afterPlaceCorridorNS(ctx(world, gridX, gridY, anchorSouth, corridorNS)); } } @@ -122,9 +122,9 @@ public class ChipiDungeonGenerator { currentCenter.getZ()); CorridorEWStructure corridorEW = - WorldMaster.resolveCorridorEW(ctx(gridX, gridY, anchorEast, null)); + WorldMaster.resolveCorridorEW(ctx(world, gridX, gridY, anchorEast, null)); corridorEW.placeAt(world, anchorEast); - WorldMaster.afterPlaceCorridorEW(ctx(gridX, gridY, anchorEast, corridorEW)); + WorldMaster.afterPlaceCorridorEW(ctx(world, gridX, gridY, anchorEast, corridorEW)); } } @@ -188,7 +188,7 @@ public class ChipiDungeonGenerator { } private static DungeonContext ctx( - int gridX, int gridY, BlockPos origin, ChipiStructure structure) { - return DungeonContext.of(gridX, gridY, origin, structure); + ServerWorld world, int gridX, int gridY, BlockPos origin, ChipiStructure structure) { + return DungeonContext.of(world, gridX, gridY, origin, structure); } } diff --git a/src/main/java/net/Chipperfluff/chipi/world/gen/ChipiStructure.java b/src/main/java/net/Chipperfluff/chipi/world/gen/ChipiStructure.java index 7e9529c..952161c 100644 --- a/src/main/java/net/Chipperfluff/chipi/world/gen/ChipiStructure.java +++ b/src/main/java/net/Chipperfluff/chipi/world/gen/ChipiStructure.java @@ -1,5 +1,7 @@ package net.Chipperfluff.chipi.world.gen; +import java.util.Optional; +import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.entity.StructureBlockBlockEntity; import net.minecraft.block.enums.StructureBlockMode; @@ -10,15 +12,10 @@ 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; - - /** Offset from STRUCTURE BLOCK → actual structure origin */ protected final int deltaX; - protected final int deltaY; protected final int deltaZ; @@ -29,41 +26,30 @@ public abstract class ChipiStructure { this.deltaZ = deltaZ; } - /** REAL size from NBT */ public BlockPos getSize(ServerWorld world) { Optional 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 centerPos) { Optional opt = world.getStructureTemplateManager().getTemplate(id); - if (opt.isEmpty()) { System.out.println("[CHIPI] Missing structure: " + id); return; } - BlockPos origin = centerPos.add(new BlockPos(deltaX, deltaY, deltaZ)); - - StructureTemplate template = opt.get(); - - template.place(world, origin, origin, new StructurePlacementData(), world.getRandom(), 2); + BlockPos origin = centerPos.add(deltaX, deltaY, deltaZ); + opt.get().place(world, origin, origin, new StructurePlacementData(), world.getRandom(), 2); } - /** Command placement (structure + optional marker) */ public void placeCommand(ServerWorld world, BlockPos placePos, boolean marker) { - placeAt(world, placePos); - BlockPos origin = placePos.add(new BlockPos(deltaX, deltaY, deltaZ)); - if (!marker) return; + BlockPos origin = placePos.add(deltaX, deltaY, deltaZ); world.setBlockState(origin, Blocks.STRUCTURE_BLOCK.getDefaultState(), 3); if (world.getBlockEntity(origin) instanceof StructureBlockBlockEntity be) { @@ -76,4 +62,48 @@ public abstract class ChipiStructure { be.markDirty(); } } + + public BlockPos local(BlockPos centerPos, BlockPos localPos) { + return centerPos.add(deltaX + localPos.getX(), deltaY + localPos.getY(), deltaZ + localPos.getZ()); + } + + public void setBlock( + ServerWorld world, + BlockPos centerPos, + BlockPos localPos, + BlockState state, + Integer gridX, + Integer gridY) { + BlockPos worldPos = local(centerPos, localPos); + System.out.println( + "[CHIPI] setBlock grid=(" + + gridX + + "," + + gridY + + ") worldPos=" + + worldPos); + world.setBlockState(worldPos, state, 3); + } + + public void fillBlocks( + ServerWorld world, + BlockPos centerPos, + BlockPos from, + BlockPos to, + BlockState state, + Integer gridX, + Integer gridY) { + BlockPos start = local(centerPos, from); + BlockPos end = local(centerPos, to); + System.out.println( + "[CHIPI] fillBlocks grid=(" + + gridX + + "," + + gridY + + ") from=" + + start + + " to=" + + end); + BlockPos.stream(start, end).forEach(pos -> world.setBlockState(pos, state, 3)); + } } diff --git a/src/main/java/net/Chipperfluff/chipi/world/gen/DungeonContext.java b/src/main/java/net/Chipperfluff/chipi/world/gen/DungeonContext.java index c42187d..fa0d56b 100644 --- a/src/main/java/net/Chipperfluff/chipi/world/gen/DungeonContext.java +++ b/src/main/java/net/Chipperfluff/chipi/world/gen/DungeonContext.java @@ -1,28 +1,34 @@ package net.Chipperfluff.chipi.world.gen; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; public final class DungeonContext { + public static final DungeonContext EMPTY = new DungeonContext(); - private Integer grid_x = null; - private Integer grid_y = null; - private BlockPos structure_origin = null; - private ChipiStructure structure = null; + private Integer grid_x; + private Integer grid_y; + private BlockPos structure_origin; + private ChipiStructure structure; + private ServerWorld world; private DungeonContext() {} - private DungeonContext( - Integer grid_x, Integer grid_y, BlockPos structure_origin, ChipiStructure structure) { + private DungeonContext(ServerWorld world, Integer grid_x, Integer grid_y, BlockPos structure_origin, ChipiStructure structure) { + this.world = world; this.grid_x = grid_x; this.grid_y = grid_y; this.structure_origin = structure_origin; this.structure = structure; } - public static DungeonContext of( - Integer grid_x, Integer grid_y, BlockPos structure_origin, ChipiStructure structure) { - return new DungeonContext(grid_x, grid_y, structure_origin, structure); + public static DungeonContext of(ServerWorld world, Integer grid_x, Integer grid_y, BlockPos structure_origin, ChipiStructure structure) { + return new DungeonContext(world, grid_x, grid_y, structure_origin, structure); + } + + public ServerWorld getWorld() { + return world; } public Integer getGridX() { diff --git a/src/main/java/net/Chipperfluff/chipi/world/gen/WorldMaster.java b/src/main/java/net/Chipperfluff/chipi/world/gen/WorldMaster.java index 6c7ee63..27e304b 100644 --- a/src/main/java/net/Chipperfluff/chipi/world/gen/WorldMaster.java +++ b/src/main/java/net/Chipperfluff/chipi/world/gen/WorldMaster.java @@ -3,6 +3,8 @@ package net.Chipperfluff.chipi.world.gen; import net.Chipperfluff.chipi.world.gen.struct.CorridorEWStructure; import net.Chipperfluff.chipi.world.gen.struct.CorridorNSStructure; import net.Chipperfluff.chipi.world.gen.struct.RoomBaseStructure; +import net.minecraft.block.Blocks; +import net.minecraft.util.math.BlockPos; public final class WorldMaster { @@ -21,7 +23,6 @@ public final class WorldMaster { } public static RoomBaseStructure resolveRoom(DungeonContext ctx) { - return getDefaultRoom(); } @@ -35,6 +36,17 @@ public final class WorldMaster { public static RoomBaseStructure afterPlaceRoom(DungeonContext ctx) { + if (ctx.getGridX() == 1 && ctx.getGridY() == 1) { + ctx.getStructure().setBlock( + ctx.getWorld(), + ctx.getStructureOrigin(), + new BlockPos(0, 0, 0), + Blocks.REDSTONE_BLOCK.getDefaultState(), + ctx.getGridX(), + ctx.getGridY() + ); + } + return getDefaultRoom(); }