refactor: update structure handling and context management in dungeon generation
This commit is contained in:
parent
dbaf8a6c0f
commit
8b2ebafe56
@ -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<World> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<StructureTemplate> 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<StructureTemplate> 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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user