This commit is contained in:
Chipperfluff 2025-12-18 01:25:05 +01:00
parent 7402a4a43b
commit b099760126
6 changed files with 126 additions and 68 deletions

1
add-build-alias.sh Normal file
View File

@ -0,0 +1 @@
alias shit="clear;rm -rf run;./gradlew runClient --stacktrace --info;echo '';tree --gitignore"

View File

@ -4,16 +4,19 @@ import net.Chipperfluff.chipi.command.ChpCommand;
import net.Chipperfluff.chipi.item.ModItems; import net.Chipperfluff.chipi.item.ModItems;
import net.Chipperfluff.chipi.block.ModBlocks; import net.Chipperfluff.chipi.block.ModBlocks;
import net.Chipperfluff.chipi.world.gen.ChipiDungeonGenerator; import net.Chipperfluff.chipi.world.gen.ChipiDungeonGenerator;
import net.Chipperfluff.chipi.block.ChipperPortalBlock;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
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.entity.player.PlayerEntity;
import net.minecraft.world.GameRules; import net.minecraft.world.GameRules;
import net.Chipperfluff.chipi.item.ModItemGroups; import net.Chipperfluff.chipi.item.ModItemGroups;
import net.fabricmc.fabric.api.biome.v1.BiomeModifications; import net.fabricmc.fabric.api.biome.v1.BiomeModifications;
@ -56,6 +59,16 @@ public class ChipiMod implements ModInitializer {
ChpCommand.register(dispatcher) ChpCommand.register(dispatcher)
); );
ServerTickEvents.END_WORLD_TICK.register(world -> {
if (!world.getRegistryKey().getValue().equals(CHIPI_DIM)) return;
for (PlayerEntity player : world.getPlayers()) {
if (player.getBlockY() >= 50) continue;
ChipperPortalBlock.teleportToChipiSpawn(world, player);
}
});
ServerWorldEvents.LOAD.register((server, world) -> { ServerWorldEvents.LOAD.register((server, world) -> {
if (!world.getRegistryKey().getValue().equals(CHIPI_DIM)) return; if (!world.getRegistryKey().getValue().equals(CHIPI_DIM)) return;

View File

@ -1,5 +1,7 @@
package net.Chipperfluff.chipi.block; package net.Chipperfluff.chipi.block;
import java.util.EnumSet;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext; import net.minecraft.block.ShapeContext;
@ -16,10 +18,11 @@ import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView; import net.minecraft.world.BlockView;
import net.minecraft.world.World; import net.minecraft.world.World;
import java.util.EnumSet;
public class ChipperPortalBlock extends Block { public class ChipperPortalBlock extends Block {
private static final BlockPos DEFAULT_SPAWN = new BlockPos(5, 90, 6);
private static final Identifier CHIPI_DIM_ID = new Identifier("chipi", "chipi_dimension");
public ChipperPortalBlock(Settings settings) { public ChipperPortalBlock(Settings settings) {
super(settings); super(settings);
} }
@ -45,32 +48,10 @@ public class ChipperPortalBlock extends Block {
if (world.isClient) return; if (world.isClient) return;
if (!(entity instanceof PlayerEntity player)) return; if (!(entity instanceof PlayerEntity player)) return;
ServerWorld targetWorld = world.getServer().getWorld( ServerWorld targetWorld = getChipiWorld(world);
RegistryKey.of(
RegistryKeys.WORLD,
new Identifier("chipi", "chipi_dimension")
)
);
if (targetWorld == null) return; if (targetWorld == null) return;
// SAFE spawn position inside your dungeon teleportToChipiSpawn(targetWorld, player);
BlockPos spawn = new BlockPos(5, 90, 6);
// Safety: make sure feet are not in air
if (!targetWorld.getBlockState(spawn.down()).isSolidBlock(targetWorld, spawn.down())) {
spawn = spawn.up();
}
player.teleport(
targetWorld,
spawn.getX() + 0.5,
spawn.getY(),
spawn.getZ() + 0.5,
EnumSet.noneOf(PositionFlag.class),
player.getYaw(),
player.getPitch()
);
} }
@Override @Override
@ -84,4 +65,36 @@ public class ChipperPortalBlock extends Block {
? super.calcBlockBreakingDelta(state, player, world, pos) ? super.calcBlockBreakingDelta(state, player, world, pos)
: 0.0F; : 0.0F;
} }
public static void teleportToChipiSpawn(ServerWorld targetWorld, PlayerEntity player) {
BlockPos spawn = resolveSafeSpawn(targetWorld);
player.teleport(
targetWorld,
spawn.getX() + 0.5,
spawn.getY(),
spawn.getZ() + 0.5,
EnumSet.noneOf(PositionFlag.class),
player.getYaw(),
player.getPitch()
);
}
public static BlockPos resolveSafeSpawn(ServerWorld targetWorld) {
BlockPos spawn = DEFAULT_SPAWN;
BlockPos under = spawn.down();
if (!targetWorld.getBlockState(under).isSolidBlock(targetWorld, under)) {
spawn = spawn.up();
}
return spawn;
}
public static ServerWorld getChipiWorld(World world) {
if (world == null || world.getServer() == null) return null;
RegistryKey<World> key = RegistryKey.of(RegistryKeys.WORLD, CHIPI_DIM_ID);
return world.getServer().getWorld(key);
}
} }

View File

@ -39,8 +39,6 @@ public class ChipiDungeonGenerator {
BlockPos firstCorridorAnchor = new BlockPos(5, CORRIDOR_Y, 11); BlockPos firstCorridorAnchor = new BlockPos(5, CORRIDOR_Y, 11);
BlockPos firstGeneratedRoomCenter = new BlockPos(5, ROOM_Y, 24); // explicit first floor anchor BlockPos firstGeneratedRoomCenter = new BlockPos(5, ROOM_Y, 24); // explicit first floor anchor
DungeonContext ctx = DungeonContext.EMPTY;
// First room/corridor use direct instances as requested. // First room/corridor use direct instances as requested.
RoomBaseStructure firstRoom = WorldMaster.getDefaultRoom(); RoomBaseStructure firstRoom = WorldMaster.getDefaultRoom();
CorridorNSStructure firstCorridor = WorldMaster.getDefaultCorridorNS(); CorridorNSStructure firstCorridor = WorldMaster.getDefaultCorridorNS();
@ -67,8 +65,13 @@ public class ChipiDungeonGenerator {
firstGeneratedRoomCenter.getZ() + (row * STEP_Z) firstGeneratedRoomCenter.getZ() + (row * STEP_Z)
); );
RoomBaseStructure room = WorldMaster.resolveRoom(gridX, gridY, ctx); RoomBaseStructure room = WorldMaster.resolveRoom(
ctx(gridX, gridY, center, null)
);
room.placeAt(world, center); room.placeAt(world, center);
WorldMaster.afterPlaceRoom(
ctx(gridX, gridY, center, room)
);
} }
} }
@ -90,8 +93,13 @@ public class ChipiDungeonGenerator {
currentCenter.getZ() + ROOM_EXTENT_SOUTH currentCenter.getZ() + ROOM_EXTENT_SOUTH
); );
CorridorNSStructure corridorNS = WorldMaster.resolveCorridorNS(gridX, gridY, ctx); CorridorNSStructure corridorNS = WorldMaster.resolveCorridorNS(
ctx(gridX, gridY, anchorSouth, null)
);
corridorNS.placeAt(world, anchorSouth); corridorNS.placeAt(world, anchorSouth);
WorldMaster.afterPlaceCorridorNS(
ctx(gridX, gridY, anchorSouth, corridorNS)
);
} }
} }
@ -113,8 +121,13 @@ public class ChipiDungeonGenerator {
currentCenter.getZ() currentCenter.getZ()
); );
CorridorEWStructure corridorEW = WorldMaster.resolveCorridorEW(gridX, gridY, ctx); CorridorEWStructure corridorEW = WorldMaster.resolveCorridorEW(
ctx(gridX, gridY, anchorEast, null)
);
corridorEW.placeAt(world, anchorEast); corridorEW.placeAt(world, anchorEast);
WorldMaster.afterPlaceCorridorEW(
ctx(gridX, gridY, anchorEast, corridorEW)
);
} }
} }
@ -169,4 +182,8 @@ public class ChipiDungeonGenerator {
"execute in chipi:chipi_dimension run " + command "execute in chipi:chipi_dimension run " + command
); );
} }
private static DungeonContext ctx(int gridX, int gridY, BlockPos origin, ChipiStructure structure) {
return DungeonContext.of(gridX, gridY, origin, structure);
}
} }

View File

@ -1,11 +1,42 @@
package net.Chipperfluff.chipi.world.gen; package net.Chipperfluff.chipi.world.gen;
/** import net.minecraft.util.math.BlockPos;
* Placeholder context for dungeon generation decisions. import net.Chipperfluff.chipi.world.gen.ChipiStructure;
* Will later hold seed, reservations, phases, etc.
*/
public final class DungeonContext { public final class DungeonContext {
public static final DungeonContext EMPTY = new 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 DungeonContext() {} private DungeonContext() {}
private DungeonContext(Integer grid_x, Integer grid_y, BlockPos structure_origin, ChipiStructure structure) {
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 Integer getGridX() {
return grid_x;
}
public Integer getGridY() {
return grid_y;
}
public BlockPos getStructureOrigin() {
return structure_origin;
}
public ChipiStructure getStructure() {
return structure;
}
} }

View File

@ -20,46 +20,29 @@ public final class WorldMaster {
return new CorridorEWStructure(); return new CorridorEWStructure();
} }
/** public static RoomBaseStructure resolveRoom(DungeonContext ctx) {
* Decide which ROOM exists at this grid position.
*
* @param gridX logical dungeon grid X
* @param gridY logical dungeon grid Y
* @param ctx snapshot of dungeon state (seed, reserved map, phase, etc.)
*/
public static RoomBaseStructure resolveRoom(
int gridX,
int gridY,
DungeonContext ctx
) {
// later:
// - check reserved HashMap
// - check spawn/boss rules
// - check generation phase
// - check random seed
return getDefaultRoom(); return getDefaultRoom();
} }
/** public static CorridorNSStructure resolveCorridorNS(DungeonContext ctx) {
* Decide which NORTH-SOUTH corridor exists at this grid position.
*/
public static CorridorNSStructure resolveCorridorNS(
int gridX,
int gridY,
DungeonContext ctx
) {
return getDefaultCorridorNS(); return getDefaultCorridorNS();
} }
/** public static CorridorEWStructure resolveCorridorEW(DungeonContext ctx) {
* Decide which EAST-WEST corridor exists at this grid position. return getDefaultCorridorEW();
*/ }
public static CorridorEWStructure resolveCorridorEW(
int gridX, public static RoomBaseStructure afterPlaceRoom(DungeonContext ctx) {
int gridY,
DungeonContext ctx return getDefaultRoom();
) { }
public static CorridorNSStructure afterPlaceCorridorNS(DungeonContext ctx) {
return getDefaultCorridorNS();
}
public static CorridorEWStructure afterPlaceCorridorEW(DungeonContext ctx) {
return getDefaultCorridorEW(); return getDefaultCorridorEW();
} }
} }