feat(UC-02): data-driven room theme infrastructure (Phase 1+2)
- BlockPalette: weighted random block selection with condition variants - RoomThemeDefinition: immutable record with wallBlock/floorBlock/etc convenience API - DecorationConfig: positioned block records for theme-specific decorations - RoomThemeRegistry: volatile atomic snapshot + pickRandom(weight-based) - RoomThemeParser: JSON parsing with BlockStateParser + random_property expansion - RoomThemeReloadListener: scans data/<ns>/tiedup_room_themes/*.json - Register listener in TiedUpMod.onAddReloadListeners()
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
package com.tiedup.remake.worldgen;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Immutable data-driven room theme definition, replacing the old {@link RoomTheme} enum.
|
||||
*
|
||||
* <p>Loaded from {@code data/<namespace>/tiedup_room_themes/*.json} and stored
|
||||
* in {@link RoomThemeRegistry}. Convenience methods mirror the old
|
||||
* abstract API so that {@code HangingCagePiece} can swap with minimal changes.</p>
|
||||
*
|
||||
* @param id unique identifier (e.g. "tiedup:oubliette")
|
||||
* @param weight random selection weight (higher = more likely)
|
||||
* @param wallPalette palette for wall blocks (supports "default" and "bottom_row")
|
||||
* @param floorPalette palette for floor blocks (supports "default", "edge", "corner")
|
||||
* @param ceilingPalette palette for ceiling blocks
|
||||
* @param wallShellBlock single block used for the outer wall shell
|
||||
* @param wallAccentBlock single accent block (e.g. for frames, trims)
|
||||
* @param pillarPalette palette for pillars (supports "default" and "cap")
|
||||
* @param scatterPalette optional palette for scatter decorations (cobwebs, etc.)
|
||||
* @param decorations decoration configuration (corners, midpoints, furniture, etc.)
|
||||
*/
|
||||
public record RoomThemeDefinition(
|
||||
ResourceLocation id,
|
||||
int weight,
|
||||
BlockPalette wallPalette,
|
||||
BlockPalette floorPalette,
|
||||
BlockPalette ceilingPalette,
|
||||
BlockState wallShellBlock,
|
||||
BlockState wallAccentBlock,
|
||||
BlockPalette pillarPalette,
|
||||
@Nullable BlockPalette scatterPalette,
|
||||
DecorationConfig decorations
|
||||
) {
|
||||
|
||||
/**
|
||||
* Pick a wall block. Uses "bottom_row" condition for ry==1, "default" otherwise.
|
||||
*/
|
||||
public BlockState wallBlock(RandomSource random, int ry) {
|
||||
return wallPalette.pick(random, ry == 1 ? "bottom_row" : "default");
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick a floor block. Uses "corner" for corner positions, "edge" for edges,
|
||||
* "default" for interior positions.
|
||||
*/
|
||||
public BlockState floorBlock(RandomSource random, int rx, int rz, boolean isEdge) {
|
||||
boolean isCorner = (rx == 1 || rx == 11) && (rz == 1 || rz == 11);
|
||||
return floorPalette.pick(
|
||||
random, isCorner ? "corner" : isEdge ? "edge" : "default"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick a ceiling block (always "default" condition).
|
||||
*/
|
||||
public BlockState ceilingBlock(RandomSource random) {
|
||||
return ceilingPalette.pick(random, "default");
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick a pillar block. Uses "cap" for top/bottom rows, "default" for the shaft.
|
||||
*/
|
||||
public BlockState pillarBlock(RandomSource random, int ry) {
|
||||
return pillarPalette.pick(random, (ry == 1 || ry == 10) ? "cap" : "default");
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick a scatter block, or null if no scatter palette is defined.
|
||||
*/
|
||||
@Nullable
|
||||
public BlockState scatterBlock(RandomSource random) {
|
||||
return scatterPalette != null ? scatterPalette.pick(random, "default") : null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user