Skip to main content

steel_core/worldgen/template/
mod.rs

1use std::collections::{BTreeMap, BTreeSet};
2use std::io::{Cursor, Read};
3use std::str::FromStr;
4
5use flate2::read::GzDecoder;
6use glam::{DVec3, IVec3};
7use simdnbt::borrow::{
8    Nbt as BorrowedNbt, NbtCompound as BorrowedNbtCompound,
9    NbtCompoundList as BorrowedNbtCompoundList, NbtList as BorrowedNbtList, read as read_nbt,
10    read_compound as read_borrowed_compound,
11};
12use simdnbt::owned::{NbtCompound, NbtTag};
13use steel_registry::block_entity_type::BlockEntityTypeRef;
14use steel_registry::blocks::properties::Direction as BlockPropertyDirection;
15use steel_registry::blocks::properties::{BlockStateProperties, Half};
16use steel_registry::blocks::{self};
17use steel_registry::blocks::{BlockRef, block_state_ext::BlockStateExt as _};
18use steel_registry::entity_type::EntityTypeRef;
19use steel_registry::fluid::FluidState;
20use steel_registry::shared_structs::BlockStateData;
21use steel_registry::structure::LiquidSettingsData;
22use steel_registry::structure_processor::{
23    PosRuleTestData, ProcessorRuleData, RuleBlockEntityModifierData, StructureProcessorAxis,
24    StructureProcessorKind, StructureRuleTestData,
25};
26use steel_registry::template_pool::Projection;
27use steel_registry::vanilla_block_tags::BlockTag;
28use steel_registry::{
29    Registry, RegistryExt, TaggedRegistryExt, vanilla_block_entity_types, vanilla_blocks,
30    vanilla_template_pools,
31};
32use steel_utils::random::legacy_random::LegacyRandom;
33use steel_utils::random::worldgen_random::WorldgenRandom;
34use steel_utils::random::{PositionalRandom, Random, RandomSource};
35use steel_utils::value_providers::IntProvider;
36use steel_utils::{
37    BlockPos, BlockStateId, BoundingBox, Direction, Identifier, Rotation, types::UpdateFlags,
38};
39use text_components::TextComponent;
40use uuid::Uuid;
41
42use crate::behavior::BLOCK_BEHAVIORS;
43use crate::chunk::heightmap::HeightmapType;
44use crate::entity::{
45    DEFAULT_MAX_AIR_SUPPLY, ENTITIES, EntityBaseSaveData, EntityFireFreezeState, EntityLoadRequest,
46    MAX_ENTITY_TAGS,
47};
48use crate::worldgen::region::WorldGenRegion;
49use steel_worldgen::state_resolver::WorldgenStateResolver;
50use steel_worldgen::structure::{StructureBlockIgnore, StructureMirror};
51
52/// Loaded vanilla structure template payload.
53///
54/// Steel keeps template data separate from template-pool metadata. Pools only need jigsaw
55/// summaries during structure-start planning; feature and piece placement need the full NBT
56/// block payload and processors, so this type mirrors vanilla's loaded `StructureTemplate`.
57#[derive(Debug, Clone)]
58pub(crate) struct StructureTemplate {
59    size: IVec3,
60    palettes: Vec<StructureTemplatePalette>,
61    entities: Vec<StructureEntityInfo>,
62}
63
64#[derive(Debug, Clone)]
65struct StructureTemplatePalette {
66    blocks: Vec<StructureBlockInfo>,
67}
68
69#[derive(Debug, Clone)]
70struct StructureBlockInfo {
71    pos: BlockPos,
72    state: BlockStateId,
73    nbt: Option<NbtCompound>,
74}
75
76#[derive(Debug, Clone)]
77struct StructureEntityInfo {
78    pos: DVec3,
79    block_pos: BlockPos,
80    entity_type: EntityTypeRef,
81    rotation: (f32, f32),
82    velocity: DVec3,
83    fall_distance: f64,
84    fire_freeze: EntityFireFreezeState,
85    on_ground: bool,
86    save_data: EntityBaseSaveData,
87    nbt: NbtCompound,
88}
89
90#[derive(Debug, Clone, PartialEq)]
91struct ProcessedBlockInfo {
92    template_pos: BlockPos,
93    world_pos: BlockPos,
94    state: BlockStateId,
95    nbt: Option<NbtCompound>,
96}
97
98pub(crate) struct StructureDataMarker {
99    pub(crate) metadata: String,
100    pub(crate) pos: BlockPos,
101}
102
103#[derive(Debug, Clone, Copy, PartialEq, Eq)]
104pub(crate) enum StructureProcessorRandom {
105    /// Vanilla `StructurePlaceSettings.setRandom(random)`.
106    Placement,
107    /// Vanilla `StructurePlaceSettings.getRandom(pos)` fallback.
108    Positional,
109}
110
111pub(crate) struct StructurePlaceSettings<'a> {
112    pub(crate) mirror: StructureMirror,
113    pub(crate) rotation: Rotation,
114    pub(crate) rotation_pivot: BlockPos,
115    pub(crate) bounding_box: BoundingBox,
116    pub(crate) processors: &'a [StructureProcessorKind],
117    pub(crate) block_ignore: StructureBlockIgnore,
118    pub(crate) late_block_ignore: StructureBlockIgnore,
119    pub(crate) replace_jigsaws: bool,
120    pub(crate) projection: Option<Projection>,
121    pub(crate) processor_random: StructureProcessorRandom,
122    pub(crate) liquid_settings: LiquidSettingsData,
123}
124
125mod loading;
126mod placement;
127mod processors;
128mod state_transforms;
129
130#[cfg(test)]
131mod tests;