diff --git a/pumpkin-codegen/src/structures.rs b/pumpkin-codegen/src/structures.rs index 0ddc1440b..6d2b7c38a 100644 --- a/pumpkin-codegen/src/structures.rs +++ b/pumpkin-codegen/src/structures.rs @@ -25,14 +25,23 @@ pub struct WeightedEntryStruct { #[derive(Deserialize)] pub struct StructurePlacementStruct { /// Optional frequency-reduction method name applied before placement. - frequency_reduction_method: Option, + pub frequency_reduction_method: Option, /// Optional probability (0–1) that a candidate chunk actually spawns the structure. - frequency: Option, + pub frequency: Option, /// Per-structure salt mixed into the placement RNG seed. - salt: u32, + pub salt: u32, + /// Optional exclusion zone to prevent this structure from generating near others. + pub exclusion_zone: Option, /// The specific placement algorithm and its parameters. #[serde(flatten)] - r#type: StructurePlacementTypeStruct, + pub r#type: StructurePlacementTypeStruct, +} + +/// Deserialized exclusion zone configuration. +#[derive(Deserialize)] +pub struct ExclusionZoneStruct { + pub other_set: String, + pub chunk_count: i32, } /// Deserialized placement algorithm for a structure set. @@ -70,10 +79,30 @@ pub struct StructureStruct { pub biomes: String, /// Generation step during which this structure is placed. pub step: String, + /// Optional jigsaw start pool. + pub start_pool: Option, + /// Optional jigsaw size (depth). + pub size: Option, + /// Optional terrain adaptation (bearding). + pub terrain_adaptation: Option, + /// Optional jigsaw start height. + pub start_height: Option, + /// Optional heightmap to project the start to. + pub project_start_to_heightmap: Option, + /// Optional max distance from center. + pub max_distance_from_center: Option, + /// Optional liquid settings. + pub liquid_settings: Option, + /// Optional dimension padding. + pub dimension_padding: Option, + /// Critical for villages to appropriately truncate long village streets. + pub use_expansion_hack: Option, + /// Defines the generation behavior (e.g. "minecraft:jigsaw"). + #[serde(rename = "type")] + pub structure_type: String, } impl ToTokens for StructureSetStruct { - /// Emits a `StructureSet { … }` struct literal token stream for the wrapped structure set. fn to_tokens(&self, tokens: &mut TokenStream) { let placement = &self.placement; let structures = &self.structures; @@ -88,7 +117,6 @@ impl ToTokens for StructureSetStruct { } impl ToTokens for WeightedEntryStruct { - /// Emits a `WeightedEntry { … }` struct literal token stream for the wrapped entry. fn to_tokens(&self, tokens: &mut TokenStream) { let structure = structure_key_to_token(&self.structure); let weight = self.weight; @@ -103,7 +131,6 @@ impl ToTokens for WeightedEntryStruct { } impl ToTokens for StructurePlacementStruct { - /// Emits a `StructurePlacement { … }` struct literal token stream for the wrapped placement config. fn to_tokens(&self, tokens: &mut TokenStream) { let frequency_reduction = if let Some(method) = &self.frequency_reduction_method { let method_token = frequency_reduction_to_token(method); @@ -118,6 +145,17 @@ impl ToTokens for StructurePlacementStruct { quote!(None) }; + let exclusion_zone = if let Some(ez) = &self.exclusion_zone { + let other_set = &ez.other_set; + let chunk_count = ez.chunk_count; + quote!(Some(ExclusionZone { + other_set: #other_set, + chunk_count: #chunk_count, + })) + } else { + quote!(None) + }; + let salt = self.salt; let placement_type = &self.r#type; @@ -126,6 +164,7 @@ impl ToTokens for StructurePlacementStruct { frequency_reduction_method: #frequency_reduction, frequency: #frequency, salt: #salt, + exclusion_zone: #exclusion_zone, placement_type: #placement_type, } )); @@ -133,7 +172,6 @@ impl ToTokens for StructurePlacementStruct { } impl ToTokens for StructurePlacementTypeStruct { - /// Emits a `StructurePlacementType` variant token stream for the wrapped placement algorithm. fn to_tokens(&self, tokens: &mut TokenStream) { match self { Self::RandomSpread { @@ -176,15 +214,85 @@ impl ToTokens for StructurePlacementTypeStruct { } impl ToTokens for StructureStruct { - /// Emits a `Structure { … }` struct literal token stream for the wrapped structure entry. fn to_tokens(&self, tokens: &mut TokenStream) { let biomes = &self.biomes; let step = generation_step_to_token(&self.step); + let start_pool = if let Some(pool) = &self.start_pool { + quote!(Some(#pool)) + } else { + quote!(None) + }; + let size = if let Some(s) = self.size { + quote!(Some(#s)) + } else { + quote!(None) + }; + let terrain_adaptation = if let Some(ta) = &self.terrain_adaptation { + let ta_token = terrain_adaptation_to_token(ta); + quote!(#ta_token) + } else { + quote!(TerrainAdaptation::None) + }; + let project_start_to_heightmap = if let Some(ps) = &self.project_start_to_heightmap { + quote!(Some(#ps)) + } else { + quote!(None) + }; + let max_distance_from_center = if let Some(m) = self.max_distance_from_center { + quote!(Some(#m)) + } else { + quote!(None) + }; + let liquid_settings = if let Some(ls) = &self.liquid_settings { + quote!(Some(#ls)) + } else { + quote!(None) + }; + let dimension_padding = if let Some(dp) = self.dimension_padding { + quote!(Some(#dp)) + } else { + quote!(None) + }; + let use_expansion_hack = if let Some(hack) = self.use_expansion_hack { + quote!(Some(#hack)) + } else { + quote!(None) + }; + + let structure_type = structure_type_to_token(&self.structure_type); + + let start_height = if let Some(sh) = &self.start_height { + if let Some(abs) = sh.get("absolute") { + let abs_val = abs.as_i64().unwrap() as i16; + quote!(Some(#abs_val)) + } else if let Some(min_inc) = sh.get("min_inclusive") { + if let Some(abs) = min_inc.get("absolute") { + let abs_val = abs.as_i64().unwrap() as i16; + quote!(Some(#abs_val)) + } else { + quote!(None) + } + } else { + quote!(None) + } + } else { + quote!(None) + }; tokens.extend(quote!( Structure { biomes: #biomes, step: #step, + start_pool: #start_pool, + size: #size, + terrain_adaptation: #terrain_adaptation, + start_height: #start_height, + project_start_to_heightmap: #project_start_to_heightmap, + max_distance_from_center: #max_distance_from_center, + liquid_settings: #liquid_settings, + dimension_padding: #dimension_padding, + use_expansion_hack: #use_expansion_hack, + structure_type: #structure_type, } )); } @@ -192,10 +300,38 @@ impl ToTokens for StructureStruct { // Helper functions -/// Converts a structure registry key to the corresponding `StructureKeys` enum variant token stream. -/// -/// # Arguments -/// – `key` – structure registry name with or without the `minecraft:` prefix. +fn structure_type_to_token(st: &str) -> TokenStream { + match st { + "minecraft:jigsaw" => quote!(StructureType::Jigsaw), + "minecraft:buried_treasure" => quote!(StructureType::BuriedTreasure), + "minecraft:desert_pyramid" => quote!(StructureType::DesertPyramid), + "minecraft:end_city" => quote!(StructureType::EndCity), + "minecraft:fortress" => quote!(StructureType::Fortress), + "minecraft:igloo" => quote!(StructureType::Igloo), + "minecraft:jungle_temple" => quote!(StructureType::JungleTemple), + "minecraft:woodland_mansion" => quote!(StructureType::WoodlandMansion), + "minecraft:mineshaft" => quote!(StructureType::Mineshaft), + "minecraft:ocean_monument" => quote!(StructureType::OceanMonument), + "minecraft:nether_fossil" => quote!(StructureType::NetherFossil), + "minecraft:ocean_ruin" => quote!(StructureType::OceanRuin), + "minecraft:ruined_portal" => quote!(StructureType::RuinedPortal), + "minecraft:shipwreck" => quote!(StructureType::Shipwreck), + "minecraft:stronghold" => quote!(StructureType::Stronghold), + "minecraft:swamp_hut" => quote!(StructureType::SwampHut), + _ => quote!(StructureType::Unknown), + } +} + +fn terrain_adaptation_to_token(ta: &str) -> TokenStream { + match ta { + "beard_thin" => quote!(TerrainAdaptation::BeardThin), + "beard_box" => quote!(TerrainAdaptation::BeardBox), + "bury" => quote!(TerrainAdaptation::Bury), + "encapsulate" => quote!(TerrainAdaptation::Encapsulate), + _ => quote!(TerrainAdaptation::None), + } +} + fn structure_key_to_token(key: &str) -> TokenStream { let stripped = key.strip_prefix("minecraft:").unwrap_or(key); @@ -238,10 +374,6 @@ fn structure_key_to_token(key: &str) -> TokenStream { } } -/// Converts a frequency-reduction method string to its `FrequencyReductionMethod` variant token stream. -/// -/// # Arguments -/// – `method` – one of `"default"`, `"legacy_type_1"`, `"legacy_type_2"`, or `"legacy_type_3"`. fn frequency_reduction_to_token(method: &str) -> TokenStream { match method { "default" => quote!(FrequencyReductionMethod::Default), @@ -252,10 +384,6 @@ fn frequency_reduction_to_token(method: &str) -> TokenStream { } } -/// Converts a spread type string to its `SpreadType` variant token stream. -/// -/// # Arguments -/// – `spread` – `"linear"` or `"triangular"`. fn spread_type_to_token(spread: &str) -> TokenStream { match spread { "linear" => quote!(SpreadType::Linear), @@ -264,10 +392,6 @@ fn spread_type_to_token(spread: &str) -> TokenStream { } } -/// Converts a generation step name to its `GenerationStep` variant token stream. -/// -/// # Arguments -/// – `step` – the generation step name as it appears in the JSON (e.g., `"surface_structures"`). fn generation_step_to_token(step: &str) -> TokenStream { match step { "raw_generation" => quote!(GenerationStep::RawGeneration), @@ -389,10 +513,16 @@ pub fn build() -> TokenStream { pub weight: u32, } + pub struct ExclusionZone { + pub other_set: &'static str, + pub chunk_count: i32, + } + pub struct StructurePlacement { pub frequency_reduction_method: Option, pub frequency: Option, pub salt: u32, + pub exclusion_zone: Option, pub placement_type: StructurePlacementType, } @@ -440,9 +570,49 @@ pub fn build() -> TokenStream { } } + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TerrainAdaptation { + None, + BeardThin, + BeardBox, + Bury, + Encapsulate, + } + + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum StructureType { + Jigsaw, + BuriedTreasure, + DesertPyramid, + EndCity, + Fortress, + Igloo, + JungleTemple, + WoodlandMansion, + Mineshaft, + OceanMonument, + NetherFossil, + OceanRuin, + RuinedPortal, + Shipwreck, + Stronghold, + SwampHut, + Unknown, + } + pub struct Structure { pub biomes: &'static str, pub step: GenerationStep, + pub start_pool: Option<&'static str>, + pub size: Option, + pub terrain_adaptation: TerrainAdaptation, + pub start_height: Option, + pub project_start_to_heightmap: Option<&'static str>, + pub max_distance_from_center: Option, + pub liquid_settings: Option<&'static str>, + pub dimension_padding: Option, + pub use_expansion_hack: Option, + pub structure_type: StructureType, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -505,4 +675,4 @@ pub fn build() -> TokenStream { } } ) -} +} \ No newline at end of file diff --git a/pumpkin-world/src/generation/structure/template/rotation.rs b/pumpkin-data/src/block_rotation.rs similarity index 69% rename from pumpkin-world/src/generation/structure/template/rotation.rs rename to pumpkin-data/src/block_rotation.rs index 0e52c3d8b..2778d5fdb 100644 --- a/pumpkin-world/src/generation/structure/template/rotation.rs +++ b/pumpkin-data/src/block_rotation.rs @@ -1,13 +1,15 @@ -//! Block rotation and mirroring transformations for structure templates. +//! Block rotation and mirroring transformations. //! -//! These transformations are used to rotate and mirror structure templates +//! These transformations are used to rotate and mirror blocks //! when placing them in the world, matching vanilla Minecraft behavior. use pumpkin_util::math::vector3::Vector3; +use serde::Deserialize; /// Rotation around the Y axis in 90-degree increments. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] -pub enum BlockRotation { +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Deserialize)] +#[serde(rename_all = "snake_case")] +pub enum Rotation { /// No rotation (0 degrees) #[default] None, @@ -19,7 +21,7 @@ pub enum BlockRotation { CounterClockwise90, } -impl BlockRotation { +impl Rotation { /// Returns all possible rotations. #[must_use] pub const fn values() -> [Self; 4] { @@ -151,9 +153,27 @@ impl BlockRotation { /// Combines this rotation with another rotation. #[must_use] pub const fn then(&self, other: Self) -> Self { - let a = *self as u8; - let b = other as u8; - Self::from_index((a + b) % 4) + match self { + Self::None => other, + Self::Clockwise90 => match other { + Self::None => Self::Clockwise90, + Self::Clockwise90 => Self::Rotate180, + Self::Rotate180 => Self::CounterClockwise90, + Self::CounterClockwise90 => Self::None, + }, + Self::Rotate180 => match other { + Self::None => Self::Rotate180, + Self::Clockwise90 => Self::CounterClockwise90, + Self::Rotate180 => Self::None, + Self::CounterClockwise90 => Self::Clockwise90, + }, + Self::CounterClockwise90 => match other { + Self::None => Self::CounterClockwise90, + Self::Clockwise90 => Self::None, + Self::Rotate180 => Self::Clockwise90, + Self::CounterClockwise90 => Self::Rotate180, + }, + } } /// Returns the inverse of this rotation. @@ -178,8 +198,9 @@ impl BlockRotation { } /// Mirror transformation for structure templates. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] -pub enum BlockMirror { +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Deserialize)] +#[serde(rename_all = "snake_case")] +pub enum Mirror { /// No mirroring #[default] None, @@ -189,7 +210,7 @@ pub enum BlockMirror { FrontBack, } -impl BlockMirror { +impl Mirror { /// Returns all possible mirrors. #[must_use] pub const fn values() -> [Self; 3] { @@ -246,20 +267,20 @@ impl BlockMirror { /// Returns the rotation needed to achieve this mirror from a base rotation. #[must_use] - pub const fn get_rotation(&self, rotation: BlockRotation) -> BlockRotation { + pub const fn get_rotation(&self, rotation: Rotation) -> Rotation { match self { Self::None => rotation, Self::LeftRight => match rotation { - BlockRotation::None => BlockRotation::None, - BlockRotation::Clockwise90 => BlockRotation::CounterClockwise90, - BlockRotation::Rotate180 => BlockRotation::Rotate180, - BlockRotation::CounterClockwise90 => BlockRotation::Clockwise90, + Rotation::None => Rotation::None, + Rotation::Clockwise90 => Rotation::CounterClockwise90, + Rotation::Rotate180 => Rotation::Rotate180, + Rotation::CounterClockwise90 => Rotation::Clockwise90, }, Self::FrontBack => match rotation { - BlockRotation::None => BlockRotation::Rotate180, - BlockRotation::Clockwise90 => BlockRotation::Clockwise90, - BlockRotation::Rotate180 => BlockRotation::None, - BlockRotation::CounterClockwise90 => BlockRotation::CounterClockwise90, + Rotation::None => Rotation::Rotate180, + Rotation::Clockwise90 => Rotation::Clockwise90, + Rotation::Rotate180 => Rotation::None, + Rotation::CounterClockwise90 => Rotation::CounterClockwise90, }, } } @@ -267,82 +288,6 @@ impl BlockMirror { /// Leaks a string to get a 'static str. /// This is used for non-standard property values that aren't covered by static strings. -fn leak_str(s: &str) -> &'static str { +pub fn leak_str(s: &str) -> &'static str { s.to_string().leak() } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_rotation_transform_pos() { - let size = Vector3::new(3, 5, 4); // 3 wide, 5 tall, 4 deep - let pos = Vector3::new(0, 2, 0); - - // No rotation: position unchanged - assert_eq!(BlockRotation::None.transform_pos(pos, size), pos); - - // Clockwise 90: (x, y, z) -> (size.z - 1 - z, y, x) - assert_eq!( - BlockRotation::Clockwise90.transform_pos(pos, size), - Vector3::new(3, 2, 0) - ); - - // 180: (x, y, z) -> (size.x - 1 - x, y, size.z - 1 - z) - assert_eq!( - BlockRotation::Rotate180.transform_pos(pos, size), - Vector3::new(2, 2, 3) - ); - - // Counter-clockwise 90: (x, y, z) -> (z, y, size.x - 1 - x) - assert_eq!( - BlockRotation::CounterClockwise90.transform_pos(pos, size), - Vector3::new(0, 2, 2) - ); - } - - #[test] - fn test_rotation_facing() { - assert_eq!(BlockRotation::Clockwise90.rotate_facing("north"), "east"); - assert_eq!(BlockRotation::Clockwise90.rotate_facing("east"), "south"); - assert_eq!(BlockRotation::Rotate180.rotate_facing("north"), "south"); - assert_eq!( - BlockRotation::CounterClockwise90.rotate_facing("north"), - "west" - ); - } - - #[test] - fn test_mirror_facing() { - assert_eq!(BlockMirror::LeftRight.mirror_facing("east"), "west"); - assert_eq!(BlockMirror::LeftRight.mirror_facing("north"), "north"); - assert_eq!(BlockMirror::FrontBack.mirror_facing("north"), "south"); - assert_eq!(BlockMirror::FrontBack.mirror_facing("east"), "east"); - } - - #[test] - fn test_rotation_inverse() { - for rotation in BlockRotation::values() { - let inverse = rotation.inverse(); - let combined = rotation.then(inverse); - assert_eq!(combined, BlockRotation::None); - } - } - - #[test] - fn test_transform_size() { - let size = Vector3::new(3, 5, 7); - - assert_eq!(BlockRotation::None.transform_size(size), size); - assert_eq!( - BlockRotation::Clockwise90.transform_size(size), - Vector3::new(7, 5, 3) - ); - assert_eq!(BlockRotation::Rotate180.transform_size(size), size); - assert_eq!( - BlockRotation::CounterClockwise90.transform_size(size), - Vector3::new(7, 5, 3) - ); - } -} diff --git a/pumpkin-data/src/blocks.rs b/pumpkin-data/src/blocks.rs index 49f95dd0b..4d96588db 100644 --- a/pumpkin-data/src/blocks.rs +++ b/pumpkin-data/src/blocks.rs @@ -159,6 +159,24 @@ impl Block { pub const fn is_air(&self) -> bool { self.default_state.is_air() } + + #[must_use] + pub fn mirror( + &self, + state_id: u16, + _mirror: crate::block_rotation::Mirror, + ) -> &'static BlockState { + BlockState::from_id(state_id) + } + + #[must_use] + pub fn rotate( + &self, + state_id: u16, + _rotation: crate::block_rotation::Rotation, + ) -> &'static BlockState { + BlockState::from_id(state_id) + } } #[derive(Clone, Debug)] diff --git a/pumpkin-data/src/generated/structures.rs b/pumpkin-data/src/generated/structures.rs index 786e8cc4c..6899ddb59 100644 --- a/pumpkin-data/src/generated/structures.rs +++ b/pumpkin-data/src/generated/structures.rs @@ -94,9 +94,25 @@ impl SpreadType { } } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum TerrainAdaptation { + None, + BeardThin, + BeardBox, + Bury, + Encapsulate, +} pub struct Structure { pub biomes: &'static str, pub step: GenerationStep, + pub start_pool: Option<&'static str>, + pub size: Option, + pub terrain_adaptation: TerrainAdaptation, + pub start_height: Option, + pub project_start_to_heightmap: Option<&'static str>, + pub max_distance_from_center: Option, + pub liquid_settings: Option<&'static str>, + pub dimension_padding: Option, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum GenerationStep { @@ -131,138 +147,410 @@ impl Structure { pub const ANCIENT_CITY: Self = Structure { biomes: "#minecraft:has_structure/ancient_city", step: GenerationStep::UndergroundDecoration, + start_pool: Some("minecraft:ancient_city/city_center"), + size: Some(7i32), + terrain_adaptation: TerrainAdaptation::BeardBox, + start_height: Some(-27i16), + project_start_to_heightmap: None, + max_distance_from_center: Some(116i32), + liquid_settings: None, + dimension_padding: None, }; pub const BASTION_REMNANT: Self = Structure { biomes: "#minecraft:has_structure/bastion_remnant", step: GenerationStep::SurfaceStructures, + start_pool: Some("minecraft:bastion/starts"), + size: Some(6i32), + terrain_adaptation: TerrainAdaptation::None, + start_height: Some(33i16), + project_start_to_heightmap: None, + max_distance_from_center: Some(80i32), + liquid_settings: None, + dimension_padding: None, }; pub const BURIED_TREASURE: Self = Structure { biomes: "#minecraft:has_structure/buried_treasure", step: GenerationStep::UndergroundStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const DESERT_PYRAMID: Self = Structure { biomes: "#minecraft:has_structure/desert_pyramid", step: GenerationStep::SurfaceStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const END_CITY: Self = Structure { biomes: "#minecraft:has_structure/end_city", step: GenerationStep::SurfaceStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const FORTRESS: Self = Structure { biomes: "#minecraft:has_structure/nether_fortress", step: GenerationStep::UndergroundDecoration, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const IGLOO: Self = Structure { biomes: "#minecraft:has_structure/igloo", step: GenerationStep::SurfaceStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const JUNGLE_PYRAMID: Self = Structure { biomes: "#minecraft:has_structure/jungle_temple", step: GenerationStep::SurfaceStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const MANSION: Self = Structure { biomes: "#minecraft:has_structure/woodland_mansion", step: GenerationStep::SurfaceStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const MINESHAFT: Self = Structure { biomes: "#minecraft:has_structure/mineshaft", step: GenerationStep::UndergroundStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const MINESHAFT_MESA: Self = Structure { biomes: "#minecraft:has_structure/mineshaft_mesa", step: GenerationStep::UndergroundStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const MONUMENT: Self = Structure { biomes: "#minecraft:has_structure/ocean_monument", step: GenerationStep::SurfaceStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const NETHER_FOSSIL: Self = Structure { biomes: "#minecraft:has_structure/nether_fossil", step: GenerationStep::UndergroundDecoration, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::BeardThin, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const OCEAN_RUIN_COLD: Self = Structure { biomes: "#minecraft:has_structure/ocean_ruin_cold", step: GenerationStep::SurfaceStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const OCEAN_RUIN_WARM: Self = Structure { biomes: "#minecraft:has_structure/ocean_ruin_warm", step: GenerationStep::SurfaceStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const PILLAGER_OUTPOST: Self = Structure { biomes: "#minecraft:has_structure/pillager_outpost", step: GenerationStep::SurfaceStructures, + start_pool: Some("minecraft:pillager_outpost/base_plates"), + size: Some(7i32), + terrain_adaptation: TerrainAdaptation::BeardThin, + start_height: Some(0i16), + project_start_to_heightmap: Some("WORLD_SURFACE_WG"), + max_distance_from_center: Some(80i32), + liquid_settings: None, + dimension_padding: None, }; pub const RUINED_PORTAL: Self = Structure { biomes: "#minecraft:has_structure/ruined_portal_standard", step: GenerationStep::SurfaceStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const RUINED_PORTAL_DESERT: Self = Structure { biomes: "#minecraft:has_structure/ruined_portal_desert", step: GenerationStep::SurfaceStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const RUINED_PORTAL_JUNGLE: Self = Structure { biomes: "#minecraft:has_structure/ruined_portal_jungle", step: GenerationStep::SurfaceStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const RUINED_PORTAL_MOUNTAIN: Self = Structure { biomes: "#minecraft:has_structure/ruined_portal_mountain", step: GenerationStep::SurfaceStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const RUINED_PORTAL_NETHER: Self = Structure { biomes: "#minecraft:has_structure/ruined_portal_nether", step: GenerationStep::SurfaceStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const RUINED_PORTAL_OCEAN: Self = Structure { biomes: "#minecraft:has_structure/ruined_portal_ocean", step: GenerationStep::SurfaceStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const RUINED_PORTAL_SWAMP: Self = Structure { biomes: "#minecraft:has_structure/ruined_portal_swamp", step: GenerationStep::SurfaceStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const SHIPWRECK: Self = Structure { biomes: "#minecraft:has_structure/shipwreck", step: GenerationStep::SurfaceStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const SHIPWRECK_BEACHED: Self = Structure { biomes: "#minecraft:has_structure/shipwreck_beached", step: GenerationStep::SurfaceStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const STRONGHOLD: Self = Structure { biomes: "#minecraft:has_structure/stronghold", step: GenerationStep::SurfaceStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::Bury, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const SWAMP_HUT: Self = Structure { biomes: "#minecraft:has_structure/swamp_hut", step: GenerationStep::SurfaceStructures, + start_pool: None, + size: None, + terrain_adaptation: TerrainAdaptation::None, + start_height: None, + project_start_to_heightmap: None, + max_distance_from_center: None, + liquid_settings: None, + dimension_padding: None, }; pub const TRAIL_RUINS: Self = Structure { biomes: "#minecraft:has_structure/trail_ruins", step: GenerationStep::UndergroundStructures, + start_pool: Some("minecraft:trail_ruins/tower"), + size: Some(7i32), + terrain_adaptation: TerrainAdaptation::Bury, + start_height: Some(-15i16), + project_start_to_heightmap: Some("WORLD_SURFACE_WG"), + max_distance_from_center: Some(80i32), + liquid_settings: None, + dimension_padding: None, }; pub const TRIAL_CHAMBERS: Self = Structure { biomes: "#minecraft:has_structure/trial_chambers", step: GenerationStep::UndergroundStructures, + start_pool: Some("minecraft:trial_chambers/chamber/end"), + size: Some(20i32), + terrain_adaptation: TerrainAdaptation::Encapsulate, + start_height: Some(-40i16), + project_start_to_heightmap: None, + max_distance_from_center: Some(116i32), + liquid_settings: Some("ignore_waterlogging"), + dimension_padding: Some(10i32), }; pub const VILLAGE_DESERT: Self = Structure { biomes: "#minecraft:has_structure/village_desert", step: GenerationStep::SurfaceStructures, + start_pool: Some("minecraft:village/desert/town_centers"), + size: Some(6i32), + terrain_adaptation: TerrainAdaptation::BeardThin, + start_height: Some(0i16), + project_start_to_heightmap: Some("WORLD_SURFACE_WG"), + max_distance_from_center: Some(80i32), + liquid_settings: None, + dimension_padding: None, }; pub const VILLAGE_PLAINS: Self = Structure { biomes: "#minecraft:has_structure/village_plains", step: GenerationStep::SurfaceStructures, + start_pool: Some("minecraft:village/plains/town_centers"), + size: Some(6i32), + terrain_adaptation: TerrainAdaptation::BeardThin, + start_height: Some(0i16), + project_start_to_heightmap: Some("WORLD_SURFACE_WG"), + max_distance_from_center: Some(80i32), + liquid_settings: None, + dimension_padding: None, }; pub const VILLAGE_SAVANNA: Self = Structure { biomes: "#minecraft:has_structure/village_savanna", step: GenerationStep::SurfaceStructures, + start_pool: Some("minecraft:village/savanna/town_centers"), + size: Some(6i32), + terrain_adaptation: TerrainAdaptation::BeardThin, + start_height: Some(0i16), + project_start_to_heightmap: Some("WORLD_SURFACE_WG"), + max_distance_from_center: Some(80i32), + liquid_settings: None, + dimension_padding: None, }; pub const VILLAGE_SNOWY: Self = Structure { biomes: "#minecraft:has_structure/village_snowy", step: GenerationStep::SurfaceStructures, + start_pool: Some("minecraft:village/snowy/town_centers"), + size: Some(6i32), + terrain_adaptation: TerrainAdaptation::BeardThin, + start_height: Some(0i16), + project_start_to_heightmap: Some("WORLD_SURFACE_WG"), + max_distance_from_center: Some(80i32), + liquid_settings: None, + dimension_padding: None, }; pub const VILLAGE_TAIGA: Self = Structure { biomes: "#minecraft:has_structure/village_taiga", step: GenerationStep::SurfaceStructures, + start_pool: Some("minecraft:village/taiga/town_centers"), + size: Some(6i32), + terrain_adaptation: TerrainAdaptation::BeardThin, + start_height: Some(0i16), + project_start_to_heightmap: Some("WORLD_SURFACE_WG"), + max_distance_from_center: Some(80i32), + liquid_settings: None, + dimension_padding: None, }; #[must_use] pub const fn get(key: &StructureKeys) -> &'static Self { diff --git a/pumpkin-data/src/lib.rs b/pumpkin-data/src/lib.rs index b91f23ec8..e207a57d5 100644 --- a/pumpkin-data/src/lib.rs +++ b/pumpkin-data/src/lib.rs @@ -287,6 +287,8 @@ pub mod recipe_remainder; #[cfg(feature = "block")] mod block_direction; #[cfg(feature = "block")] +pub mod block_rotation; +#[cfg(feature = "block")] pub mod block_state; #[cfg(feature = "block")] mod blocks; @@ -298,6 +300,8 @@ pub use block_direction::FacingExt; #[cfg(feature = "block")] pub use block_direction::HorizontalFacingExt; #[cfg(feature = "block")] +pub use block_rotation::{Mirror, Rotation}; +#[cfg(feature = "block")] pub use block_state::BlockState; #[cfg(feature = "block")] pub use block_state::BlockStateRef; diff --git a/pumpkin-protocol/src/java/server/play/jigsaw_generate.rs b/pumpkin-protocol/src/java/server/play/jigsaw_generate.rs new file mode 100644 index 000000000..17041606b --- /dev/null +++ b/pumpkin-protocol/src/java/server/play/jigsaw_generate.rs @@ -0,0 +1,14 @@ +use pumpkin_data::packet::serverbound::PLAY_JIGSAW_GENERATE; +use pumpkin_macros::java_packet; +use pumpkin_util::math::position::BlockPos; +use serde::Deserialize; + +use crate::codec::var_int::VarInt; + +#[derive(Deserialize)] +#[java_packet(PLAY_JIGSAW_GENERATE)] +pub struct SJigsawGenerate { + pub pos: BlockPos, + pub levels: VarInt, + pub keep_jigsaws: bool, +} diff --git a/pumpkin-protocol/src/java/server/play/mod.rs b/pumpkin-protocol/src/java/server/play/mod.rs index 9f38ce4dc..300fbf3a5 100644 --- a/pumpkin-protocol/src/java/server/play/mod.rs +++ b/pumpkin-protocol/src/java/server/play/mod.rs @@ -15,6 +15,7 @@ mod cookie_response; mod custom_click_action; mod custom_payload; mod interact; +mod jigsaw_generate; mod keep_alive; mod move_vehicle; mod paddle_boat; @@ -39,6 +40,7 @@ mod set_beacon; mod set_command_block; mod set_creative_slot; mod set_held_item; +mod set_jigsaw_block; mod swing_arm; mod update_sign; mod use_item; @@ -61,6 +63,7 @@ pub use cookie_response::*; pub use custom_click_action::*; pub use custom_payload::*; pub use interact::*; +pub use jigsaw_generate::*; pub use keep_alive::*; pub use move_vehicle::*; pub use paddle_boat::*; @@ -85,6 +88,7 @@ pub use set_beacon::*; pub use set_command_block::*; pub use set_creative_slot::*; pub use set_held_item::*; +pub use set_jigsaw_block::*; pub use swing_arm::*; pub use update_sign::*; pub use use_item::*; diff --git a/pumpkin-protocol/src/java/server/play/set_jigsaw_block.rs b/pumpkin-protocol/src/java/server/play/set_jigsaw_block.rs new file mode 100644 index 000000000..0b1db569f --- /dev/null +++ b/pumpkin-protocol/src/java/server/play/set_jigsaw_block.rs @@ -0,0 +1,19 @@ +use pumpkin_data::packet::serverbound::PLAY_SET_JIGSAW_BLOCK; +use pumpkin_macros::java_packet; +use pumpkin_util::math::position::BlockPos; +use serde::Deserialize; + +use crate::codec::var_int::VarInt; + +#[derive(Deserialize)] +#[java_packet(PLAY_SET_JIGSAW_BLOCK)] +pub struct SSetJigsawBlock { + pub pos: BlockPos, + pub name: String, + pub target: String, + pub pool: String, + pub final_state: String, + pub joint: String, + pub selection_priority: VarInt, + pub placement_priority: VarInt, +} diff --git a/pumpkin-util/src/lib.rs b/pumpkin-util/src/lib.rs index 38685aab7..f93e1c42c 100644 --- a/pumpkin-util/src/lib.rs +++ b/pumpkin-util/src/lib.rs @@ -143,6 +143,30 @@ impl BlockDirection { _ => Self::West, } } + + #[must_use] + pub const fn opposite(&self) -> Self { + match self { + Self::Down => Self::Up, + Self::Up => Self::Down, + Self::North => Self::South, + Self::South => Self::North, + Self::West => Self::East, + Self::East => Self::West, + } + } + + #[must_use] + pub const fn to_vector(&self) -> crate::math::vector3::Vector3 { + match self { + Self::Down => crate::math::vector3::Vector3::new(0, -1, 0), + Self::Up => crate::math::vector3::Vector3::new(0, 1, 0), + Self::North => crate::math::vector3::Vector3::new(0, 0, -1), + Self::South => crate::math::vector3::Vector3::new(0, 0, 1), + Self::West => crate::math::vector3::Vector3::new(-1, 0, 0), + Self::East => crate::math::vector3::Vector3::new(1, 0, 0), + } + } } /// A mutable slice split into three parts: the element at the split index, the start, and the end. diff --git a/pumpkin-world/assets/structures/ancient_city/city/entrance/entrance_connector.nbt b/pumpkin-world/assets/structures/ancient_city/city/entrance/entrance_connector.nbt new file mode 100644 index 000000000..b18a898d3 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/city/entrance/entrance_connector.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/city/entrance/entrance_path_1.nbt b/pumpkin-world/assets/structures/ancient_city/city/entrance/entrance_path_1.nbt new file mode 100644 index 000000000..98eb67953 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/city/entrance/entrance_path_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/city/entrance/entrance_path_2.nbt b/pumpkin-world/assets/structures/ancient_city/city/entrance/entrance_path_2.nbt new file mode 100644 index 000000000..28f4e917d Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/city/entrance/entrance_path_2.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/city/entrance/entrance_path_3.nbt b/pumpkin-world/assets/structures/ancient_city/city/entrance/entrance_path_3.nbt new file mode 100644 index 000000000..ceebb9c52 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/city/entrance/entrance_path_3.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/city/entrance/entrance_path_4.nbt b/pumpkin-world/assets/structures/ancient_city/city/entrance/entrance_path_4.nbt new file mode 100644 index 000000000..b7ae121da Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/city/entrance/entrance_path_4.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/city/entrance/entrance_path_5.nbt b/pumpkin-world/assets/structures/ancient_city/city/entrance/entrance_path_5.nbt new file mode 100644 index 000000000..103e0c075 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/city/entrance/entrance_path_5.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/city_center/city_center_1.nbt b/pumpkin-world/assets/structures/ancient_city/city_center/city_center_1.nbt new file mode 100644 index 000000000..71b084047 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/city_center/city_center_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/city_center/city_center_2.nbt b/pumpkin-world/assets/structures/ancient_city/city_center/city_center_2.nbt new file mode 100644 index 000000000..ddc62ee68 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/city_center/city_center_2.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/city_center/city_center_3.nbt b/pumpkin-world/assets/structures/ancient_city/city_center/city_center_3.nbt new file mode 100644 index 000000000..ed2b72ddc Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/city_center/city_center_3.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/city_center/walls/bottom_1.nbt b/pumpkin-world/assets/structures/ancient_city/city_center/walls/bottom_1.nbt new file mode 100644 index 000000000..0eba19a53 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/city_center/walls/bottom_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/city_center/walls/bottom_2.nbt b/pumpkin-world/assets/structures/ancient_city/city_center/walls/bottom_2.nbt new file mode 100644 index 000000000..1b09c88a1 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/city_center/walls/bottom_2.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/city_center/walls/bottom_left_corner.nbt b/pumpkin-world/assets/structures/ancient_city/city_center/walls/bottom_left_corner.nbt new file mode 100644 index 000000000..2a80a1a3a Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/city_center/walls/bottom_left_corner.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/city_center/walls/bottom_right_corner.nbt b/pumpkin-world/assets/structures/ancient_city/city_center/walls/bottom_right_corner.nbt new file mode 100644 index 000000000..42c257ef2 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/city_center/walls/bottom_right_corner.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/city_center/walls/bottom_right_corner_1.nbt b/pumpkin-world/assets/structures/ancient_city/city_center/walls/bottom_right_corner_1.nbt new file mode 100644 index 000000000..cbb1ee6d7 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/city_center/walls/bottom_right_corner_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/city_center/walls/bottom_right_corner_2.nbt b/pumpkin-world/assets/structures/ancient_city/city_center/walls/bottom_right_corner_2.nbt new file mode 100644 index 000000000..25ec5fc5e Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/city_center/walls/bottom_right_corner_2.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/city_center/walls/left.nbt b/pumpkin-world/assets/structures/ancient_city/city_center/walls/left.nbt new file mode 100644 index 000000000..e086383f8 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/city_center/walls/left.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/city_center/walls/right.nbt b/pumpkin-world/assets/structures/ancient_city/city_center/walls/right.nbt new file mode 100644 index 000000000..079509889 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/city_center/walls/right.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/city_center/walls/top.nbt b/pumpkin-world/assets/structures/ancient_city/city_center/walls/top.nbt new file mode 100644 index 000000000..a33b1c07e Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/city_center/walls/top.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/city_center/walls/top_left_corner.nbt b/pumpkin-world/assets/structures/ancient_city/city_center/walls/top_left_corner.nbt new file mode 100644 index 000000000..3306b05a0 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/city_center/walls/top_left_corner.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/city_center/walls/top_right_corner.nbt b/pumpkin-world/assets/structures/ancient_city/city_center/walls/top_right_corner.nbt new file mode 100644 index 000000000..8ff20e1bc Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/city_center/walls/top_right_corner.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/barracks.nbt b/pumpkin-world/assets/structures/ancient_city/structures/barracks.nbt new file mode 100644 index 000000000..97173720e Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/barracks.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/camp_1.nbt b/pumpkin-world/assets/structures/ancient_city/structures/camp_1.nbt new file mode 100644 index 000000000..db4ef14b5 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/camp_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/camp_2.nbt b/pumpkin-world/assets/structures/ancient_city/structures/camp_2.nbt new file mode 100644 index 000000000..2513c30fb Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/camp_2.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/camp_3.nbt b/pumpkin-world/assets/structures/ancient_city/structures/camp_3.nbt new file mode 100644 index 000000000..1b0c01ee3 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/camp_3.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/chamber_1.nbt b/pumpkin-world/assets/structures/ancient_city/structures/chamber_1.nbt new file mode 100644 index 000000000..65ff552a5 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/chamber_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/chamber_2.nbt b/pumpkin-world/assets/structures/ancient_city/structures/chamber_2.nbt new file mode 100644 index 000000000..c1bd0110c Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/chamber_2.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/chamber_3.nbt b/pumpkin-world/assets/structures/ancient_city/structures/chamber_3.nbt new file mode 100644 index 000000000..711280fbf Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/chamber_3.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/ice_box_1.nbt b/pumpkin-world/assets/structures/ancient_city/structures/ice_box_1.nbt new file mode 100644 index 000000000..e5d787760 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/ice_box_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/large_pillar_1.nbt b/pumpkin-world/assets/structures/ancient_city/structures/large_pillar_1.nbt new file mode 100644 index 000000000..4d619829f Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/large_pillar_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/large_ruin_1.nbt b/pumpkin-world/assets/structures/ancient_city/structures/large_ruin_1.nbt new file mode 100644 index 000000000..3ce04aa7c Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/large_ruin_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/medium_pillar_1.nbt b/pumpkin-world/assets/structures/ancient_city/structures/medium_pillar_1.nbt new file mode 100644 index 000000000..38ece3d8a Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/medium_pillar_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/medium_ruin_1.nbt b/pumpkin-world/assets/structures/ancient_city/structures/medium_ruin_1.nbt new file mode 100644 index 000000000..c476ea766 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/medium_ruin_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/medium_ruin_2.nbt b/pumpkin-world/assets/structures/ancient_city/structures/medium_ruin_2.nbt new file mode 100644 index 000000000..0f8b01b7a Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/medium_ruin_2.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/sauna_1.nbt b/pumpkin-world/assets/structures/ancient_city/structures/sauna_1.nbt new file mode 100644 index 000000000..ef56d35f1 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/sauna_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/small_ruin_1.nbt b/pumpkin-world/assets/structures/ancient_city/structures/small_ruin_1.nbt new file mode 100644 index 000000000..b1b9c2ac7 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/small_ruin_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/small_ruin_2.nbt b/pumpkin-world/assets/structures/ancient_city/structures/small_ruin_2.nbt new file mode 100644 index 000000000..34d14f95c Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/small_ruin_2.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/small_statue.nbt b/pumpkin-world/assets/structures/ancient_city/structures/small_statue.nbt new file mode 100644 index 000000000..9cf2d16d8 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/small_statue.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/tall_ruin_1.nbt b/pumpkin-world/assets/structures/ancient_city/structures/tall_ruin_1.nbt new file mode 100644 index 000000000..098949f62 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/tall_ruin_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/tall_ruin_2.nbt b/pumpkin-world/assets/structures/ancient_city/structures/tall_ruin_2.nbt new file mode 100644 index 000000000..c57b7bfbe Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/tall_ruin_2.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/tall_ruin_3.nbt b/pumpkin-world/assets/structures/ancient_city/structures/tall_ruin_3.nbt new file mode 100644 index 000000000..7a3301e09 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/tall_ruin_3.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/structures/tall_ruin_4.nbt b/pumpkin-world/assets/structures/ancient_city/structures/tall_ruin_4.nbt new file mode 100644 index 000000000..2d4fbadbe Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/structures/tall_ruin_4.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/walls/intact_corner_wall_1.nbt b/pumpkin-world/assets/structures/ancient_city/walls/intact_corner_wall_1.nbt new file mode 100644 index 000000000..15d3abff3 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/walls/intact_corner_wall_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_1.nbt b/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_1.nbt new file mode 100644 index 000000000..d30a16acf Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_2.nbt b/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_2.nbt new file mode 100644 index 000000000..ad669030f Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_2.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_bridge.nbt b/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_bridge.nbt new file mode 100644 index 000000000..8ee9c6185 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_bridge.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_passage_1.nbt b/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_passage_1.nbt new file mode 100644 index 000000000..2803da716 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_passage_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_stairs_1.nbt b/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_stairs_1.nbt new file mode 100644 index 000000000..061b61e31 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_stairs_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_stairs_2.nbt b/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_stairs_2.nbt new file mode 100644 index 000000000..c6d75f33f Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_stairs_2.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_stairs_3.nbt b/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_stairs_3.nbt new file mode 100644 index 000000000..811e98d1c Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_stairs_3.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_stairs_4.nbt b/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_stairs_4.nbt new file mode 100644 index 000000000..64a717962 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/walls/intact_horizontal_wall_stairs_4.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/walls/intact_intersection_wall_1.nbt b/pumpkin-world/assets/structures/ancient_city/walls/intact_intersection_wall_1.nbt new file mode 100644 index 000000000..e76ec7332 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/walls/intact_intersection_wall_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/walls/intact_lshape_wall_1.nbt b/pumpkin-world/assets/structures/ancient_city/walls/intact_lshape_wall_1.nbt new file mode 100644 index 000000000..28a9ad1e0 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/walls/intact_lshape_wall_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/walls/ruined_corner_wall_1.nbt b/pumpkin-world/assets/structures/ancient_city/walls/ruined_corner_wall_1.nbt new file mode 100644 index 000000000..84eca3e12 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/walls/ruined_corner_wall_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/walls/ruined_corner_wall_2.nbt b/pumpkin-world/assets/structures/ancient_city/walls/ruined_corner_wall_2.nbt new file mode 100644 index 000000000..f67ac59a9 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/walls/ruined_corner_wall_2.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/walls/ruined_horizontal_wall_stairs_1.nbt b/pumpkin-world/assets/structures/ancient_city/walls/ruined_horizontal_wall_stairs_1.nbt new file mode 100644 index 000000000..f0a055004 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/walls/ruined_horizontal_wall_stairs_1.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/walls/ruined_horizontal_wall_stairs_2.nbt b/pumpkin-world/assets/structures/ancient_city/walls/ruined_horizontal_wall_stairs_2.nbt new file mode 100644 index 000000000..4adb10a2e Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/walls/ruined_horizontal_wall_stairs_2.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/walls/ruined_horizontal_wall_stairs_3.nbt b/pumpkin-world/assets/structures/ancient_city/walls/ruined_horizontal_wall_stairs_3.nbt new file mode 100644 index 000000000..7a107406e Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/walls/ruined_horizontal_wall_stairs_3.nbt differ diff --git a/pumpkin-world/assets/structures/ancient_city/walls/ruined_horizontal_wall_stairs_4.nbt b/pumpkin-world/assets/structures/ancient_city/walls/ruined_horizontal_wall_stairs_4.nbt new file mode 100644 index 000000000..021d75853 Binary files /dev/null and b/pumpkin-world/assets/structures/ancient_city/walls/ruined_horizontal_wall_stairs_4.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/blocks/air.nbt b/pumpkin-world/assets/structures/bastion/blocks/air.nbt new file mode 100644 index 000000000..dffbd66a8 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/blocks/air.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/blocks/gold.nbt b/pumpkin-world/assets/structures/bastion/blocks/gold.nbt new file mode 100644 index 000000000..61eee90df Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/blocks/gold.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/bridge/bridge_pieces/bridge.nbt b/pumpkin-world/assets/structures/bastion/bridge/bridge_pieces/bridge.nbt new file mode 100644 index 000000000..c22988079 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/bridge/bridge_pieces/bridge.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/bridge/connectors/back_bridge_bottom.nbt b/pumpkin-world/assets/structures/bastion/bridge/connectors/back_bridge_bottom.nbt new file mode 100644 index 000000000..3ffbf2e55 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/bridge/connectors/back_bridge_bottom.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/bridge/connectors/back_bridge_top.nbt b/pumpkin-world/assets/structures/bastion/bridge/connectors/back_bridge_top.nbt new file mode 100644 index 000000000..8b28f4a8e Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/bridge/connectors/back_bridge_top.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/bridge/legs/leg_0.nbt b/pumpkin-world/assets/structures/bastion/bridge/legs/leg_0.nbt new file mode 100644 index 000000000..3581ef51f Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/bridge/legs/leg_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/bridge/legs/leg_1.nbt b/pumpkin-world/assets/structures/bastion/bridge/legs/leg_1.nbt new file mode 100644 index 000000000..c742611f0 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/bridge/legs/leg_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/bridge/rampart_plates/plate_0.nbt b/pumpkin-world/assets/structures/bastion/bridge/rampart_plates/plate_0.nbt new file mode 100644 index 000000000..188b9ca24 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/bridge/rampart_plates/plate_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/bridge/ramparts/rampart_0.nbt b/pumpkin-world/assets/structures/bastion/bridge/ramparts/rampart_0.nbt new file mode 100644 index 000000000..57ef6fe27 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/bridge/ramparts/rampart_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/bridge/ramparts/rampart_1.nbt b/pumpkin-world/assets/structures/bastion/bridge/ramparts/rampart_1.nbt new file mode 100644 index 000000000..8afaa9e55 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/bridge/ramparts/rampart_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/bridge/starting_pieces/entrance.nbt b/pumpkin-world/assets/structures/bastion/bridge/starting_pieces/entrance.nbt new file mode 100644 index 000000000..e89155f58 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/bridge/starting_pieces/entrance.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/bridge/starting_pieces/entrance_base.nbt b/pumpkin-world/assets/structures/bastion/bridge/starting_pieces/entrance_base.nbt new file mode 100644 index 000000000..5f5a46466 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/bridge/starting_pieces/entrance_base.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/bridge/starting_pieces/entrance_face.nbt b/pumpkin-world/assets/structures/bastion/bridge/starting_pieces/entrance_face.nbt new file mode 100644 index 000000000..f1650d51e Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/bridge/starting_pieces/entrance_face.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/bridge/walls/wall_base_0.nbt b/pumpkin-world/assets/structures/bastion/bridge/walls/wall_base_0.nbt new file mode 100644 index 000000000..0490714e2 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/bridge/walls/wall_base_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/bridge/walls/wall_base_1.nbt b/pumpkin-world/assets/structures/bastion/bridge/walls/wall_base_1.nbt new file mode 100644 index 000000000..bde271e94 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/bridge/walls/wall_base_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/air_base.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/air_base.nbt new file mode 100644 index 000000000..6519c94f6 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/air_base.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/connectors/end_post_connector.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/connectors/end_post_connector.nbt new file mode 100644 index 000000000..e59099370 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/connectors/end_post_connector.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/inner_0.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/inner_0.nbt new file mode 100644 index 000000000..9abe1cb8c Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/inner_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/inner_1.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/inner_1.nbt new file mode 100644 index 000000000..21f1d2870 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/inner_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/inner_2.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/inner_2.nbt new file mode 100644 index 000000000..b2bd7d41d Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/inner_2.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/inner_3.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/inner_3.nbt new file mode 100644 index 000000000..7cf7cae0a Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/inner_3.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/inner_4.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/inner_4.nbt new file mode 100644 index 000000000..cce54b238 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/inner_4.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/outer_0.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/outer_0.nbt new file mode 100644 index 000000000..4d6819860 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/outer_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/outer_1.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/outer_1.nbt new file mode 100644 index 000000000..324ec3432 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/outer_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/outer_2.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/outer_2.nbt new file mode 100644 index 000000000..85ac81694 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/outer_2.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/outer_3.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/outer_3.nbt new file mode 100644 index 000000000..bc227dcdf Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/outer_3.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/outer_4.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/outer_4.nbt new file mode 100644 index 000000000..77dbc5fb7 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/large_stables/outer_4.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/posts/end_post.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/posts/end_post.nbt new file mode 100644 index 000000000..ce8889730 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/posts/end_post.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/posts/stair_post.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/posts/stair_post.nbt new file mode 100644 index 000000000..aa78c6d86 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/posts/stair_post.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/rampart_plates/rampart_plate_1.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/rampart_plates/rampart_plate_1.nbt new file mode 100644 index 000000000..892e3c734 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/rampart_plates/rampart_plate_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/ramparts/ramparts_1.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/ramparts/ramparts_1.nbt new file mode 100644 index 000000000..da9b879b5 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/ramparts/ramparts_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/ramparts/ramparts_2.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/ramparts/ramparts_2.nbt new file mode 100644 index 000000000..13d0dbfc2 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/ramparts/ramparts_2.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/ramparts/ramparts_3.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/ramparts/ramparts_3.nbt new file mode 100644 index 000000000..4a1a52b9a Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/ramparts/ramparts_3.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/inner_0.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/inner_0.nbt new file mode 100644 index 000000000..7096eb255 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/inner_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/inner_1.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/inner_1.nbt new file mode 100644 index 000000000..93236e7cc Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/inner_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/inner_2.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/inner_2.nbt new file mode 100644 index 000000000..37998ac99 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/inner_2.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/inner_3.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/inner_3.nbt new file mode 100644 index 000000000..f6cb1f17a Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/inner_3.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/outer_0.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/outer_0.nbt new file mode 100644 index 000000000..6c93c4fa6 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/outer_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/outer_1.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/outer_1.nbt new file mode 100644 index 000000000..16a4bc5c3 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/outer_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/outer_2.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/outer_2.nbt new file mode 100644 index 000000000..7116a45d5 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/outer_2.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/outer_3.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/outer_3.nbt new file mode 100644 index 000000000..b21beab9b Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/small_stables/outer_3.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_1_0.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_1_0.nbt new file mode 100644 index 000000000..e8d42207a Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_1_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_1_1.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_1_1.nbt new file mode 100644 index 000000000..e3700b2d4 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_1_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_1_2.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_1_2.nbt new file mode 100644 index 000000000..693ab6542 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_1_2.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_1_3.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_1_3.nbt new file mode 100644 index 000000000..b03438f51 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_1_3.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_1_4.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_1_4.nbt new file mode 100644 index 000000000..c396616e8 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_1_4.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_2_0.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_2_0.nbt new file mode 100644 index 000000000..75c047a6d Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_2_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_2_1.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_2_1.nbt new file mode 100644 index 000000000..988fb0088 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_2_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_2_2.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_2_2.nbt new file mode 100644 index 000000000..d7a669544 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_2_2.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_2_3.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_2_3.nbt new file mode 100644 index 000000000..70038541f Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_2_3.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_2_4.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_2_4.nbt new file mode 100644 index 000000000..18fe11004 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_2_4.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_3_0.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_3_0.nbt new file mode 100644 index 000000000..a8a529007 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_3_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_3_1.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_3_1.nbt new file mode 100644 index 000000000..efc27ad0b Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_3_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_3_2.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_3_2.nbt new file mode 100644 index 000000000..baea48404 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_3_2.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_3_3.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_3_3.nbt new file mode 100644 index 000000000..e9bd128fa Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_3_3.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_3_4.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_3_4.nbt new file mode 100644 index 000000000..3a5774dd2 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/stairs/stairs_3_4.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/stairs_0_mirrored.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/stairs_0_mirrored.nbt new file mode 100644 index 000000000..7bd171630 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/stairs_0_mirrored.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/stairs_1_mirrored.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/stairs_1_mirrored.nbt new file mode 100644 index 000000000..d66499bf1 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/stairs_1_mirrored.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/stairs_2_mirrored.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/stairs_2_mirrored.nbt new file mode 100644 index 000000000..854780901 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/stairs_2_mirrored.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/stairs_3_mirrored.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/stairs_3_mirrored.nbt new file mode 100644 index 000000000..8b61a1913 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/stairs_3_mirrored.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/stairs_4_mirrored.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/stairs_4_mirrored.nbt new file mode 100644 index 000000000..78c1da94b Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/stairs_4_mirrored.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/starting_stairs_0.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/starting_stairs_0.nbt new file mode 100644 index 000000000..151f7bba2 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/starting_stairs_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/starting_stairs_1.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/starting_stairs_1.nbt new file mode 100644 index 000000000..b6ecf62dd Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/starting_stairs_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/starting_stairs_2.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/starting_stairs_2.nbt new file mode 100644 index 000000000..fece6a3ad Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/starting_stairs_2.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/starting_stairs_3.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/starting_stairs_3.nbt new file mode 100644 index 000000000..20579ca56 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/starting_stairs_3.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/starting_stairs_4.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/starting_stairs_4.nbt new file mode 100644 index 000000000..ce05408d7 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/starting_pieces/starting_stairs_4.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/walls/side_wall_0.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/walls/side_wall_0.nbt new file mode 100644 index 000000000..38bf40969 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/walls/side_wall_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/walls/side_wall_1.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/walls/side_wall_1.nbt new file mode 100644 index 000000000..ced2088c4 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/walls/side_wall_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/hoglin_stable/walls/wall_base.nbt b/pumpkin-world/assets/structures/bastion/hoglin_stable/walls/wall_base.nbt new file mode 100644 index 000000000..93667fe23 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/hoglin_stable/walls/wall_base.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/mobs/crossbow_piglin.nbt b/pumpkin-world/assets/structures/bastion/mobs/crossbow_piglin.nbt new file mode 100644 index 000000000..92dc2111d Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/mobs/crossbow_piglin.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/mobs/empty.nbt b/pumpkin-world/assets/structures/bastion/mobs/empty.nbt new file mode 100644 index 000000000..66e1cbc90 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/mobs/empty.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/mobs/hoglin.nbt b/pumpkin-world/assets/structures/bastion/mobs/hoglin.nbt new file mode 100644 index 000000000..99beaa65b Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/mobs/hoglin.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/mobs/melee_piglin.nbt b/pumpkin-world/assets/structures/bastion/mobs/melee_piglin.nbt new file mode 100644 index 000000000..041e999b7 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/mobs/melee_piglin.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/mobs/melee_piglin_always.nbt b/pumpkin-world/assets/structures/bastion/mobs/melee_piglin_always.nbt new file mode 100644 index 000000000..75c5858c7 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/mobs/melee_piglin_always.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/mobs/sword_piglin.nbt b/pumpkin-world/assets/structures/bastion/mobs/sword_piglin.nbt new file mode 100644 index 000000000..d3f59daba Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/mobs/sword_piglin.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/bases/centers/center_0.nbt b/pumpkin-world/assets/structures/bastion/treasure/bases/centers/center_0.nbt new file mode 100644 index 000000000..07897d25d Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/bases/centers/center_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/bases/centers/center_1.nbt b/pumpkin-world/assets/structures/bastion/treasure/bases/centers/center_1.nbt new file mode 100644 index 000000000..e2a56dd2d Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/bases/centers/center_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/bases/centers/center_2.nbt b/pumpkin-world/assets/structures/bastion/treasure/bases/centers/center_2.nbt new file mode 100644 index 000000000..998746fea Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/bases/centers/center_2.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/bases/centers/center_3.nbt b/pumpkin-world/assets/structures/bastion/treasure/bases/centers/center_3.nbt new file mode 100644 index 000000000..ab65c9749 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/bases/centers/center_3.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/bases/lava_basin.nbt b/pumpkin-world/assets/structures/bastion/treasure/bases/lava_basin.nbt new file mode 100644 index 000000000..79db59459 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/bases/lava_basin.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/big_air_full.nbt b/pumpkin-world/assets/structures/bastion/treasure/big_air_full.nbt new file mode 100644 index 000000000..972d5975f Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/big_air_full.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/brains/center_brain.nbt b/pumpkin-world/assets/structures/bastion/treasure/brains/center_brain.nbt new file mode 100644 index 000000000..3094336cb Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/brains/center_brain.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/connectors/center_to_wall_middle.nbt b/pumpkin-world/assets/structures/bastion/treasure/connectors/center_to_wall_middle.nbt new file mode 100644 index 000000000..4c14fb3f7 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/connectors/center_to_wall_middle.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/connectors/center_to_wall_top.nbt b/pumpkin-world/assets/structures/bastion/treasure/connectors/center_to_wall_top.nbt new file mode 100644 index 000000000..f12fbeb0f Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/connectors/center_to_wall_top.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/connectors/center_to_wall_top_entrance.nbt b/pumpkin-world/assets/structures/bastion/treasure/connectors/center_to_wall_top_entrance.nbt new file mode 100644 index 000000000..8d00e8cfd Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/connectors/center_to_wall_top_entrance.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/corners/bottom/corner_0.nbt b/pumpkin-world/assets/structures/bastion/treasure/corners/bottom/corner_0.nbt new file mode 100644 index 000000000..884350387 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/corners/bottom/corner_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/corners/bottom/corner_1.nbt b/pumpkin-world/assets/structures/bastion/treasure/corners/bottom/corner_1.nbt new file mode 100644 index 000000000..58c19f06e Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/corners/bottom/corner_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/corners/edges/bottom.nbt b/pumpkin-world/assets/structures/bastion/treasure/corners/edges/bottom.nbt new file mode 100644 index 000000000..7ebe6acc0 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/corners/edges/bottom.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/corners/edges/middle.nbt b/pumpkin-world/assets/structures/bastion/treasure/corners/edges/middle.nbt new file mode 100644 index 000000000..b6155564d Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/corners/edges/middle.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/corners/edges/top.nbt b/pumpkin-world/assets/structures/bastion/treasure/corners/edges/top.nbt new file mode 100644 index 000000000..e1404cabb Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/corners/edges/top.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/corners/middle/corner_0.nbt b/pumpkin-world/assets/structures/bastion/treasure/corners/middle/corner_0.nbt new file mode 100644 index 000000000..c0c5713f5 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/corners/middle/corner_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/corners/middle/corner_1.nbt b/pumpkin-world/assets/structures/bastion/treasure/corners/middle/corner_1.nbt new file mode 100644 index 000000000..4bab2c8b6 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/corners/middle/corner_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/corners/top/corner_0.nbt b/pumpkin-world/assets/structures/bastion/treasure/corners/top/corner_0.nbt new file mode 100644 index 000000000..121ce2e60 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/corners/top/corner_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/corners/top/corner_1.nbt b/pumpkin-world/assets/structures/bastion/treasure/corners/top/corner_1.nbt new file mode 100644 index 000000000..f6d9e8b19 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/corners/top/corner_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/entrances/entrance_0.nbt b/pumpkin-world/assets/structures/bastion/treasure/entrances/entrance_0.nbt new file mode 100644 index 000000000..80400b901 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/entrances/entrance_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/extensions/empty.nbt b/pumpkin-world/assets/structures/bastion/treasure/extensions/empty.nbt new file mode 100644 index 000000000..0e7c890d4 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/extensions/empty.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/extensions/fire_room.nbt b/pumpkin-world/assets/structures/bastion/treasure/extensions/fire_room.nbt new file mode 100644 index 000000000..3d3350a11 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/extensions/fire_room.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/extensions/house_0.nbt b/pumpkin-world/assets/structures/bastion/treasure/extensions/house_0.nbt new file mode 100644 index 000000000..d32aec67f Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/extensions/house_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/extensions/house_1.nbt b/pumpkin-world/assets/structures/bastion/treasure/extensions/house_1.nbt new file mode 100644 index 000000000..b9581562e Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/extensions/house_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/extensions/large_bridge_0.nbt b/pumpkin-world/assets/structures/bastion/treasure/extensions/large_bridge_0.nbt new file mode 100644 index 000000000..695dfde78 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/extensions/large_bridge_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/extensions/large_bridge_1.nbt b/pumpkin-world/assets/structures/bastion/treasure/extensions/large_bridge_1.nbt new file mode 100644 index 000000000..3e63c561f Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/extensions/large_bridge_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/extensions/large_bridge_2.nbt b/pumpkin-world/assets/structures/bastion/treasure/extensions/large_bridge_2.nbt new file mode 100644 index 000000000..ac7d9d297 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/extensions/large_bridge_2.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/extensions/large_bridge_3.nbt b/pumpkin-world/assets/structures/bastion/treasure/extensions/large_bridge_3.nbt new file mode 100644 index 000000000..12c4040d1 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/extensions/large_bridge_3.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/extensions/roofed_bridge.nbt b/pumpkin-world/assets/structures/bastion/treasure/extensions/roofed_bridge.nbt new file mode 100644 index 000000000..14e643c4f Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/extensions/roofed_bridge.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/extensions/small_bridge_0.nbt b/pumpkin-world/assets/structures/bastion/treasure/extensions/small_bridge_0.nbt new file mode 100644 index 000000000..080f821ed Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/extensions/small_bridge_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/extensions/small_bridge_1.nbt b/pumpkin-world/assets/structures/bastion/treasure/extensions/small_bridge_1.nbt new file mode 100644 index 000000000..4aa5216e2 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/extensions/small_bridge_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/extensions/small_bridge_2.nbt b/pumpkin-world/assets/structures/bastion/treasure/extensions/small_bridge_2.nbt new file mode 100644 index 000000000..2ae89bcb7 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/extensions/small_bridge_2.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/extensions/small_bridge_3.nbt b/pumpkin-world/assets/structures/bastion/treasure/extensions/small_bridge_3.nbt new file mode 100644 index 000000000..af4eacf2a Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/extensions/small_bridge_3.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/ramparts/bottom_wall_0.nbt b/pumpkin-world/assets/structures/bastion/treasure/ramparts/bottom_wall_0.nbt new file mode 100644 index 000000000..3496eeb14 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/ramparts/bottom_wall_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/ramparts/lava_basin_main.nbt b/pumpkin-world/assets/structures/bastion/treasure/ramparts/lava_basin_main.nbt new file mode 100644 index 000000000..1ecb7dcf4 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/ramparts/lava_basin_main.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/ramparts/lava_basin_side.nbt b/pumpkin-world/assets/structures/bastion/treasure/ramparts/lava_basin_side.nbt new file mode 100644 index 000000000..2ec2b60ec Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/ramparts/lava_basin_side.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/ramparts/mid_wall_main.nbt b/pumpkin-world/assets/structures/bastion/treasure/ramparts/mid_wall_main.nbt new file mode 100644 index 000000000..85670d327 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/ramparts/mid_wall_main.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/ramparts/mid_wall_side.nbt b/pumpkin-world/assets/structures/bastion/treasure/ramparts/mid_wall_side.nbt new file mode 100644 index 000000000..2648d4720 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/ramparts/mid_wall_side.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/ramparts/top_wall.nbt b/pumpkin-world/assets/structures/bastion/treasure/ramparts/top_wall.nbt new file mode 100644 index 000000000..70646ce36 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/ramparts/top_wall.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/roofs/center_roof.nbt b/pumpkin-world/assets/structures/bastion/treasure/roofs/center_roof.nbt new file mode 100644 index 000000000..628ba28e9 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/roofs/center_roof.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/roofs/corner_roof.nbt b/pumpkin-world/assets/structures/bastion/treasure/roofs/corner_roof.nbt new file mode 100644 index 000000000..5ed1d4213 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/roofs/corner_roof.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/roofs/wall_roof.nbt b/pumpkin-world/assets/structures/bastion/treasure/roofs/wall_roof.nbt new file mode 100644 index 000000000..c2ef1a329 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/roofs/wall_roof.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/stairs/lower_stairs.nbt b/pumpkin-world/assets/structures/bastion/treasure/stairs/lower_stairs.nbt new file mode 100644 index 000000000..d5cbac072 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/stairs/lower_stairs.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/walls/bottom/wall_0.nbt b/pumpkin-world/assets/structures/bastion/treasure/walls/bottom/wall_0.nbt new file mode 100644 index 000000000..cbc035532 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/walls/bottom/wall_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/walls/bottom/wall_1.nbt b/pumpkin-world/assets/structures/bastion/treasure/walls/bottom/wall_1.nbt new file mode 100644 index 000000000..7392a640f Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/walls/bottom/wall_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/walls/bottom/wall_2.nbt b/pumpkin-world/assets/structures/bastion/treasure/walls/bottom/wall_2.nbt new file mode 100644 index 000000000..9806c1aa2 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/walls/bottom/wall_2.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/walls/bottom/wall_3.nbt b/pumpkin-world/assets/structures/bastion/treasure/walls/bottom/wall_3.nbt new file mode 100644 index 000000000..a8e887666 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/walls/bottom/wall_3.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/walls/entrance_wall.nbt b/pumpkin-world/assets/structures/bastion/treasure/walls/entrance_wall.nbt new file mode 100644 index 000000000..e1ad6c4de Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/walls/entrance_wall.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/walls/lava_wall.nbt b/pumpkin-world/assets/structures/bastion/treasure/walls/lava_wall.nbt new file mode 100644 index 000000000..bbd9ef8eb Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/walls/lava_wall.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/walls/mid/wall_0.nbt b/pumpkin-world/assets/structures/bastion/treasure/walls/mid/wall_0.nbt new file mode 100644 index 000000000..1d5a87327 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/walls/mid/wall_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/walls/mid/wall_1.nbt b/pumpkin-world/assets/structures/bastion/treasure/walls/mid/wall_1.nbt new file mode 100644 index 000000000..b81462958 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/walls/mid/wall_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/walls/mid/wall_2.nbt b/pumpkin-world/assets/structures/bastion/treasure/walls/mid/wall_2.nbt new file mode 100644 index 000000000..331549fd5 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/walls/mid/wall_2.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/walls/outer/bottom_corner.nbt b/pumpkin-world/assets/structures/bastion/treasure/walls/outer/bottom_corner.nbt new file mode 100644 index 000000000..c9ce099ff Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/walls/outer/bottom_corner.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/walls/outer/medium_outer_wall.nbt b/pumpkin-world/assets/structures/bastion/treasure/walls/outer/medium_outer_wall.nbt new file mode 100644 index 000000000..86a6773d4 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/walls/outer/medium_outer_wall.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/walls/outer/mid_corner.nbt b/pumpkin-world/assets/structures/bastion/treasure/walls/outer/mid_corner.nbt new file mode 100644 index 000000000..43b553035 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/walls/outer/mid_corner.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/walls/outer/outer_wall.nbt b/pumpkin-world/assets/structures/bastion/treasure/walls/outer/outer_wall.nbt new file mode 100644 index 000000000..5acfb94d3 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/walls/outer/outer_wall.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/walls/outer/tall_outer_wall.nbt b/pumpkin-world/assets/structures/bastion/treasure/walls/outer/tall_outer_wall.nbt new file mode 100644 index 000000000..62617a3ed Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/walls/outer/tall_outer_wall.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/walls/outer/top_corner.nbt b/pumpkin-world/assets/structures/bastion/treasure/walls/outer/top_corner.nbt new file mode 100644 index 000000000..f403c01bb Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/walls/outer/top_corner.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/walls/top/main_entrance.nbt b/pumpkin-world/assets/structures/bastion/treasure/walls/top/main_entrance.nbt new file mode 100644 index 000000000..eff8d5e4e Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/walls/top/main_entrance.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/walls/top/wall_0.nbt b/pumpkin-world/assets/structures/bastion/treasure/walls/top/wall_0.nbt new file mode 100644 index 000000000..540280225 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/walls/top/wall_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/treasure/walls/top/wall_1.nbt b/pumpkin-world/assets/structures/bastion/treasure/walls/top/wall_1.nbt new file mode 100644 index 000000000..87beaeec4 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/treasure/walls/top/wall_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/air_base.nbt b/pumpkin-world/assets/structures/bastion/units/air_base.nbt new file mode 100644 index 000000000..82f303487 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/air_base.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/center_pieces/center_0.nbt b/pumpkin-world/assets/structures/bastion/units/center_pieces/center_0.nbt new file mode 100644 index 000000000..7cd90ff48 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/center_pieces/center_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/center_pieces/center_1.nbt b/pumpkin-world/assets/structures/bastion/units/center_pieces/center_1.nbt new file mode 100644 index 000000000..b64b12436 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/center_pieces/center_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/center_pieces/center_2.nbt b/pumpkin-world/assets/structures/bastion/units/center_pieces/center_2.nbt new file mode 100644 index 000000000..0cf793df0 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/center_pieces/center_2.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/edges/edge_0.nbt b/pumpkin-world/assets/structures/bastion/units/edges/edge_0.nbt new file mode 100644 index 000000000..806e55366 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/edges/edge_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/fillers/stage_0.nbt b/pumpkin-world/assets/structures/bastion/units/fillers/stage_0.nbt new file mode 100644 index 000000000..e39a59436 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/fillers/stage_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/pathways/pathway_0.nbt b/pumpkin-world/assets/structures/bastion/units/pathways/pathway_0.nbt new file mode 100644 index 000000000..a4d0e3325 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/pathways/pathway_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/pathways/pathway_wall_0.nbt b/pumpkin-world/assets/structures/bastion/units/pathways/pathway_wall_0.nbt new file mode 100644 index 000000000..83b00384f Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/pathways/pathway_wall_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/rampart_plates/plate_0.nbt b/pumpkin-world/assets/structures/bastion/units/rampart_plates/plate_0.nbt new file mode 100644 index 000000000..a22bc0ae3 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/rampart_plates/plate_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/ramparts/ramparts_0.nbt b/pumpkin-world/assets/structures/bastion/units/ramparts/ramparts_0.nbt new file mode 100644 index 000000000..9bddfa1b8 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/ramparts/ramparts_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/ramparts/ramparts_1.nbt b/pumpkin-world/assets/structures/bastion/units/ramparts/ramparts_1.nbt new file mode 100644 index 000000000..b9ad35b09 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/ramparts/ramparts_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/ramparts/ramparts_2.nbt b/pumpkin-world/assets/structures/bastion/units/ramparts/ramparts_2.nbt new file mode 100644 index 000000000..55d4896a2 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/ramparts/ramparts_2.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/stages/rot/stage_1_0.nbt b/pumpkin-world/assets/structures/bastion/units/stages/rot/stage_1_0.nbt new file mode 100644 index 000000000..1265fea16 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/stages/rot/stage_1_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/stages/stage_0_0.nbt b/pumpkin-world/assets/structures/bastion/units/stages/stage_0_0.nbt new file mode 100644 index 000000000..f1fe1c0a9 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/stages/stage_0_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/stages/stage_0_1.nbt b/pumpkin-world/assets/structures/bastion/units/stages/stage_0_1.nbt new file mode 100644 index 000000000..3e0fb6aab Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/stages/stage_0_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/stages/stage_0_2.nbt b/pumpkin-world/assets/structures/bastion/units/stages/stage_0_2.nbt new file mode 100644 index 000000000..455436458 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/stages/stage_0_2.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/stages/stage_0_3.nbt b/pumpkin-world/assets/structures/bastion/units/stages/stage_0_3.nbt new file mode 100644 index 000000000..c34d2f6ec Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/stages/stage_0_3.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/stages/stage_1_0.nbt b/pumpkin-world/assets/structures/bastion/units/stages/stage_1_0.nbt new file mode 100644 index 000000000..fbb842673 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/stages/stage_1_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/stages/stage_1_1.nbt b/pumpkin-world/assets/structures/bastion/units/stages/stage_1_1.nbt new file mode 100644 index 000000000..e36179874 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/stages/stage_1_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/stages/stage_1_2.nbt b/pumpkin-world/assets/structures/bastion/units/stages/stage_1_2.nbt new file mode 100644 index 000000000..69b5ac3fb Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/stages/stage_1_2.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/stages/stage_1_3.nbt b/pumpkin-world/assets/structures/bastion/units/stages/stage_1_3.nbt new file mode 100644 index 000000000..bda604124 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/stages/stage_1_3.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/stages/stage_2_0.nbt b/pumpkin-world/assets/structures/bastion/units/stages/stage_2_0.nbt new file mode 100644 index 000000000..d8b878a06 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/stages/stage_2_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/stages/stage_2_1.nbt b/pumpkin-world/assets/structures/bastion/units/stages/stage_2_1.nbt new file mode 100644 index 000000000..6d8f0da92 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/stages/stage_2_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/stages/stage_3_0.nbt b/pumpkin-world/assets/structures/bastion/units/stages/stage_3_0.nbt new file mode 100644 index 000000000..1eb964c36 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/stages/stage_3_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/stages/stage_3_1.nbt b/pumpkin-world/assets/structures/bastion/units/stages/stage_3_1.nbt new file mode 100644 index 000000000..1e53e6c1f Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/stages/stage_3_1.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/stages/stage_3_2.nbt b/pumpkin-world/assets/structures/bastion/units/stages/stage_3_2.nbt new file mode 100644 index 000000000..563466212 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/stages/stage_3_2.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/stages/stage_3_3.nbt b/pumpkin-world/assets/structures/bastion/units/stages/stage_3_3.nbt new file mode 100644 index 000000000..b90df0187 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/stages/stage_3_3.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/wall_units/edge_0_large.nbt b/pumpkin-world/assets/structures/bastion/units/wall_units/edge_0_large.nbt new file mode 100644 index 000000000..360038d3b Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/wall_units/edge_0_large.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/wall_units/unit_0.nbt b/pumpkin-world/assets/structures/bastion/units/wall_units/unit_0.nbt new file mode 100644 index 000000000..7f8dc2314 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/wall_units/unit_0.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/walls/connected_wall.nbt b/pumpkin-world/assets/structures/bastion/units/walls/connected_wall.nbt new file mode 100644 index 000000000..cd4016f61 Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/walls/connected_wall.nbt differ diff --git a/pumpkin-world/assets/structures/bastion/units/walls/wall_base.nbt b/pumpkin-world/assets/structures/bastion/units/walls/wall_base.nbt new file mode 100644 index 000000000..23888bc6c Binary files /dev/null and b/pumpkin-world/assets/structures/bastion/units/walls/wall_base.nbt differ diff --git a/pumpkin-world/assets/structures/empty.nbt b/pumpkin-world/assets/structures/empty.nbt new file mode 100644 index 000000000..9850b6650 Binary files /dev/null and b/pumpkin-world/assets/structures/empty.nbt differ diff --git a/pumpkin-world/assets/structures/end_city/base_floor.nbt b/pumpkin-world/assets/structures/end_city/base_floor.nbt new file mode 100644 index 000000000..ee63ba369 Binary files /dev/null and b/pumpkin-world/assets/structures/end_city/base_floor.nbt differ diff --git a/pumpkin-world/assets/structures/end_city/base_roof.nbt b/pumpkin-world/assets/structures/end_city/base_roof.nbt new file mode 100644 index 000000000..8449b59d4 Binary files /dev/null and b/pumpkin-world/assets/structures/end_city/base_roof.nbt differ diff --git a/pumpkin-world/assets/structures/end_city/bridge_end.nbt b/pumpkin-world/assets/structures/end_city/bridge_end.nbt new file mode 100644 index 000000000..6133068b5 Binary files /dev/null and b/pumpkin-world/assets/structures/end_city/bridge_end.nbt differ diff --git a/pumpkin-world/assets/structures/end_city/bridge_gentle_stairs.nbt b/pumpkin-world/assets/structures/end_city/bridge_gentle_stairs.nbt new file mode 100644 index 000000000..c569a6942 Binary files /dev/null and b/pumpkin-world/assets/structures/end_city/bridge_gentle_stairs.nbt differ diff --git a/pumpkin-world/assets/structures/end_city/bridge_piece.nbt b/pumpkin-world/assets/structures/end_city/bridge_piece.nbt new file mode 100644 index 000000000..8e540e234 Binary files /dev/null and b/pumpkin-world/assets/structures/end_city/bridge_piece.nbt differ diff --git a/pumpkin-world/assets/structures/end_city/bridge_steep_stairs.nbt b/pumpkin-world/assets/structures/end_city/bridge_steep_stairs.nbt new file mode 100644 index 000000000..fa14ae5a6 Binary files /dev/null and b/pumpkin-world/assets/structures/end_city/bridge_steep_stairs.nbt differ diff --git a/pumpkin-world/assets/structures/end_city/fat_tower_base.nbt b/pumpkin-world/assets/structures/end_city/fat_tower_base.nbt new file mode 100644 index 000000000..b8ea61d52 Binary files /dev/null and b/pumpkin-world/assets/structures/end_city/fat_tower_base.nbt differ diff --git a/pumpkin-world/assets/structures/end_city/fat_tower_middle.nbt b/pumpkin-world/assets/structures/end_city/fat_tower_middle.nbt new file mode 100644 index 000000000..d40488a92 Binary files /dev/null and b/pumpkin-world/assets/structures/end_city/fat_tower_middle.nbt differ diff --git a/pumpkin-world/assets/structures/end_city/fat_tower_top.nbt b/pumpkin-world/assets/structures/end_city/fat_tower_top.nbt new file mode 100644 index 000000000..5bd91515b Binary files /dev/null and b/pumpkin-world/assets/structures/end_city/fat_tower_top.nbt differ diff --git a/pumpkin-world/assets/structures/end_city/second_floor_1.nbt b/pumpkin-world/assets/structures/end_city/second_floor_1.nbt new file mode 100644 index 000000000..567fea328 Binary files /dev/null and b/pumpkin-world/assets/structures/end_city/second_floor_1.nbt differ diff --git a/pumpkin-world/assets/structures/end_city/second_floor_2.nbt b/pumpkin-world/assets/structures/end_city/second_floor_2.nbt new file mode 100644 index 000000000..f31822ac0 Binary files /dev/null and b/pumpkin-world/assets/structures/end_city/second_floor_2.nbt differ diff --git a/pumpkin-world/assets/structures/end_city/second_roof.nbt b/pumpkin-world/assets/structures/end_city/second_roof.nbt new file mode 100644 index 000000000..2871d6cc8 Binary files /dev/null and b/pumpkin-world/assets/structures/end_city/second_roof.nbt differ diff --git a/pumpkin-world/assets/structures/end_city/ship.nbt b/pumpkin-world/assets/structures/end_city/ship.nbt new file mode 100644 index 000000000..1da52743c Binary files /dev/null and b/pumpkin-world/assets/structures/end_city/ship.nbt differ diff --git a/pumpkin-world/assets/structures/end_city/third_floor_1.nbt b/pumpkin-world/assets/structures/end_city/third_floor_1.nbt new file mode 100644 index 000000000..5d5144a56 Binary files /dev/null and b/pumpkin-world/assets/structures/end_city/third_floor_1.nbt differ diff --git a/pumpkin-world/assets/structures/end_city/third_floor_2.nbt b/pumpkin-world/assets/structures/end_city/third_floor_2.nbt new file mode 100644 index 000000000..f0a574a7d Binary files /dev/null and b/pumpkin-world/assets/structures/end_city/third_floor_2.nbt differ diff --git a/pumpkin-world/assets/structures/end_city/third_roof.nbt b/pumpkin-world/assets/structures/end_city/third_roof.nbt new file mode 100644 index 000000000..5e6d9df91 Binary files /dev/null and b/pumpkin-world/assets/structures/end_city/third_roof.nbt differ diff --git a/pumpkin-world/assets/structures/end_city/tower_base.nbt b/pumpkin-world/assets/structures/end_city/tower_base.nbt new file mode 100644 index 000000000..745ebc53c Binary files /dev/null and b/pumpkin-world/assets/structures/end_city/tower_base.nbt differ diff --git a/pumpkin-world/assets/structures/end_city/tower_floor.nbt b/pumpkin-world/assets/structures/end_city/tower_floor.nbt new file mode 100644 index 000000000..218ce5b46 Binary files /dev/null and b/pumpkin-world/assets/structures/end_city/tower_floor.nbt differ diff --git a/pumpkin-world/assets/structures/end_city/tower_piece.nbt b/pumpkin-world/assets/structures/end_city/tower_piece.nbt new file mode 100644 index 000000000..b79ae01b0 Binary files /dev/null and b/pumpkin-world/assets/structures/end_city/tower_piece.nbt differ diff --git a/pumpkin-world/assets/structures/end_city/tower_top.nbt b/pumpkin-world/assets/structures/end_city/tower_top.nbt new file mode 100644 index 000000000..5f00f4b3f Binary files /dev/null and b/pumpkin-world/assets/structures/end_city/tower_top.nbt differ diff --git a/pumpkin-world/assets/structures/fossil/skull_1.nbt b/pumpkin-world/assets/structures/fossil/skull_1.nbt new file mode 100644 index 000000000..c20b0dd23 Binary files /dev/null and b/pumpkin-world/assets/structures/fossil/skull_1.nbt differ diff --git a/pumpkin-world/assets/structures/fossil/skull_1_coal.nbt b/pumpkin-world/assets/structures/fossil/skull_1_coal.nbt new file mode 100644 index 000000000..7b77a8be1 Binary files /dev/null and b/pumpkin-world/assets/structures/fossil/skull_1_coal.nbt differ diff --git a/pumpkin-world/assets/structures/fossil/skull_2.nbt b/pumpkin-world/assets/structures/fossil/skull_2.nbt new file mode 100644 index 000000000..5bd38a0d3 Binary files /dev/null and b/pumpkin-world/assets/structures/fossil/skull_2.nbt differ diff --git a/pumpkin-world/assets/structures/fossil/skull_2_coal.nbt b/pumpkin-world/assets/structures/fossil/skull_2_coal.nbt new file mode 100644 index 000000000..30fc54d1a Binary files /dev/null and b/pumpkin-world/assets/structures/fossil/skull_2_coal.nbt differ diff --git a/pumpkin-world/assets/structures/fossil/skull_3.nbt b/pumpkin-world/assets/structures/fossil/skull_3.nbt new file mode 100644 index 000000000..833bfcb28 Binary files /dev/null and b/pumpkin-world/assets/structures/fossil/skull_3.nbt differ diff --git a/pumpkin-world/assets/structures/fossil/skull_3_coal.nbt b/pumpkin-world/assets/structures/fossil/skull_3_coal.nbt new file mode 100644 index 000000000..93b1c68c5 Binary files /dev/null and b/pumpkin-world/assets/structures/fossil/skull_3_coal.nbt differ diff --git a/pumpkin-world/assets/structures/fossil/skull_4.nbt b/pumpkin-world/assets/structures/fossil/skull_4.nbt new file mode 100644 index 000000000..c68836d3e Binary files /dev/null and b/pumpkin-world/assets/structures/fossil/skull_4.nbt differ diff --git a/pumpkin-world/assets/structures/fossil/skull_4_coal.nbt b/pumpkin-world/assets/structures/fossil/skull_4_coal.nbt new file mode 100644 index 000000000..d95295d35 Binary files /dev/null and b/pumpkin-world/assets/structures/fossil/skull_4_coal.nbt differ diff --git a/pumpkin-world/assets/structures/fossil/spine_1.nbt b/pumpkin-world/assets/structures/fossil/spine_1.nbt new file mode 100644 index 000000000..6b9cdef80 Binary files /dev/null and b/pumpkin-world/assets/structures/fossil/spine_1.nbt differ diff --git a/pumpkin-world/assets/structures/fossil/spine_1_coal.nbt b/pumpkin-world/assets/structures/fossil/spine_1_coal.nbt new file mode 100644 index 000000000..6a8afd1f6 Binary files /dev/null and b/pumpkin-world/assets/structures/fossil/spine_1_coal.nbt differ diff --git a/pumpkin-world/assets/structures/fossil/spine_2.nbt b/pumpkin-world/assets/structures/fossil/spine_2.nbt new file mode 100644 index 000000000..7f3086553 Binary files /dev/null and b/pumpkin-world/assets/structures/fossil/spine_2.nbt differ diff --git a/pumpkin-world/assets/structures/fossil/spine_2_coal.nbt b/pumpkin-world/assets/structures/fossil/spine_2_coal.nbt new file mode 100644 index 000000000..f6d0943a1 Binary files /dev/null and b/pumpkin-world/assets/structures/fossil/spine_2_coal.nbt differ diff --git a/pumpkin-world/assets/structures/fossil/spine_3.nbt b/pumpkin-world/assets/structures/fossil/spine_3.nbt new file mode 100644 index 000000000..c565601b6 Binary files /dev/null and b/pumpkin-world/assets/structures/fossil/spine_3.nbt differ diff --git a/pumpkin-world/assets/structures/fossil/spine_3_coal.nbt b/pumpkin-world/assets/structures/fossil/spine_3_coal.nbt new file mode 100644 index 000000000..d7ee9864b Binary files /dev/null and b/pumpkin-world/assets/structures/fossil/spine_3_coal.nbt differ diff --git a/pumpkin-world/assets/structures/fossil/spine_4.nbt b/pumpkin-world/assets/structures/fossil/spine_4.nbt new file mode 100644 index 000000000..b9b765489 Binary files /dev/null and b/pumpkin-world/assets/structures/fossil/spine_4.nbt differ diff --git a/pumpkin-world/assets/structures/fossil/spine_4_coal.nbt b/pumpkin-world/assets/structures/fossil/spine_4_coal.nbt new file mode 100644 index 000000000..d6cd51a02 Binary files /dev/null and b/pumpkin-world/assets/structures/fossil/spine_4_coal.nbt differ diff --git a/pumpkin-world/assets/structures/igloo/bottom.nbt b/pumpkin-world/assets/structures/igloo/bottom.nbt index fe1c87112..c1d0aa946 100644 Binary files a/pumpkin-world/assets/structures/igloo/bottom.nbt and b/pumpkin-world/assets/structures/igloo/bottom.nbt differ diff --git a/pumpkin-world/assets/structures/igloo/middle.nbt b/pumpkin-world/assets/structures/igloo/middle.nbt index 1c22fa065..8ece442c1 100644 Binary files a/pumpkin-world/assets/structures/igloo/middle.nbt and b/pumpkin-world/assets/structures/igloo/middle.nbt differ diff --git a/pumpkin-world/assets/structures/igloo/top.nbt b/pumpkin-world/assets/structures/igloo/top.nbt index a7f899cbb..ef5ed0107 100644 Binary files a/pumpkin-world/assets/structures/igloo/top.nbt and b/pumpkin-world/assets/structures/igloo/top.nbt differ diff --git a/pumpkin-world/assets/structures/nether_fossils/fossil_1.nbt b/pumpkin-world/assets/structures/nether_fossils/fossil_1.nbt index dfc1a6446..4b4d65418 100644 Binary files a/pumpkin-world/assets/structures/nether_fossils/fossil_1.nbt and b/pumpkin-world/assets/structures/nether_fossils/fossil_1.nbt differ diff --git a/pumpkin-world/assets/structures/nether_fossils/fossil_10.nbt b/pumpkin-world/assets/structures/nether_fossils/fossil_10.nbt index b9b981f73..2c349204d 100644 Binary files a/pumpkin-world/assets/structures/nether_fossils/fossil_10.nbt and b/pumpkin-world/assets/structures/nether_fossils/fossil_10.nbt differ diff --git a/pumpkin-world/assets/structures/nether_fossils/fossil_11.nbt b/pumpkin-world/assets/structures/nether_fossils/fossil_11.nbt index db64b608e..3a050f6bf 100644 Binary files a/pumpkin-world/assets/structures/nether_fossils/fossil_11.nbt and b/pumpkin-world/assets/structures/nether_fossils/fossil_11.nbt differ diff --git a/pumpkin-world/assets/structures/nether_fossils/fossil_12.nbt b/pumpkin-world/assets/structures/nether_fossils/fossil_12.nbt index 751c6cf30..525269727 100644 Binary files a/pumpkin-world/assets/structures/nether_fossils/fossil_12.nbt and b/pumpkin-world/assets/structures/nether_fossils/fossil_12.nbt differ diff --git a/pumpkin-world/assets/structures/nether_fossils/fossil_13.nbt b/pumpkin-world/assets/structures/nether_fossils/fossil_13.nbt index 46822482a..981d06d57 100644 Binary files a/pumpkin-world/assets/structures/nether_fossils/fossil_13.nbt and b/pumpkin-world/assets/structures/nether_fossils/fossil_13.nbt differ diff --git a/pumpkin-world/assets/structures/nether_fossils/fossil_14.nbt b/pumpkin-world/assets/structures/nether_fossils/fossil_14.nbt index 1a9a4294b..71e7c78c5 100644 Binary files a/pumpkin-world/assets/structures/nether_fossils/fossil_14.nbt and b/pumpkin-world/assets/structures/nether_fossils/fossil_14.nbt differ diff --git a/pumpkin-world/assets/structures/nether_fossils/fossil_2.nbt b/pumpkin-world/assets/structures/nether_fossils/fossil_2.nbt index 0f717ab88..5f80b1632 100644 Binary files a/pumpkin-world/assets/structures/nether_fossils/fossil_2.nbt and b/pumpkin-world/assets/structures/nether_fossils/fossil_2.nbt differ diff --git a/pumpkin-world/assets/structures/nether_fossils/fossil_3.nbt b/pumpkin-world/assets/structures/nether_fossils/fossil_3.nbt index 7a4e05cf7..4029285ce 100644 Binary files a/pumpkin-world/assets/structures/nether_fossils/fossil_3.nbt and b/pumpkin-world/assets/structures/nether_fossils/fossil_3.nbt differ diff --git a/pumpkin-world/assets/structures/nether_fossils/fossil_4.nbt b/pumpkin-world/assets/structures/nether_fossils/fossil_4.nbt index e4c722b17..3151592a7 100644 Binary files a/pumpkin-world/assets/structures/nether_fossils/fossil_4.nbt and b/pumpkin-world/assets/structures/nether_fossils/fossil_4.nbt differ diff --git a/pumpkin-world/assets/structures/nether_fossils/fossil_5.nbt b/pumpkin-world/assets/structures/nether_fossils/fossil_5.nbt index e6ebc1021..344cc2016 100644 Binary files a/pumpkin-world/assets/structures/nether_fossils/fossil_5.nbt and b/pumpkin-world/assets/structures/nether_fossils/fossil_5.nbt differ diff --git a/pumpkin-world/assets/structures/nether_fossils/fossil_6.nbt b/pumpkin-world/assets/structures/nether_fossils/fossil_6.nbt index 7db72cb99..7142152f6 100644 Binary files a/pumpkin-world/assets/structures/nether_fossils/fossil_6.nbt and b/pumpkin-world/assets/structures/nether_fossils/fossil_6.nbt differ diff --git a/pumpkin-world/assets/structures/nether_fossils/fossil_7.nbt b/pumpkin-world/assets/structures/nether_fossils/fossil_7.nbt index f9fa09c7d..b38f050ed 100644 Binary files a/pumpkin-world/assets/structures/nether_fossils/fossil_7.nbt and b/pumpkin-world/assets/structures/nether_fossils/fossil_7.nbt differ diff --git a/pumpkin-world/assets/structures/nether_fossils/fossil_8.nbt b/pumpkin-world/assets/structures/nether_fossils/fossil_8.nbt index c14268d6b..9571c4286 100644 Binary files a/pumpkin-world/assets/structures/nether_fossils/fossil_8.nbt and b/pumpkin-world/assets/structures/nether_fossils/fossil_8.nbt differ diff --git a/pumpkin-world/assets/structures/nether_fossils/fossil_9.nbt b/pumpkin-world/assets/structures/nether_fossils/fossil_9.nbt index 9d2c78e2f..5d0837c97 100644 Binary files a/pumpkin-world/assets/structures/nether_fossils/fossil_9.nbt and b/pumpkin-world/assets/structures/nether_fossils/fossil_9.nbt differ diff --git a/pumpkin-world/assets/structures/pillager_outpost/base_plate.nbt b/pumpkin-world/assets/structures/pillager_outpost/base_plate.nbt new file mode 100644 index 000000000..b8b25e893 Binary files /dev/null and b/pumpkin-world/assets/structures/pillager_outpost/base_plate.nbt differ diff --git a/pumpkin-world/assets/structures/pillager_outpost/feature_cage1.nbt b/pumpkin-world/assets/structures/pillager_outpost/feature_cage1.nbt new file mode 100644 index 000000000..35a114421 Binary files /dev/null and b/pumpkin-world/assets/structures/pillager_outpost/feature_cage1.nbt differ diff --git a/pumpkin-world/assets/structures/pillager_outpost/feature_cage2.nbt b/pumpkin-world/assets/structures/pillager_outpost/feature_cage2.nbt new file mode 100644 index 000000000..0b513fb5d Binary files /dev/null and b/pumpkin-world/assets/structures/pillager_outpost/feature_cage2.nbt differ diff --git a/pumpkin-world/assets/structures/pillager_outpost/feature_cage_with_allays.nbt b/pumpkin-world/assets/structures/pillager_outpost/feature_cage_with_allays.nbt new file mode 100644 index 000000000..8c9e3b6f0 Binary files /dev/null and b/pumpkin-world/assets/structures/pillager_outpost/feature_cage_with_allays.nbt differ diff --git a/pumpkin-world/assets/structures/pillager_outpost/feature_logs.nbt b/pumpkin-world/assets/structures/pillager_outpost/feature_logs.nbt new file mode 100644 index 000000000..fe487bc86 Binary files /dev/null and b/pumpkin-world/assets/structures/pillager_outpost/feature_logs.nbt differ diff --git a/pumpkin-world/assets/structures/pillager_outpost/feature_plate.nbt b/pumpkin-world/assets/structures/pillager_outpost/feature_plate.nbt new file mode 100644 index 000000000..18499a9c5 Binary files /dev/null and b/pumpkin-world/assets/structures/pillager_outpost/feature_plate.nbt differ diff --git a/pumpkin-world/assets/structures/pillager_outpost/feature_targets.nbt b/pumpkin-world/assets/structures/pillager_outpost/feature_targets.nbt new file mode 100644 index 000000000..0c1aac401 Binary files /dev/null and b/pumpkin-world/assets/structures/pillager_outpost/feature_targets.nbt differ diff --git a/pumpkin-world/assets/structures/pillager_outpost/feature_tent1.nbt b/pumpkin-world/assets/structures/pillager_outpost/feature_tent1.nbt new file mode 100644 index 000000000..17ec84d19 Binary files /dev/null and b/pumpkin-world/assets/structures/pillager_outpost/feature_tent1.nbt differ diff --git a/pumpkin-world/assets/structures/pillager_outpost/feature_tent2.nbt b/pumpkin-world/assets/structures/pillager_outpost/feature_tent2.nbt new file mode 100644 index 000000000..a5061b0d6 Binary files /dev/null and b/pumpkin-world/assets/structures/pillager_outpost/feature_tent2.nbt differ diff --git a/pumpkin-world/assets/structures/pillager_outpost/watchtower.nbt b/pumpkin-world/assets/structures/pillager_outpost/watchtower.nbt new file mode 100644 index 000000000..1e2e02957 Binary files /dev/null and b/pumpkin-world/assets/structures/pillager_outpost/watchtower.nbt differ diff --git a/pumpkin-world/assets/structures/pillager_outpost/watchtower_overgrown.nbt b/pumpkin-world/assets/structures/pillager_outpost/watchtower_overgrown.nbt new file mode 100644 index 000000000..49c8daa34 Binary files /dev/null and b/pumpkin-world/assets/structures/pillager_outpost/watchtower_overgrown.nbt differ diff --git a/pumpkin-world/assets/structures/ruined_portal/giant_portal_1.nbt b/pumpkin-world/assets/structures/ruined_portal/giant_portal_1.nbt new file mode 100644 index 000000000..1fc2e2be6 Binary files /dev/null and b/pumpkin-world/assets/structures/ruined_portal/giant_portal_1.nbt differ diff --git a/pumpkin-world/assets/structures/ruined_portal/giant_portal_2.nbt b/pumpkin-world/assets/structures/ruined_portal/giant_portal_2.nbt new file mode 100644 index 000000000..3aa35c93b Binary files /dev/null and b/pumpkin-world/assets/structures/ruined_portal/giant_portal_2.nbt differ diff --git a/pumpkin-world/assets/structures/ruined_portal/giant_portal_3.nbt b/pumpkin-world/assets/structures/ruined_portal/giant_portal_3.nbt new file mode 100644 index 000000000..659803f8e Binary files /dev/null and b/pumpkin-world/assets/structures/ruined_portal/giant_portal_3.nbt differ diff --git a/pumpkin-world/assets/structures/ruined_portal/portal_1.nbt b/pumpkin-world/assets/structures/ruined_portal/portal_1.nbt new file mode 100644 index 000000000..02cd40803 Binary files /dev/null and b/pumpkin-world/assets/structures/ruined_portal/portal_1.nbt differ diff --git a/pumpkin-world/assets/structures/ruined_portal/portal_10.nbt b/pumpkin-world/assets/structures/ruined_portal/portal_10.nbt new file mode 100644 index 000000000..77f49b01e Binary files /dev/null and b/pumpkin-world/assets/structures/ruined_portal/portal_10.nbt differ diff --git a/pumpkin-world/assets/structures/ruined_portal/portal_2.nbt b/pumpkin-world/assets/structures/ruined_portal/portal_2.nbt new file mode 100644 index 000000000..2f3d3c499 Binary files /dev/null and b/pumpkin-world/assets/structures/ruined_portal/portal_2.nbt differ diff --git a/pumpkin-world/assets/structures/ruined_portal/portal_3.nbt b/pumpkin-world/assets/structures/ruined_portal/portal_3.nbt new file mode 100644 index 000000000..325278765 Binary files /dev/null and b/pumpkin-world/assets/structures/ruined_portal/portal_3.nbt differ diff --git a/pumpkin-world/assets/structures/ruined_portal/portal_4.nbt b/pumpkin-world/assets/structures/ruined_portal/portal_4.nbt new file mode 100644 index 000000000..6cbedac6d Binary files /dev/null and b/pumpkin-world/assets/structures/ruined_portal/portal_4.nbt differ diff --git a/pumpkin-world/assets/structures/ruined_portal/portal_5.nbt b/pumpkin-world/assets/structures/ruined_portal/portal_5.nbt new file mode 100644 index 000000000..aefbf66a3 Binary files /dev/null and b/pumpkin-world/assets/structures/ruined_portal/portal_5.nbt differ diff --git a/pumpkin-world/assets/structures/ruined_portal/portal_6.nbt b/pumpkin-world/assets/structures/ruined_portal/portal_6.nbt new file mode 100644 index 000000000..5626a6f51 Binary files /dev/null and b/pumpkin-world/assets/structures/ruined_portal/portal_6.nbt differ diff --git a/pumpkin-world/assets/structures/ruined_portal/portal_7.nbt b/pumpkin-world/assets/structures/ruined_portal/portal_7.nbt new file mode 100644 index 000000000..3b3b890b5 Binary files /dev/null and b/pumpkin-world/assets/structures/ruined_portal/portal_7.nbt differ diff --git a/pumpkin-world/assets/structures/ruined_portal/portal_8.nbt b/pumpkin-world/assets/structures/ruined_portal/portal_8.nbt new file mode 100644 index 000000000..e2ea4352e Binary files /dev/null and b/pumpkin-world/assets/structures/ruined_portal/portal_8.nbt differ diff --git a/pumpkin-world/assets/structures/ruined_portal/portal_9.nbt b/pumpkin-world/assets/structures/ruined_portal/portal_9.nbt new file mode 100644 index 000000000..12afd6dd0 Binary files /dev/null and b/pumpkin-world/assets/structures/ruined_portal/portal_9.nbt differ diff --git a/pumpkin-world/assets/structures/shipwreck/rightsideup_backhalf.nbt b/pumpkin-world/assets/structures/shipwreck/rightsideup_backhalf.nbt new file mode 100644 index 000000000..399aea373 Binary files /dev/null and b/pumpkin-world/assets/structures/shipwreck/rightsideup_backhalf.nbt differ diff --git a/pumpkin-world/assets/structures/shipwreck/rightsideup_backhalf_degraded.nbt b/pumpkin-world/assets/structures/shipwreck/rightsideup_backhalf_degraded.nbt new file mode 100644 index 000000000..1761acb32 Binary files /dev/null and b/pumpkin-world/assets/structures/shipwreck/rightsideup_backhalf_degraded.nbt differ diff --git a/pumpkin-world/assets/structures/shipwreck/rightsideup_fronthalf.nbt b/pumpkin-world/assets/structures/shipwreck/rightsideup_fronthalf.nbt new file mode 100644 index 000000000..8d3bcb3de Binary files /dev/null and b/pumpkin-world/assets/structures/shipwreck/rightsideup_fronthalf.nbt differ diff --git a/pumpkin-world/assets/structures/shipwreck/rightsideup_fronthalf_degraded.nbt b/pumpkin-world/assets/structures/shipwreck/rightsideup_fronthalf_degraded.nbt new file mode 100644 index 000000000..5c99c8e45 Binary files /dev/null and b/pumpkin-world/assets/structures/shipwreck/rightsideup_fronthalf_degraded.nbt differ diff --git a/pumpkin-world/assets/structures/shipwreck/rightsideup_full.nbt b/pumpkin-world/assets/structures/shipwreck/rightsideup_full.nbt new file mode 100644 index 000000000..d8ade595f Binary files /dev/null and b/pumpkin-world/assets/structures/shipwreck/rightsideup_full.nbt differ diff --git a/pumpkin-world/assets/structures/shipwreck/rightsideup_full_degraded.nbt b/pumpkin-world/assets/structures/shipwreck/rightsideup_full_degraded.nbt new file mode 100644 index 000000000..036d2f151 Binary files /dev/null and b/pumpkin-world/assets/structures/shipwreck/rightsideup_full_degraded.nbt differ diff --git a/pumpkin-world/assets/structures/shipwreck/sideways_backhalf.nbt b/pumpkin-world/assets/structures/shipwreck/sideways_backhalf.nbt new file mode 100644 index 000000000..5d9c8c968 Binary files /dev/null and b/pumpkin-world/assets/structures/shipwreck/sideways_backhalf.nbt differ diff --git a/pumpkin-world/assets/structures/shipwreck/sideways_backhalf_degraded.nbt b/pumpkin-world/assets/structures/shipwreck/sideways_backhalf_degraded.nbt new file mode 100644 index 000000000..13c915f3c Binary files /dev/null and b/pumpkin-world/assets/structures/shipwreck/sideways_backhalf_degraded.nbt differ diff --git a/pumpkin-world/assets/structures/shipwreck/sideways_fronthalf.nbt b/pumpkin-world/assets/structures/shipwreck/sideways_fronthalf.nbt new file mode 100644 index 000000000..58b1f6ffd Binary files /dev/null and b/pumpkin-world/assets/structures/shipwreck/sideways_fronthalf.nbt differ diff --git a/pumpkin-world/assets/structures/shipwreck/sideways_fronthalf_degraded.nbt b/pumpkin-world/assets/structures/shipwreck/sideways_fronthalf_degraded.nbt new file mode 100644 index 000000000..a3d7bc42a Binary files /dev/null and b/pumpkin-world/assets/structures/shipwreck/sideways_fronthalf_degraded.nbt differ diff --git a/pumpkin-world/assets/structures/shipwreck/sideways_full.nbt b/pumpkin-world/assets/structures/shipwreck/sideways_full.nbt new file mode 100644 index 000000000..14df05ed6 Binary files /dev/null and b/pumpkin-world/assets/structures/shipwreck/sideways_full.nbt differ diff --git a/pumpkin-world/assets/structures/shipwreck/sideways_full_degraded.nbt b/pumpkin-world/assets/structures/shipwreck/sideways_full_degraded.nbt new file mode 100644 index 000000000..05b5a4e3b Binary files /dev/null and b/pumpkin-world/assets/structures/shipwreck/sideways_full_degraded.nbt differ diff --git a/pumpkin-world/assets/structures/shipwreck/upsidedown_backhalf.nbt b/pumpkin-world/assets/structures/shipwreck/upsidedown_backhalf.nbt new file mode 100644 index 000000000..c444eebd2 Binary files /dev/null and b/pumpkin-world/assets/structures/shipwreck/upsidedown_backhalf.nbt differ diff --git a/pumpkin-world/assets/structures/shipwreck/upsidedown_backhalf_degraded.nbt b/pumpkin-world/assets/structures/shipwreck/upsidedown_backhalf_degraded.nbt new file mode 100644 index 000000000..695a3e4b3 Binary files /dev/null and b/pumpkin-world/assets/structures/shipwreck/upsidedown_backhalf_degraded.nbt differ diff --git a/pumpkin-world/assets/structures/shipwreck/upsidedown_fronthalf.nbt b/pumpkin-world/assets/structures/shipwreck/upsidedown_fronthalf.nbt new file mode 100644 index 000000000..b87e2ca9e Binary files /dev/null and b/pumpkin-world/assets/structures/shipwreck/upsidedown_fronthalf.nbt differ diff --git a/pumpkin-world/assets/structures/shipwreck/upsidedown_fronthalf_degraded.nbt b/pumpkin-world/assets/structures/shipwreck/upsidedown_fronthalf_degraded.nbt new file mode 100644 index 000000000..e7d38272e Binary files /dev/null and b/pumpkin-world/assets/structures/shipwreck/upsidedown_fronthalf_degraded.nbt differ diff --git a/pumpkin-world/assets/structures/shipwreck/upsidedown_full.nbt b/pumpkin-world/assets/structures/shipwreck/upsidedown_full.nbt new file mode 100644 index 000000000..7b334994f Binary files /dev/null and b/pumpkin-world/assets/structures/shipwreck/upsidedown_full.nbt differ diff --git a/pumpkin-world/assets/structures/shipwreck/upsidedown_full_degraded.nbt b/pumpkin-world/assets/structures/shipwreck/upsidedown_full_degraded.nbt new file mode 100644 index 000000000..e60e28d0c Binary files /dev/null and b/pumpkin-world/assets/structures/shipwreck/upsidedown_full_degraded.nbt differ diff --git a/pumpkin-world/assets/structures/shipwreck/with_mast.nbt b/pumpkin-world/assets/structures/shipwreck/with_mast.nbt new file mode 100644 index 000000000..9187e09c4 Binary files /dev/null and b/pumpkin-world/assets/structures/shipwreck/with_mast.nbt differ diff --git a/pumpkin-world/assets/structures/shipwreck/with_mast_degraded.nbt b/pumpkin-world/assets/structures/shipwreck/with_mast_degraded.nbt new file mode 100644 index 000000000..3497e1188 Binary files /dev/null and b/pumpkin-world/assets/structures/shipwreck/with_mast_degraded.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_full_1.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_full_1.nbt new file mode 100644 index 000000000..33815ed0d Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_full_1.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_full_2.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_full_2.nbt new file mode 100644 index 000000000..973409a19 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_full_2.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_full_3.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_full_3.nbt new file mode 100644 index 000000000..7c7206bba Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_full_3.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_full_4.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_full_4.nbt new file mode 100644 index 000000000..b0f44680e Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_full_4.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_full_5.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_full_5.nbt new file mode 100644 index 000000000..62a5883c1 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_full_5.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_hall_1.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_hall_1.nbt new file mode 100644 index 000000000..d6cb2c84d Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_hall_1.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_hall_2.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_hall_2.nbt new file mode 100644 index 000000000..eefa6d492 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_hall_2.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_hall_3.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_hall_3.nbt new file mode 100644 index 000000000..e50ba3de5 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_hall_3.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_hall_4.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_hall_4.nbt new file mode 100644 index 000000000..24264b43d Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_hall_4.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_hall_5.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_hall_5.nbt new file mode 100644 index 000000000..77fc9fd88 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_hall_5.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_lower_1.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_lower_1.nbt new file mode 100644 index 000000000..912c874a7 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_lower_1.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_lower_2.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_lower_2.nbt new file mode 100644 index 000000000..1b63cfee0 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_lower_2.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_lower_3.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_lower_3.nbt new file mode 100644 index 000000000..70408fe9d Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_lower_3.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_lower_4.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_lower_4.nbt new file mode 100644 index 000000000..487591537 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_lower_4.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_lower_5.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_lower_5.nbt new file mode 100644 index 000000000..0c1609ab4 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_lower_5.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_room_1.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_room_1.nbt new file mode 100644 index 000000000..783a34bc9 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_room_1.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_room_2.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_room_2.nbt new file mode 100644 index 000000000..087d94ce4 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_room_2.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_room_3.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_room_3.nbt new file mode 100644 index 000000000..6319f5fe6 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_room_3.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_room_4.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_room_4.nbt new file mode 100644 index 000000000..35848c6dd Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_room_4.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_room_5.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_room_5.nbt new file mode 100644 index 000000000..43fc1727b Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_room_5.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_upper_1.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_upper_1.nbt new file mode 100644 index 000000000..c0e794b22 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_upper_1.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_upper_2.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_upper_2.nbt new file mode 100644 index 000000000..c9f18d0ae Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_upper_2.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_upper_3.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_upper_3.nbt new file mode 100644 index 000000000..9d9037ae4 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_upper_3.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_upper_4.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_upper_4.nbt new file mode 100644 index 000000000..f42e28638 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_upper_4.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/group_upper_5.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/group_upper_5.nbt new file mode 100644 index 000000000..2a49d0514 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/group_upper_5.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/large_room_1.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/large_room_1.nbt new file mode 100644 index 000000000..501445891 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/large_room_1.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/large_room_2.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/large_room_2.nbt new file mode 100644 index 000000000..8e13e71dc Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/large_room_2.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/large_room_3.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/large_room_3.nbt new file mode 100644 index 000000000..6526820f1 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/large_room_3.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/large_room_4.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/large_room_4.nbt new file mode 100644 index 000000000..4820a0911 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/large_room_4.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/large_room_5.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/large_room_5.nbt new file mode 100644 index 000000000..de7d5b283 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/large_room_5.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/one_room_1.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/one_room_1.nbt new file mode 100644 index 000000000..e5067967f Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/one_room_1.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/one_room_2.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/one_room_2.nbt new file mode 100644 index 000000000..5b0b0e02f Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/one_room_2.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/one_room_3.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/one_room_3.nbt new file mode 100644 index 000000000..a497f4aa6 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/one_room_3.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/one_room_4.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/one_room_4.nbt new file mode 100644 index 000000000..9a0511908 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/one_room_4.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/buildings/one_room_5.nbt b/pumpkin-world/assets/structures/trail_ruins/buildings/one_room_5.nbt new file mode 100644 index 000000000..236a66b24 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/buildings/one_room_5.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/decor/decor_1.nbt b/pumpkin-world/assets/structures/trail_ruins/decor/decor_1.nbt new file mode 100644 index 000000000..0b7addd23 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/decor/decor_1.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/decor/decor_2.nbt b/pumpkin-world/assets/structures/trail_ruins/decor/decor_2.nbt new file mode 100644 index 000000000..99b1d39ff Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/decor/decor_2.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/decor/decor_3.nbt b/pumpkin-world/assets/structures/trail_ruins/decor/decor_3.nbt new file mode 100644 index 000000000..6b6685b04 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/decor/decor_3.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/decor/decor_4.nbt b/pumpkin-world/assets/structures/trail_ruins/decor/decor_4.nbt new file mode 100644 index 000000000..cff673f68 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/decor/decor_4.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/decor/decor_5.nbt b/pumpkin-world/assets/structures/trail_ruins/decor/decor_5.nbt new file mode 100644 index 000000000..4052b89eb Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/decor/decor_5.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/decor/decor_6.nbt b/pumpkin-world/assets/structures/trail_ruins/decor/decor_6.nbt new file mode 100644 index 000000000..799819b82 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/decor/decor_6.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/decor/decor_7.nbt b/pumpkin-world/assets/structures/trail_ruins/decor/decor_7.nbt new file mode 100644 index 000000000..f6a54e67f Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/decor/decor_7.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/roads/long_road_end.nbt b/pumpkin-world/assets/structures/trail_ruins/roads/long_road_end.nbt new file mode 100644 index 000000000..ec3b28f31 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/roads/long_road_end.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/roads/road_end_1.nbt b/pumpkin-world/assets/structures/trail_ruins/roads/road_end_1.nbt new file mode 100644 index 000000000..ef63adac4 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/roads/road_end_1.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/roads/road_section_1.nbt b/pumpkin-world/assets/structures/trail_ruins/roads/road_section_1.nbt new file mode 100644 index 000000000..0e5172730 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/roads/road_section_1.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/roads/road_section_2.nbt b/pumpkin-world/assets/structures/trail_ruins/roads/road_section_2.nbt new file mode 100644 index 000000000..aee67fd6f Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/roads/road_section_2.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/roads/road_section_3.nbt b/pumpkin-world/assets/structures/trail_ruins/roads/road_section_3.nbt new file mode 100644 index 000000000..d2cba29cd Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/roads/road_section_3.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/roads/road_section_4.nbt b/pumpkin-world/assets/structures/trail_ruins/roads/road_section_4.nbt new file mode 100644 index 000000000..6d4c049a9 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/roads/road_section_4.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/roads/road_spacer_1.nbt b/pumpkin-world/assets/structures/trail_ruins/roads/road_spacer_1.nbt new file mode 100644 index 000000000..3dfd4a606 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/roads/road_spacer_1.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/hall_1.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/hall_1.nbt new file mode 100644 index 000000000..712d05cc2 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/hall_1.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/hall_2.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/hall_2.nbt new file mode 100644 index 000000000..c4b8b933f Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/hall_2.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/hall_3.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/hall_3.nbt new file mode 100644 index 000000000..f868f95d1 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/hall_3.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/hall_4.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/hall_4.nbt new file mode 100644 index 000000000..27d38861b Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/hall_4.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/hall_5.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/hall_5.nbt new file mode 100644 index 000000000..8c4917801 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/hall_5.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/large_hall_1.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/large_hall_1.nbt new file mode 100644 index 000000000..48911d19d Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/large_hall_1.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/large_hall_2.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/large_hall_2.nbt new file mode 100644 index 000000000..a5066349a Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/large_hall_2.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/large_hall_3.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/large_hall_3.nbt new file mode 100644 index 000000000..6cad12e96 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/large_hall_3.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/large_hall_4.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/large_hall_4.nbt new file mode 100644 index 000000000..24d59b915 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/large_hall_4.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/large_hall_5.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/large_hall_5.nbt new file mode 100644 index 000000000..f534d33b0 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/large_hall_5.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/one_room_1.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/one_room_1.nbt new file mode 100644 index 000000000..c8ccfb9b2 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/one_room_1.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/one_room_2.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/one_room_2.nbt new file mode 100644 index 000000000..632a1ce66 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/one_room_2.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/one_room_3.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/one_room_3.nbt new file mode 100644 index 000000000..7f31486c8 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/one_room_3.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/one_room_4.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/one_room_4.nbt new file mode 100644 index 000000000..bb50f6340 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/one_room_4.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/one_room_5.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/one_room_5.nbt new file mode 100644 index 000000000..387ca1942 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/one_room_5.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/platform_1.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/platform_1.nbt new file mode 100644 index 000000000..e58b8bf8f Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/platform_1.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/platform_2.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/platform_2.nbt new file mode 100644 index 000000000..0eac0bd96 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/platform_2.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/platform_3.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/platform_3.nbt new file mode 100644 index 000000000..f64e8e650 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/platform_3.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/platform_4.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/platform_4.nbt new file mode 100644 index 000000000..c90cc34c5 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/platform_4.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/platform_5.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/platform_5.nbt new file mode 100644 index 000000000..4c1414002 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/platform_5.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/stable_1.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/stable_1.nbt new file mode 100644 index 000000000..3d2611bbd Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/stable_1.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/stable_2.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/stable_2.nbt new file mode 100644 index 000000000..3697e59f0 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/stable_2.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/stable_3.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/stable_3.nbt new file mode 100644 index 000000000..7493da1b5 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/stable_3.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/stable_4.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/stable_4.nbt new file mode 100644 index 000000000..e14b184d2 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/stable_4.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/stable_5.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/stable_5.nbt new file mode 100644 index 000000000..978c81947 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/stable_5.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/tower_1.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/tower_1.nbt new file mode 100644 index 000000000..29c8e6ceb Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/tower_1.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/tower_2.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/tower_2.nbt new file mode 100644 index 000000000..f1d01315a Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/tower_2.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/tower_3.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/tower_3.nbt new file mode 100644 index 000000000..9d2fa952a Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/tower_3.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/tower_4.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/tower_4.nbt new file mode 100644 index 000000000..9273e43bb Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/tower_4.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/tower_5.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/tower_5.nbt new file mode 100644 index 000000000..dfd8960fa Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/tower_5.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/tower_top_1.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/tower_top_1.nbt new file mode 100644 index 000000000..53f75cfe4 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/tower_top_1.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/tower_top_2.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/tower_top_2.nbt new file mode 100644 index 000000000..6f33745e4 Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/tower_top_2.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/tower_top_3.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/tower_top_3.nbt new file mode 100644 index 000000000..7ca5279ad Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/tower_top_3.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/tower_top_4.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/tower_top_4.nbt new file mode 100644 index 000000000..fe1675a4a Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/tower_top_4.nbt differ diff --git a/pumpkin-world/assets/structures/trail_ruins/tower/tower_top_5.nbt b/pumpkin-world/assets/structures/trail_ruins/tower/tower_top_5.nbt new file mode 100644 index 000000000..055fc98ae Binary files /dev/null and b/pumpkin-world/assets/structures/trail_ruins/tower/tower_top_5.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/addon/c1_breeze.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/addon/c1_breeze.nbt new file mode 100644 index 000000000..a5ac58510 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/addon/c1_breeze.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/addon/full_corner_column.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/addon/full_corner_column.nbt new file mode 100644 index 000000000..a83d0719b Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/addon/full_corner_column.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/addon/full_stacked_walkway.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/addon/full_stacked_walkway.nbt new file mode 100644 index 000000000..0e375cd9c Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/addon/full_stacked_walkway.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/addon/full_stacked_walkway_2.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/addon/full_stacked_walkway_2.nbt new file mode 100644 index 000000000..1d3874e9d Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/addon/full_stacked_walkway_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/addon/grate_bridge.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/addon/grate_bridge.nbt new file mode 100644 index 000000000..24e1bb2b2 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/addon/grate_bridge.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/addon/hanging_platform.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/addon/hanging_platform.nbt new file mode 100644 index 000000000..1c38b89e5 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/addon/hanging_platform.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/addon/lower_staircase_down.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/addon/lower_staircase_down.nbt new file mode 100644 index 000000000..53bcbd998 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/addon/lower_staircase_down.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/addon/short_grate_platform.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/addon/short_grate_platform.nbt new file mode 100644 index 000000000..e01f324d8 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/addon/short_grate_platform.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/addon/short_platform.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/addon/short_platform.nbt new file mode 100644 index 000000000..82011a29b Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/addon/short_platform.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/addon/walkway_with_bridge_1.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/addon/walkway_with_bridge_1.nbt new file mode 100644 index 000000000..8082f9dc2 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/addon/walkway_with_bridge_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly.nbt new file mode 100644 index 000000000..e32e7e2e2 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_1.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_1.nbt new file mode 100644 index 000000000..71e96cf1d Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_2.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_2.nbt new file mode 100644 index 000000000..b3534485d Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_3.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_3.nbt new file mode 100644 index 000000000..7d2d67672 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_3.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_4.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_4.nbt new file mode 100644 index 000000000..040dcc942 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_4.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_5.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_5.nbt new file mode 100644 index 000000000..c5f30ed62 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_5.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_6.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_6.nbt new file mode 100644 index 000000000..5d14db5ad Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_6.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_7.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_7.nbt new file mode 100644 index 000000000..83010c733 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/cover_7.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/full_column.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/full_column.nbt new file mode 100644 index 000000000..3aace9a9f Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/full_column.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/hanging_1.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/hanging_1.nbt new file mode 100644 index 000000000..6eabd7f51 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/hanging_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/hanging_2.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/hanging_2.nbt new file mode 100644 index 000000000..e99ebeef6 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/hanging_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/hanging_3.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/hanging_3.nbt new file mode 100644 index 000000000..1ada00e22 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/hanging_3.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/hanging_4.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/hanging_4.nbt new file mode 100644 index 000000000..fa9b7fe2f Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/hanging_4.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/hanging_5.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/hanging_5.nbt new file mode 100644 index 000000000..670aaf755 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/hanging_5.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/left_staircase_1.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/left_staircase_1.nbt new file mode 100644 index 000000000..d81dac221 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/left_staircase_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/left_staircase_2.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/left_staircase_2.nbt new file mode 100644 index 000000000..a2aa0b675 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/left_staircase_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/left_staircase_3.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/left_staircase_3.nbt new file mode 100644 index 000000000..b0208cee0 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/left_staircase_3.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/platform_1.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/platform_1.nbt new file mode 100644 index 000000000..e3dc3adfc Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/platform_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/right_staircase_1.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/right_staircase_1.nbt new file mode 100644 index 000000000..137c4357d Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/right_staircase_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/right_staircase_2.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/right_staircase_2.nbt new file mode 100644 index 000000000..7d120ddc5 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/right_staircase_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/right_staircase_3.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/right_staircase_3.nbt new file mode 100644 index 000000000..d2b7a4d8c Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/right_staircase_3.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/spawner_1.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/spawner_1.nbt new file mode 100644 index 000000000..57b12529c Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/assembly/spawner_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/chamber_1.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/chamber_1.nbt new file mode 100644 index 000000000..9ca06bc11 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/chamber_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/chamber_2.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/chamber_2.nbt new file mode 100644 index 000000000..6ff4d3feb Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/chamber_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/chamber_4.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/chamber_4.nbt new file mode 100644 index 000000000..225774bb9 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/chamber_4.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/chamber_8.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/chamber_8.nbt new file mode 100644 index 000000000..ff2e90fbd Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/chamber_8.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/entrance_cap.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/entrance_cap.nbt new file mode 100644 index 000000000..d1fcee2c8 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/entrance_cap.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/eruption.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption.nbt new file mode 100644 index 000000000..0f3b00f46 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/breeze_slice_1.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/breeze_slice_1.nbt new file mode 100644 index 000000000..dfdff119f Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/breeze_slice_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/center_1.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/center_1.nbt new file mode 100644 index 000000000..dedf63d45 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/center_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/quadrant_1.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/quadrant_1.nbt new file mode 100644 index 000000000..173ec15e1 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/quadrant_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/quadrant_2.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/quadrant_2.nbt new file mode 100644 index 000000000..88b20c9ba Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/quadrant_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/quadrant_3.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/quadrant_3.nbt new file mode 100644 index 000000000..658c2f772 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/quadrant_3.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/quadrant_4.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/quadrant_4.nbt new file mode 100644 index 000000000..12c8abf50 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/quadrant_4.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/quadrant_5.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/quadrant_5.nbt new file mode 100644 index 000000000..6def68745 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/quadrant_5.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/slice_1.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/slice_1.nbt new file mode 100644 index 000000000..7a8139021 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/slice_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/slice_2.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/slice_2.nbt new file mode 100644 index 000000000..5caf87715 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/slice_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/slice_3.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/slice_3.nbt new file mode 100644 index 000000000..938315e6f Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/eruption/slice_3.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal.nbt new file mode 100644 index 000000000..9a19e7c88 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/center_1.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/center_1.nbt new file mode 100644 index 000000000..5bba49e10 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/center_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/ominous_slice_1.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/ominous_slice_1.nbt new file mode 100644 index 000000000..f0ce87548 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/ominous_slice_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/quadrant_1.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/quadrant_1.nbt new file mode 100644 index 000000000..3ea1abc46 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/quadrant_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/quadrant_2.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/quadrant_2.nbt new file mode 100644 index 000000000..fe35ee328 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/quadrant_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/quadrant_3.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/quadrant_3.nbt new file mode 100644 index 000000000..954ce27f3 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/quadrant_3.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/slice_1.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/slice_1.nbt new file mode 100644 index 000000000..de67b32c0 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/slice_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/slice_2.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/slice_2.nbt new file mode 100644 index 000000000..0aed3748c Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/slice_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/slice_3.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/slice_3.nbt new file mode 100644 index 000000000..f6a88195c Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/slice_3.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/slice_4.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/slice_4.nbt new file mode 100644 index 000000000..2def0e1f0 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/slice_4.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/slice_5.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/slice_5.nbt new file mode 100644 index 000000000..717f54475 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/pedestal/slice_5.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/slanted.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted.nbt new file mode 100644 index 000000000..359737627 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/center.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/center.nbt new file mode 100644 index 000000000..1e90aa446 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/center.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/hallway_1.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/hallway_1.nbt new file mode 100644 index 000000000..408463bd7 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/hallway_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/hallway_2.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/hallway_2.nbt new file mode 100644 index 000000000..a5e190b1d Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/hallway_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/hallway_3.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/hallway_3.nbt new file mode 100644 index 000000000..f1a93706b Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/hallway_3.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/ominous_upper_arm_1.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/ominous_upper_arm_1.nbt new file mode 100644 index 000000000..1507f5a43 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/ominous_upper_arm_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/quadrant_1.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/quadrant_1.nbt new file mode 100644 index 000000000..c0996bed3 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/quadrant_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/quadrant_2.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/quadrant_2.nbt new file mode 100644 index 000000000..f7a416862 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/quadrant_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/quadrant_3.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/quadrant_3.nbt new file mode 100644 index 000000000..b7c56fc76 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/quadrant_3.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/quadrant_4.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/quadrant_4.nbt new file mode 100644 index 000000000..0b99c822b Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/quadrant_4.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/ramp_1.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/ramp_1.nbt new file mode 100644 index 000000000..efb01d3b1 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/ramp_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/ramp_2.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/ramp_2.nbt new file mode 100644 index 000000000..58a629849 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/ramp_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/ramp_3.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/ramp_3.nbt new file mode 100644 index 000000000..4cb4aee64 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/ramp_3.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/ramp_4.nbt b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/ramp_4.nbt new file mode 100644 index 000000000..9bd95539a Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chamber/slanted/ramp_4.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chests/connectors/supply.nbt b/pumpkin-world/assets/structures/trial_chambers/chests/connectors/supply.nbt new file mode 100644 index 000000000..8a3df6dd2 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chests/connectors/supply.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/chests/supply.nbt b/pumpkin-world/assets/structures/trial_chambers/chests/supply.nbt new file mode 100644 index 000000000..c13821759 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/chests/supply.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/addon/arrow_dispenser.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/arrow_dispenser.nbt new file mode 100644 index 000000000..5a9f6670d Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/arrow_dispenser.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/addon/bridge_lower.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/bridge_lower.nbt new file mode 100644 index 000000000..8e50c4021 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/bridge_lower.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/addon/chandelier_upper.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/chandelier_upper.nbt new file mode 100644 index 000000000..d6ddddf11 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/chandelier_upper.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/addon/decoration_upper.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/decoration_upper.nbt new file mode 100644 index 000000000..1f645f74f Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/decoration_upper.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/addon/display_1.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/display_1.nbt new file mode 100644 index 000000000..c4470b8a3 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/display_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/addon/display_2.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/display_2.nbt new file mode 100644 index 000000000..2f0671701 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/display_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/addon/display_3.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/display_3.nbt new file mode 100644 index 000000000..523e9c809 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/display_3.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/addon/head_upper.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/head_upper.nbt new file mode 100644 index 000000000..4e64391c7 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/head_upper.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/addon/ladder_to_middle.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/ladder_to_middle.nbt new file mode 100644 index 000000000..02122fd4b Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/ladder_to_middle.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/addon/open_walkway.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/open_walkway.nbt new file mode 100644 index 000000000..ed26cc0af Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/open_walkway.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/addon/open_walkway_upper.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/open_walkway_upper.nbt new file mode 100644 index 000000000..0b5518d31 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/open_walkway_upper.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/addon/reward_upper.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/reward_upper.nbt new file mode 100644 index 000000000..3dc057644 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/reward_upper.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/addon/staircase.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/staircase.nbt new file mode 100644 index 000000000..a8d672f7f Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/staircase.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/addon/wall.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/wall.nbt new file mode 100644 index 000000000..0e716926b Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/wall.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/addon/walled_walkway.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/walled_walkway.nbt new file mode 100644 index 000000000..91a7219dc Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/addon/walled_walkway.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/bogged_relief.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/bogged_relief.nbt new file mode 100644 index 000000000..5190155cf Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/bogged_relief.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/breeze_relief.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/breeze_relief.nbt new file mode 100644 index 000000000..9fe72f0dc Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/breeze_relief.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/grand_staircase_1.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/grand_staircase_1.nbt new file mode 100644 index 000000000..d408fffbe Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/grand_staircase_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/grand_staircase_2.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/grand_staircase_2.nbt new file mode 100644 index 000000000..b34ded112 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/grand_staircase_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/grand_staircase_3.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/grand_staircase_3.nbt new file mode 100644 index 000000000..162f1d835 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/grand_staircase_3.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/spider_relief.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/spider_relief.nbt new file mode 100644 index 000000000..fee3588f3 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/spider_relief.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/spiral_relief.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/spiral_relief.nbt new file mode 100644 index 000000000..2ef2d4551 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/atrium/spiral_relief.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/atrium_1.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/atrium_1.nbt new file mode 100644 index 000000000..9618c06a2 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/atrium_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/end_1.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/end_1.nbt new file mode 100644 index 000000000..a4f174256 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/end_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/end_2.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/end_2.nbt new file mode 100644 index 000000000..2f564b329 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/end_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/entrance_1.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/entrance_1.nbt new file mode 100644 index 000000000..d5c04d90b Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/entrance_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/entrance_2.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/entrance_2.nbt new file mode 100644 index 000000000..32434f547 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/entrance_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/entrance_3.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/entrance_3.nbt new file mode 100644 index 000000000..ec776a424 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/entrance_3.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/first_plate.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/first_plate.nbt new file mode 100644 index 000000000..0cb9dc92a Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/first_plate.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/second_plate.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/second_plate.nbt new file mode 100644 index 000000000..f18163870 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/second_plate.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/straight_1.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/straight_1.nbt new file mode 100644 index 000000000..ad0226fc7 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/straight_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/straight_2.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/straight_2.nbt new file mode 100644 index 000000000..b27f32f67 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/straight_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/straight_3.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/straight_3.nbt new file mode 100644 index 000000000..00bb61b9d Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/straight_3.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/straight_4.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/straight_4.nbt new file mode 100644 index 000000000..d7deaf9e3 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/straight_4.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/straight_5.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/straight_5.nbt new file mode 100644 index 000000000..2330a218c Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/straight_5.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/straight_6.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/straight_6.nbt new file mode 100644 index 000000000..fd98b1a05 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/straight_6.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/straight_7.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/straight_7.nbt new file mode 100644 index 000000000..f6b4e64e9 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/straight_7.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/corridor/straight_8.nbt b/pumpkin-world/assets/structures/trial_chambers/corridor/straight_8.nbt new file mode 100644 index 000000000..1a9d71e7c Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/corridor/straight_8.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/barrel.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/barrel.nbt new file mode 100644 index 000000000..aae06c5ef Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/barrel.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/black_bed.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/black_bed.nbt new file mode 100644 index 000000000..925c31094 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/black_bed.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/blue_bed.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/blue_bed.nbt new file mode 100644 index 000000000..2f5cfd683 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/blue_bed.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/brown_bed.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/brown_bed.nbt new file mode 100644 index 000000000..8cf5e82f9 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/brown_bed.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/candle_1.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/candle_1.nbt new file mode 100644 index 000000000..9749c3ef2 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/candle_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/candle_2.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/candle_2.nbt new file mode 100644 index 000000000..22efb091c Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/candle_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/candle_3.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/candle_3.nbt new file mode 100644 index 000000000..f8729ece0 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/candle_3.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/candle_4.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/candle_4.nbt new file mode 100644 index 000000000..23477ae97 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/candle_4.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/cyan_bed.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/cyan_bed.nbt new file mode 100644 index 000000000..bf46b0ea3 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/cyan_bed.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/dead_bush_pot.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/dead_bush_pot.nbt new file mode 100644 index 000000000..befac7a57 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/dead_bush_pot.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/disposal.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/disposal.nbt new file mode 100644 index 000000000..363da565b Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/disposal.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/empty_pot.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/empty_pot.nbt new file mode 100644 index 000000000..b6742e496 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/empty_pot.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/flow_pot.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/flow_pot.nbt new file mode 100644 index 000000000..3c0198ed7 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/flow_pot.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/gray_bed.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/gray_bed.nbt new file mode 100644 index 000000000..3a2784b3a Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/gray_bed.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/green_bed.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/green_bed.nbt new file mode 100644 index 000000000..eb08acb14 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/green_bed.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/guster_pot.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/guster_pot.nbt new file mode 100644 index 000000000..bd2437c35 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/guster_pot.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/light_blue_bed.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/light_blue_bed.nbt new file mode 100644 index 000000000..f9d723b2b Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/light_blue_bed.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/light_gray_bed.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/light_gray_bed.nbt new file mode 100644 index 000000000..e2960c85d Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/light_gray_bed.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/lime_bed.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/lime_bed.nbt new file mode 100644 index 000000000..84d4cdb49 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/lime_bed.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/magenta_bed.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/magenta_bed.nbt new file mode 100644 index 000000000..26abd2e52 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/magenta_bed.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/orange_bed.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/orange_bed.nbt new file mode 100644 index 000000000..e7c1662a2 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/orange_bed.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/pink_bed.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/pink_bed.nbt new file mode 100644 index 000000000..aba7926d0 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/pink_bed.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/purple_bed.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/purple_bed.nbt new file mode 100644 index 000000000..71656705e Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/purple_bed.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/red_bed.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/red_bed.nbt new file mode 100644 index 000000000..4b01d444c Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/red_bed.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/scrape_pot.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/scrape_pot.nbt new file mode 100644 index 000000000..22f930883 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/scrape_pot.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/undecorated_pot.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/undecorated_pot.nbt new file mode 100644 index 000000000..baf2e47bd Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/undecorated_pot.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/white_bed.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/white_bed.nbt new file mode 100644 index 000000000..48d2b07b8 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/white_bed.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/decor/yellow_bed.nbt b/pumpkin-world/assets/structures/trial_chambers/decor/yellow_bed.nbt new file mode 100644 index 000000000..a5f868a6f Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/decor/yellow_bed.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/dispensers/chamber.nbt b/pumpkin-world/assets/structures/trial_chambers/dispensers/chamber.nbt new file mode 100644 index 000000000..a21fea49a Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/dispensers/chamber.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/dispensers/floor_dispenser.nbt b/pumpkin-world/assets/structures/trial_chambers/dispensers/floor_dispenser.nbt new file mode 100644 index 000000000..f3d295a21 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/dispensers/floor_dispenser.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/dispensers/wall_dispenser.nbt b/pumpkin-world/assets/structures/trial_chambers/dispensers/wall_dispenser.nbt new file mode 100644 index 000000000..a54ceb802 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/dispensers/wall_dispenser.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/cache_1.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/cache_1.nbt new file mode 100644 index 000000000..4e083bd38 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/cache_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/corner_staircase.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/corner_staircase.nbt new file mode 100644 index 000000000..38360c5e3 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/corner_staircase.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/corner_staircase_down.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/corner_staircase_down.nbt new file mode 100644 index 000000000..763f6e597 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/corner_staircase_down.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/corridor_connector_1.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/corridor_connector_1.nbt new file mode 100644 index 000000000..803626a9a Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/corridor_connector_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/encounter_1.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/encounter_1.nbt new file mode 100644 index 000000000..17bafe002 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/encounter_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/encounter_2.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/encounter_2.nbt new file mode 100644 index 000000000..febd5714f Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/encounter_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/encounter_3.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/encounter_3.nbt new file mode 100644 index 000000000..722917bf0 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/encounter_3.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/encounter_4.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/encounter_4.nbt new file mode 100644 index 000000000..d8f78450b Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/encounter_4.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/encounter_5.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/encounter_5.nbt new file mode 100644 index 000000000..f55515196 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/encounter_5.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/left_corner.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/left_corner.nbt new file mode 100644 index 000000000..1a2953a59 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/left_corner.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/long_straight_staircase.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/long_straight_staircase.nbt new file mode 100644 index 000000000..f45d99d64 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/long_straight_staircase.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/long_straight_staircase_down.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/long_straight_staircase_down.nbt new file mode 100644 index 000000000..0de2e22b4 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/long_straight_staircase_down.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/lower_hallway_connector.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/lower_hallway_connector.nbt new file mode 100644 index 000000000..25befa90b Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/lower_hallway_connector.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/right_corner.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/right_corner.nbt new file mode 100644 index 000000000..aae7d9f62 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/right_corner.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/rubble.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/rubble.nbt new file mode 100644 index 000000000..603368f23 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/rubble.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/rubble_chamber.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/rubble_chamber.nbt new file mode 100644 index 000000000..67e36c40e Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/rubble_chamber.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/rubble_chamber_thin.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/rubble_chamber_thin.nbt new file mode 100644 index 000000000..c698329b3 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/rubble_chamber_thin.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/rubble_thin.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/rubble_thin.nbt new file mode 100644 index 000000000..c698329b3 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/rubble_thin.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/straight.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/straight.nbt new file mode 100644 index 000000000..c0decf6ae Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/straight.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/straight_staircase.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/straight_staircase.nbt new file mode 100644 index 000000000..4ec841b6b Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/straight_staircase.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/straight_staircase_down.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/straight_staircase_down.nbt new file mode 100644 index 000000000..2b5e09770 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/straight_staircase_down.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/trapped_staircase.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/trapped_staircase.nbt new file mode 100644 index 000000000..93f51127d Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/trapped_staircase.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/hallway/upper_hallway_connector.nbt b/pumpkin-world/assets/structures/trial_chambers/hallway/upper_hallway_connector.nbt new file mode 100644 index 000000000..d80dbd461 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/hallway/upper_hallway_connector.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/intersection/intersection_1.nbt b/pumpkin-world/assets/structures/trial_chambers/intersection/intersection_1.nbt new file mode 100644 index 000000000..3894dab62 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/intersection/intersection_1.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/intersection/intersection_2.nbt b/pumpkin-world/assets/structures/trial_chambers/intersection/intersection_2.nbt new file mode 100644 index 000000000..d8d9ea386 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/intersection/intersection_2.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/intersection/intersection_3.nbt b/pumpkin-world/assets/structures/trial_chambers/intersection/intersection_3.nbt new file mode 100644 index 000000000..90f4b452b Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/intersection/intersection_3.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/reward/ominous_vault.nbt b/pumpkin-world/assets/structures/trial_chambers/reward/ominous_vault.nbt new file mode 100644 index 000000000..e18ca75f7 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/reward/ominous_vault.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/reward/vault.nbt b/pumpkin-world/assets/structures/trial_chambers/reward/vault.nbt new file mode 100644 index 000000000..9a0e933a3 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/reward/vault.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/spawner/breeze/breeze.nbt b/pumpkin-world/assets/structures/trial_chambers/spawner/breeze/breeze.nbt new file mode 100644 index 000000000..6358299da Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/spawner/breeze/breeze.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/spawner/connectors/breeze.nbt b/pumpkin-world/assets/structures/trial_chambers/spawner/connectors/breeze.nbt new file mode 100644 index 000000000..061df19d9 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/spawner/connectors/breeze.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/spawner/connectors/melee.nbt b/pumpkin-world/assets/structures/trial_chambers/spawner/connectors/melee.nbt new file mode 100644 index 000000000..60c2e6e37 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/spawner/connectors/melee.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/spawner/connectors/ranged.nbt b/pumpkin-world/assets/structures/trial_chambers/spawner/connectors/ranged.nbt new file mode 100644 index 000000000..3c6297cbb Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/spawner/connectors/ranged.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/spawner/connectors/slow_ranged.nbt b/pumpkin-world/assets/structures/trial_chambers/spawner/connectors/slow_ranged.nbt new file mode 100644 index 000000000..3e8bb036c Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/spawner/connectors/slow_ranged.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/spawner/connectors/small_melee.nbt b/pumpkin-world/assets/structures/trial_chambers/spawner/connectors/small_melee.nbt new file mode 100644 index 000000000..557c9d87e Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/spawner/connectors/small_melee.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/spawner/melee/husk.nbt b/pumpkin-world/assets/structures/trial_chambers/spawner/melee/husk.nbt new file mode 100644 index 000000000..fdc9f4a11 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/spawner/melee/husk.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/spawner/melee/spider.nbt b/pumpkin-world/assets/structures/trial_chambers/spawner/melee/spider.nbt new file mode 100644 index 000000000..4d477e36c Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/spawner/melee/spider.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/spawner/melee/zombie.nbt b/pumpkin-world/assets/structures/trial_chambers/spawner/melee/zombie.nbt new file mode 100644 index 000000000..70e68b2b1 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/spawner/melee/zombie.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/spawner/ranged/poison_skeleton.nbt b/pumpkin-world/assets/structures/trial_chambers/spawner/ranged/poison_skeleton.nbt new file mode 100644 index 000000000..8d6bc258b Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/spawner/ranged/poison_skeleton.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/spawner/ranged/skeleton.nbt b/pumpkin-world/assets/structures/trial_chambers/spawner/ranged/skeleton.nbt new file mode 100644 index 000000000..cdc311403 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/spawner/ranged/skeleton.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/spawner/ranged/stray.nbt b/pumpkin-world/assets/structures/trial_chambers/spawner/ranged/stray.nbt new file mode 100644 index 000000000..02e0a203c Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/spawner/ranged/stray.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/spawner/slow_ranged/poison_skeleton.nbt b/pumpkin-world/assets/structures/trial_chambers/spawner/slow_ranged/poison_skeleton.nbt new file mode 100644 index 000000000..c8bd33c28 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/spawner/slow_ranged/poison_skeleton.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/spawner/slow_ranged/skeleton.nbt b/pumpkin-world/assets/structures/trial_chambers/spawner/slow_ranged/skeleton.nbt new file mode 100644 index 000000000..ee14633c9 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/spawner/slow_ranged/skeleton.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/spawner/slow_ranged/stray.nbt b/pumpkin-world/assets/structures/trial_chambers/spawner/slow_ranged/stray.nbt new file mode 100644 index 000000000..70c188b56 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/spawner/slow_ranged/stray.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/spawner/small_melee/baby_zombie.nbt b/pumpkin-world/assets/structures/trial_chambers/spawner/small_melee/baby_zombie.nbt new file mode 100644 index 000000000..6918babef Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/spawner/small_melee/baby_zombie.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/spawner/small_melee/cave_spider.nbt b/pumpkin-world/assets/structures/trial_chambers/spawner/small_melee/cave_spider.nbt new file mode 100644 index 000000000..109b7b273 Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/spawner/small_melee/cave_spider.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/spawner/small_melee/silverfish.nbt b/pumpkin-world/assets/structures/trial_chambers/spawner/small_melee/silverfish.nbt new file mode 100644 index 000000000..bfc95e62d Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/spawner/small_melee/silverfish.nbt differ diff --git a/pumpkin-world/assets/structures/trial_chambers/spawner/small_melee/slime.nbt b/pumpkin-world/assets/structures/trial_chambers/spawner/small_melee/slime.nbt new file mode 100644 index 000000000..484e6644f Binary files /dev/null and b/pumpkin-world/assets/structures/trial_chambers/spawner/small_melee/slime.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/big_brick_1.nbt b/pumpkin-world/assets/structures/underwater_ruin/big_brick_1.nbt new file mode 100644 index 000000000..ea58053a1 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/big_brick_1.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/big_brick_2.nbt b/pumpkin-world/assets/structures/underwater_ruin/big_brick_2.nbt new file mode 100644 index 000000000..c0b1dc3e6 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/big_brick_2.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/big_brick_3.nbt b/pumpkin-world/assets/structures/underwater_ruin/big_brick_3.nbt new file mode 100644 index 000000000..bdf55c155 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/big_brick_3.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/big_brick_8.nbt b/pumpkin-world/assets/structures/underwater_ruin/big_brick_8.nbt new file mode 100644 index 000000000..b726172db Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/big_brick_8.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/big_cracked_1.nbt b/pumpkin-world/assets/structures/underwater_ruin/big_cracked_1.nbt new file mode 100644 index 000000000..fc848cb6e Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/big_cracked_1.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/big_cracked_2.nbt b/pumpkin-world/assets/structures/underwater_ruin/big_cracked_2.nbt new file mode 100644 index 000000000..b233a9330 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/big_cracked_2.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/big_cracked_3.nbt b/pumpkin-world/assets/structures/underwater_ruin/big_cracked_3.nbt new file mode 100644 index 000000000..ae1374581 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/big_cracked_3.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/big_cracked_8.nbt b/pumpkin-world/assets/structures/underwater_ruin/big_cracked_8.nbt new file mode 100644 index 000000000..390b92f91 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/big_cracked_8.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/big_mossy_1.nbt b/pumpkin-world/assets/structures/underwater_ruin/big_mossy_1.nbt new file mode 100644 index 000000000..8a5c60299 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/big_mossy_1.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/big_mossy_2.nbt b/pumpkin-world/assets/structures/underwater_ruin/big_mossy_2.nbt new file mode 100644 index 000000000..44569cf89 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/big_mossy_2.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/big_mossy_3.nbt b/pumpkin-world/assets/structures/underwater_ruin/big_mossy_3.nbt new file mode 100644 index 000000000..aa4b867c6 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/big_mossy_3.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/big_mossy_8.nbt b/pumpkin-world/assets/structures/underwater_ruin/big_mossy_8.nbt new file mode 100644 index 000000000..580888dc7 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/big_mossy_8.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/big_warm_4.nbt b/pumpkin-world/assets/structures/underwater_ruin/big_warm_4.nbt new file mode 100644 index 000000000..e5c8c7a55 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/big_warm_4.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/big_warm_5.nbt b/pumpkin-world/assets/structures/underwater_ruin/big_warm_5.nbt new file mode 100644 index 000000000..b524b8161 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/big_warm_5.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/big_warm_6.nbt b/pumpkin-world/assets/structures/underwater_ruin/big_warm_6.nbt new file mode 100644 index 000000000..1c082d43f Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/big_warm_6.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/big_warm_7.nbt b/pumpkin-world/assets/structures/underwater_ruin/big_warm_7.nbt new file mode 100644 index 000000000..8533f8d71 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/big_warm_7.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/brick_1.nbt b/pumpkin-world/assets/structures/underwater_ruin/brick_1.nbt new file mode 100644 index 000000000..118db982b Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/brick_1.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/brick_2.nbt b/pumpkin-world/assets/structures/underwater_ruin/brick_2.nbt new file mode 100644 index 000000000..00633cf8d Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/brick_2.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/brick_3.nbt b/pumpkin-world/assets/structures/underwater_ruin/brick_3.nbt new file mode 100644 index 000000000..b659f3f38 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/brick_3.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/brick_4.nbt b/pumpkin-world/assets/structures/underwater_ruin/brick_4.nbt new file mode 100644 index 000000000..1d9b73592 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/brick_4.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/brick_5.nbt b/pumpkin-world/assets/structures/underwater_ruin/brick_5.nbt new file mode 100644 index 000000000..be09986d7 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/brick_5.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/brick_6.nbt b/pumpkin-world/assets/structures/underwater_ruin/brick_6.nbt new file mode 100644 index 000000000..d1fdcc7e1 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/brick_6.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/brick_7.nbt b/pumpkin-world/assets/structures/underwater_ruin/brick_7.nbt new file mode 100644 index 000000000..1d0026cff Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/brick_7.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/brick_8.nbt b/pumpkin-world/assets/structures/underwater_ruin/brick_8.nbt new file mode 100644 index 000000000..997b9583b Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/brick_8.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/cracked_1.nbt b/pumpkin-world/assets/structures/underwater_ruin/cracked_1.nbt new file mode 100644 index 000000000..7bd95c0af Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/cracked_1.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/cracked_2.nbt b/pumpkin-world/assets/structures/underwater_ruin/cracked_2.nbt new file mode 100644 index 000000000..27944f0bd Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/cracked_2.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/cracked_3.nbt b/pumpkin-world/assets/structures/underwater_ruin/cracked_3.nbt new file mode 100644 index 000000000..07dc0254a Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/cracked_3.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/cracked_4.nbt b/pumpkin-world/assets/structures/underwater_ruin/cracked_4.nbt new file mode 100644 index 000000000..9900ed023 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/cracked_4.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/cracked_5.nbt b/pumpkin-world/assets/structures/underwater_ruin/cracked_5.nbt new file mode 100644 index 000000000..a32ca06b5 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/cracked_5.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/cracked_6.nbt b/pumpkin-world/assets/structures/underwater_ruin/cracked_6.nbt new file mode 100644 index 000000000..51da5e434 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/cracked_6.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/cracked_7.nbt b/pumpkin-world/assets/structures/underwater_ruin/cracked_7.nbt new file mode 100644 index 000000000..8c62f8362 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/cracked_7.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/cracked_8.nbt b/pumpkin-world/assets/structures/underwater_ruin/cracked_8.nbt new file mode 100644 index 000000000..c1eaed5d7 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/cracked_8.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/mossy_1.nbt b/pumpkin-world/assets/structures/underwater_ruin/mossy_1.nbt new file mode 100644 index 000000000..60e9130af Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/mossy_1.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/mossy_2.nbt b/pumpkin-world/assets/structures/underwater_ruin/mossy_2.nbt new file mode 100644 index 000000000..63d4e57d0 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/mossy_2.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/mossy_3.nbt b/pumpkin-world/assets/structures/underwater_ruin/mossy_3.nbt new file mode 100644 index 000000000..5bf985bfb Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/mossy_3.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/mossy_4.nbt b/pumpkin-world/assets/structures/underwater_ruin/mossy_4.nbt new file mode 100644 index 000000000..9e2c8e96c Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/mossy_4.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/mossy_5.nbt b/pumpkin-world/assets/structures/underwater_ruin/mossy_5.nbt new file mode 100644 index 000000000..da5517a58 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/mossy_5.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/mossy_6.nbt b/pumpkin-world/assets/structures/underwater_ruin/mossy_6.nbt new file mode 100644 index 000000000..5ff82b946 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/mossy_6.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/mossy_7.nbt b/pumpkin-world/assets/structures/underwater_ruin/mossy_7.nbt new file mode 100644 index 000000000..1332830f5 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/mossy_7.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/mossy_8.nbt b/pumpkin-world/assets/structures/underwater_ruin/mossy_8.nbt new file mode 100644 index 000000000..1c72d2cad Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/mossy_8.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/warm_1.nbt b/pumpkin-world/assets/structures/underwater_ruin/warm_1.nbt new file mode 100644 index 000000000..418e154ce Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/warm_1.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/warm_2.nbt b/pumpkin-world/assets/structures/underwater_ruin/warm_2.nbt new file mode 100644 index 000000000..d1bf7e7e8 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/warm_2.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/warm_3.nbt b/pumpkin-world/assets/structures/underwater_ruin/warm_3.nbt new file mode 100644 index 000000000..b580edfcd Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/warm_3.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/warm_4.nbt b/pumpkin-world/assets/structures/underwater_ruin/warm_4.nbt new file mode 100644 index 000000000..125fb92ea Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/warm_4.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/warm_5.nbt b/pumpkin-world/assets/structures/underwater_ruin/warm_5.nbt new file mode 100644 index 000000000..d03bfa572 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/warm_5.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/warm_6.nbt b/pumpkin-world/assets/structures/underwater_ruin/warm_6.nbt new file mode 100644 index 000000000..58195314a Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/warm_6.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/warm_7.nbt b/pumpkin-world/assets/structures/underwater_ruin/warm_7.nbt new file mode 100644 index 000000000..e21ff14e9 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/warm_7.nbt differ diff --git a/pumpkin-world/assets/structures/underwater_ruin/warm_8.nbt b/pumpkin-world/assets/structures/underwater_ruin/warm_8.nbt new file mode 100644 index 000000000..bbf69be33 Binary files /dev/null and b/pumpkin-world/assets/structures/underwater_ruin/warm_8.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/animals/cat_black.nbt b/pumpkin-world/assets/structures/village/common/animals/cat_black.nbt new file mode 100644 index 000000000..617cf1092 Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/animals/cat_black.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/animals/cat_british.nbt b/pumpkin-world/assets/structures/village/common/animals/cat_british.nbt new file mode 100644 index 000000000..c14f73e3f Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/animals/cat_british.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/animals/cat_calico.nbt b/pumpkin-world/assets/structures/village/common/animals/cat_calico.nbt new file mode 100644 index 000000000..218ba73d1 Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/animals/cat_calico.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/animals/cat_jellie.nbt b/pumpkin-world/assets/structures/village/common/animals/cat_jellie.nbt new file mode 100644 index 000000000..818881fd8 Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/animals/cat_jellie.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/animals/cat_persian.nbt b/pumpkin-world/assets/structures/village/common/animals/cat_persian.nbt new file mode 100644 index 000000000..d8079dc14 Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/animals/cat_persian.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/animals/cat_ragdoll.nbt b/pumpkin-world/assets/structures/village/common/animals/cat_ragdoll.nbt new file mode 100644 index 000000000..f474bd942 Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/animals/cat_ragdoll.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/animals/cat_red.nbt b/pumpkin-world/assets/structures/village/common/animals/cat_red.nbt new file mode 100644 index 000000000..e5bff6998 Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/animals/cat_red.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/animals/cat_siamese.nbt b/pumpkin-world/assets/structures/village/common/animals/cat_siamese.nbt new file mode 100644 index 000000000..e34919b97 Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/animals/cat_siamese.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/animals/cat_tabby.nbt b/pumpkin-world/assets/structures/village/common/animals/cat_tabby.nbt new file mode 100644 index 000000000..b81f91a13 Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/animals/cat_tabby.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/animals/cat_white.nbt b/pumpkin-world/assets/structures/village/common/animals/cat_white.nbt new file mode 100644 index 000000000..563534adf Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/animals/cat_white.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/animals/cows_1.nbt b/pumpkin-world/assets/structures/village/common/animals/cows_1.nbt new file mode 100644 index 000000000..6a2f4da2b Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/animals/cows_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/animals/horses_1.nbt b/pumpkin-world/assets/structures/village/common/animals/horses_1.nbt new file mode 100644 index 000000000..01cabc369 Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/animals/horses_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/animals/horses_2.nbt b/pumpkin-world/assets/structures/village/common/animals/horses_2.nbt new file mode 100644 index 000000000..ff1f588d5 Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/animals/horses_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/animals/horses_3.nbt b/pumpkin-world/assets/structures/village/common/animals/horses_3.nbt new file mode 100644 index 000000000..760a0f59c Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/animals/horses_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/animals/horses_4.nbt b/pumpkin-world/assets/structures/village/common/animals/horses_4.nbt new file mode 100644 index 000000000..dd64e0232 Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/animals/horses_4.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/animals/horses_5.nbt b/pumpkin-world/assets/structures/village/common/animals/horses_5.nbt new file mode 100644 index 000000000..51aa7e4dc Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/animals/horses_5.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/animals/pigs_1.nbt b/pumpkin-world/assets/structures/village/common/animals/pigs_1.nbt new file mode 100644 index 000000000..d82052a58 Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/animals/pigs_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/animals/sheep_1.nbt b/pumpkin-world/assets/structures/village/common/animals/sheep_1.nbt new file mode 100644 index 000000000..31be536e7 Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/animals/sheep_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/animals/sheep_2.nbt b/pumpkin-world/assets/structures/village/common/animals/sheep_2.nbt new file mode 100644 index 000000000..ef24a225d Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/animals/sheep_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/iron_golem.nbt b/pumpkin-world/assets/structures/village/common/iron_golem.nbt new file mode 100644 index 000000000..456177729 Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/iron_golem.nbt differ diff --git a/pumpkin-world/assets/structures/village/common/well_bottom.nbt b/pumpkin-world/assets/structures/village/common/well_bottom.nbt new file mode 100644 index 000000000..60b01f6a8 Binary files /dev/null and b/pumpkin-world/assets/structures/village/common/well_bottom.nbt differ diff --git a/pumpkin-world/assets/structures/village/decays/grass_11x13.nbt b/pumpkin-world/assets/structures/village/decays/grass_11x13.nbt new file mode 100644 index 000000000..3505f3997 Binary files /dev/null and b/pumpkin-world/assets/structures/village/decays/grass_11x13.nbt differ diff --git a/pumpkin-world/assets/structures/village/decays/grass_16x16.nbt b/pumpkin-world/assets/structures/village/decays/grass_16x16.nbt new file mode 100644 index 000000000..10d080746 Binary files /dev/null and b/pumpkin-world/assets/structures/village/decays/grass_16x16.nbt differ diff --git a/pumpkin-world/assets/structures/village/decays/grass_9x9.nbt b/pumpkin-world/assets/structures/village/decays/grass_9x9.nbt new file mode 100644 index 000000000..ae07c5cf4 Binary files /dev/null and b/pumpkin-world/assets/structures/village/decays/grass_9x9.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/camel_spawn.nbt b/pumpkin-world/assets/structures/village/desert/camel_spawn.nbt new file mode 100644 index 000000000..dbabe99f6 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/camel_spawn.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/desert_lamp_1.nbt b/pumpkin-world/assets/structures/village/desert/desert_lamp_1.nbt new file mode 100644 index 000000000..cb8502dd0 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/desert_lamp_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_animal_pen_1.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_animal_pen_1.nbt new file mode 100644 index 000000000..b3ddc7c91 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_animal_pen_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_animal_pen_2.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_animal_pen_2.nbt new file mode 100644 index 000000000..3e06ce943 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_animal_pen_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_armorer_1.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_armorer_1.nbt new file mode 100644 index 000000000..2bf97bb78 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_armorer_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_butcher_shop_1.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_butcher_shop_1.nbt new file mode 100644 index 000000000..65ba9e117 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_butcher_shop_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_cartographer_house_1.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_cartographer_house_1.nbt new file mode 100644 index 000000000..cdbcb2043 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_cartographer_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_farm_1.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_farm_1.nbt new file mode 100644 index 000000000..f255ce3b7 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_farm_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_farm_2.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_farm_2.nbt new file mode 100644 index 000000000..1464e52b8 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_farm_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_fisher_1.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_fisher_1.nbt new file mode 100644 index 000000000..1d6883728 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_fisher_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_fletcher_house_1.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_fletcher_house_1.nbt new file mode 100644 index 000000000..8e7c3d92b Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_fletcher_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_large_farm_1.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_large_farm_1.nbt new file mode 100644 index 000000000..9df82e0fb Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_large_farm_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_library_1.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_library_1.nbt new file mode 100644 index 000000000..4af11ab2b Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_library_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_mason_1.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_mason_1.nbt new file mode 100644 index 000000000..d22ab2be8 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_mason_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_medium_house_1.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_medium_house_1.nbt new file mode 100644 index 000000000..fd9f58b2d Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_medium_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_medium_house_2.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_medium_house_2.nbt new file mode 100644 index 000000000..00921646a Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_medium_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_shepherd_house_1.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_shepherd_house_1.nbt new file mode 100644 index 000000000..a04c4cf3c Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_shepherd_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_1.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_1.nbt new file mode 100644 index 000000000..341cb54f5 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_2.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_2.nbt new file mode 100644 index 000000000..1d8b2e266 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_3.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_3.nbt new file mode 100644 index 000000000..3ea845423 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_4.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_4.nbt new file mode 100644 index 000000000..2a2860bbc Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_4.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_5.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_5.nbt new file mode 100644 index 000000000..9385de25c Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_5.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_6.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_6.nbt new file mode 100644 index 000000000..981912c15 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_6.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_7.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_7.nbt new file mode 100644 index 000000000..6a95de7b4 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_7.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_8.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_8.nbt new file mode 100644 index 000000000..933a3e1f2 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_small_house_8.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_tannery_1.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_tannery_1.nbt new file mode 100644 index 000000000..965a51e8f Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_tannery_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_temple_1.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_temple_1.nbt new file mode 100644 index 000000000..bf9239c6d Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_temple_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_temple_2.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_temple_2.nbt new file mode 100644 index 000000000..4491aa2ff Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_temple_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_tool_smith_1.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_tool_smith_1.nbt new file mode 100644 index 000000000..4e0f21005 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_tool_smith_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/houses/desert_weaponsmith_1.nbt b/pumpkin-world/assets/structures/village/desert/houses/desert_weaponsmith_1.nbt new file mode 100644 index 000000000..8e3899d94 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/houses/desert_weaponsmith_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/streets/corner_01.nbt b/pumpkin-world/assets/structures/village/desert/streets/corner_01.nbt new file mode 100644 index 000000000..068c57d3d Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/streets/corner_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/streets/corner_02.nbt b/pumpkin-world/assets/structures/village/desert/streets/corner_02.nbt new file mode 100644 index 000000000..cd767c908 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/streets/corner_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/streets/crossroad_01.nbt b/pumpkin-world/assets/structures/village/desert/streets/crossroad_01.nbt new file mode 100644 index 000000000..fe0409d97 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/streets/crossroad_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/streets/crossroad_02.nbt b/pumpkin-world/assets/structures/village/desert/streets/crossroad_02.nbt new file mode 100644 index 000000000..d1f1c3917 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/streets/crossroad_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/streets/crossroad_03.nbt b/pumpkin-world/assets/structures/village/desert/streets/crossroad_03.nbt new file mode 100644 index 000000000..6229030f3 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/streets/crossroad_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/streets/square_01.nbt b/pumpkin-world/assets/structures/village/desert/streets/square_01.nbt new file mode 100644 index 000000000..a2795e443 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/streets/square_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/streets/square_02.nbt b/pumpkin-world/assets/structures/village/desert/streets/square_02.nbt new file mode 100644 index 000000000..0bbb2eeb9 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/streets/square_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/streets/straight_01.nbt b/pumpkin-world/assets/structures/village/desert/streets/straight_01.nbt new file mode 100644 index 000000000..edb95134e Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/streets/straight_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/streets/straight_02.nbt b/pumpkin-world/assets/structures/village/desert/streets/straight_02.nbt new file mode 100644 index 000000000..c29e8ec13 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/streets/straight_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/streets/straight_03.nbt b/pumpkin-world/assets/structures/village/desert/streets/straight_03.nbt new file mode 100644 index 000000000..a15cf056d Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/streets/straight_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/streets/turn_01.nbt b/pumpkin-world/assets/structures/village/desert/streets/turn_01.nbt new file mode 100644 index 000000000..0178608a5 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/streets/turn_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/terminators/terminator_01.nbt b/pumpkin-world/assets/structures/village/desert/terminators/terminator_01.nbt new file mode 100644 index 000000000..51e761741 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/terminators/terminator_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/terminators/terminator_02.nbt b/pumpkin-world/assets/structures/village/desert/terminators/terminator_02.nbt new file mode 100644 index 000000000..e216c21f9 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/terminators/terminator_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/town_centers/desert_meeting_point_1.nbt b/pumpkin-world/assets/structures/village/desert/town_centers/desert_meeting_point_1.nbt new file mode 100644 index 000000000..0b4ef33b3 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/town_centers/desert_meeting_point_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/town_centers/desert_meeting_point_2.nbt b/pumpkin-world/assets/structures/village/desert/town_centers/desert_meeting_point_2.nbt new file mode 100644 index 000000000..fcdeb5fe5 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/town_centers/desert_meeting_point_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/town_centers/desert_meeting_point_3.nbt b/pumpkin-world/assets/structures/village/desert/town_centers/desert_meeting_point_3.nbt new file mode 100644 index 000000000..cd6e7161b Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/town_centers/desert_meeting_point_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/villagers/baby.nbt b/pumpkin-world/assets/structures/village/desert/villagers/baby.nbt new file mode 100644 index 000000000..2d1e07341 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/villagers/baby.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/villagers/nitwit.nbt b/pumpkin-world/assets/structures/village/desert/villagers/nitwit.nbt new file mode 100644 index 000000000..a1f326b49 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/villagers/nitwit.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/villagers/unemployed.nbt b/pumpkin-world/assets/structures/village/desert/villagers/unemployed.nbt new file mode 100644 index 000000000..b75819637 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/villagers/unemployed.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_medium_house_1.nbt b/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_medium_house_1.nbt new file mode 100644 index 000000000..0594add48 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_medium_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_medium_house_2.nbt b/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_medium_house_2.nbt new file mode 100644 index 000000000..89517194a Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_medium_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_1.nbt b/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_1.nbt new file mode 100644 index 000000000..6c8d0fd1b Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_2.nbt b/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_2.nbt new file mode 100644 index 000000000..a7a23bbb7 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_3.nbt b/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_3.nbt new file mode 100644 index 000000000..18b5d8586 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_4.nbt b/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_4.nbt new file mode 100644 index 000000000..1a7aa560b Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_4.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_5.nbt b/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_5.nbt new file mode 100644 index 000000000..ce8a97ec0 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_5.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_6.nbt b/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_6.nbt new file mode 100644 index 000000000..9771b83fb Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_6.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_7.nbt b/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_7.nbt new file mode 100644 index 000000000..bc511e614 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_7.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_8.nbt b/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_8.nbt new file mode 100644 index 000000000..cca091e80 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/houses/desert_small_house_8.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/streets/corner_01.nbt b/pumpkin-world/assets/structures/village/desert/zombie/streets/corner_01.nbt new file mode 100644 index 000000000..5e1602467 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/streets/corner_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/streets/corner_02.nbt b/pumpkin-world/assets/structures/village/desert/zombie/streets/corner_02.nbt new file mode 100644 index 000000000..ce117f963 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/streets/corner_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/streets/crossroad_01.nbt b/pumpkin-world/assets/structures/village/desert/zombie/streets/crossroad_01.nbt new file mode 100644 index 000000000..8a7077a7e Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/streets/crossroad_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/streets/crossroad_02.nbt b/pumpkin-world/assets/structures/village/desert/zombie/streets/crossroad_02.nbt new file mode 100644 index 000000000..03b5a5c4f Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/streets/crossroad_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/streets/crossroad_03.nbt b/pumpkin-world/assets/structures/village/desert/zombie/streets/crossroad_03.nbt new file mode 100644 index 000000000..7438fe3d0 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/streets/crossroad_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/streets/square_01.nbt b/pumpkin-world/assets/structures/village/desert/zombie/streets/square_01.nbt new file mode 100644 index 000000000..425824fad Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/streets/square_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/streets/square_02.nbt b/pumpkin-world/assets/structures/village/desert/zombie/streets/square_02.nbt new file mode 100644 index 000000000..c2ed73662 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/streets/square_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/streets/straight_01.nbt b/pumpkin-world/assets/structures/village/desert/zombie/streets/straight_01.nbt new file mode 100644 index 000000000..564702c80 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/streets/straight_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/streets/straight_02.nbt b/pumpkin-world/assets/structures/village/desert/zombie/streets/straight_02.nbt new file mode 100644 index 000000000..570ed21d1 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/streets/straight_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/streets/straight_03.nbt b/pumpkin-world/assets/structures/village/desert/zombie/streets/straight_03.nbt new file mode 100644 index 000000000..01f564137 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/streets/straight_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/streets/turn_01.nbt b/pumpkin-world/assets/structures/village/desert/zombie/streets/turn_01.nbt new file mode 100644 index 000000000..5b1814f60 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/streets/turn_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/terminators/terminator_02.nbt b/pumpkin-world/assets/structures/village/desert/zombie/terminators/terminator_02.nbt new file mode 100644 index 000000000..d3a695a05 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/terminators/terminator_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/town_centers/desert_meeting_point_1.nbt b/pumpkin-world/assets/structures/village/desert/zombie/town_centers/desert_meeting_point_1.nbt new file mode 100644 index 000000000..101ce68ba Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/town_centers/desert_meeting_point_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/town_centers/desert_meeting_point_2.nbt b/pumpkin-world/assets/structures/village/desert/zombie/town_centers/desert_meeting_point_2.nbt new file mode 100644 index 000000000..50f2c12ec Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/town_centers/desert_meeting_point_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/town_centers/desert_meeting_point_3.nbt b/pumpkin-world/assets/structures/village/desert/zombie/town_centers/desert_meeting_point_3.nbt new file mode 100644 index 000000000..fd7b3e27d Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/town_centers/desert_meeting_point_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/villagers/nitwit.nbt b/pumpkin-world/assets/structures/village/desert/zombie/villagers/nitwit.nbt new file mode 100644 index 000000000..cd5a53942 Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/villagers/nitwit.nbt differ diff --git a/pumpkin-world/assets/structures/village/desert/zombie/villagers/unemployed.nbt b/pumpkin-world/assets/structures/village/desert/zombie/villagers/unemployed.nbt new file mode 100644 index 000000000..1112697af Binary files /dev/null and b/pumpkin-world/assets/structures/village/desert/zombie/villagers/unemployed.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_accessory_1.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_accessory_1.nbt new file mode 100644 index 000000000..8d19bc71e Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_accessory_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_animal_pen_1.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_animal_pen_1.nbt new file mode 100644 index 000000000..f0454944d Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_animal_pen_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_animal_pen_2.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_animal_pen_2.nbt new file mode 100644 index 000000000..bb22e7367 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_animal_pen_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_animal_pen_3.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_animal_pen_3.nbt new file mode 100644 index 000000000..02300949a Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_animal_pen_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_armorer_house_1.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_armorer_house_1.nbt new file mode 100644 index 000000000..c970b205a Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_armorer_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_big_house_1.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_big_house_1.nbt new file mode 100644 index 000000000..e381223e4 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_big_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_butcher_shop_1.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_butcher_shop_1.nbt new file mode 100644 index 000000000..93a2a8235 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_butcher_shop_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_butcher_shop_2.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_butcher_shop_2.nbt new file mode 100644 index 000000000..057f9a360 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_butcher_shop_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_cartographer_1.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_cartographer_1.nbt new file mode 100644 index 000000000..2895810d4 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_cartographer_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_fisher_cottage_1.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_fisher_cottage_1.nbt new file mode 100644 index 000000000..20f682282 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_fisher_cottage_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_fletcher_house_1.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_fletcher_house_1.nbt new file mode 100644 index 000000000..a9a4ce244 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_fletcher_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_large_farm_1.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_large_farm_1.nbt new file mode 100644 index 000000000..b1b6c3ed2 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_large_farm_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_library_1.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_library_1.nbt new file mode 100644 index 000000000..8e8824d4b Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_library_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_library_2.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_library_2.nbt new file mode 100644 index 000000000..08a30bada Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_library_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_masons_house_1.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_masons_house_1.nbt new file mode 100644 index 000000000..ba98a7ec1 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_masons_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_medium_house_1.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_medium_house_1.nbt new file mode 100644 index 000000000..9c13f97be Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_medium_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_medium_house_2.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_medium_house_2.nbt new file mode 100644 index 000000000..b2275f128 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_medium_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_meeting_point_4.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_meeting_point_4.nbt new file mode 100644 index 000000000..021446590 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_meeting_point_4.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_meeting_point_5.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_meeting_point_5.nbt new file mode 100644 index 000000000..67eada1ba Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_meeting_point_5.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_shepherds_house_1.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_shepherds_house_1.nbt new file mode 100644 index 000000000..9d94dc152 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_shepherds_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_small_farm_1.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_small_farm_1.nbt new file mode 100644 index 000000000..0dab5a8b2 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_small_farm_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_1.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_1.nbt new file mode 100644 index 000000000..64d7d822f Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_2.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_2.nbt new file mode 100644 index 000000000..bde690ebc Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_3.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_3.nbt new file mode 100644 index 000000000..048e58970 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_4.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_4.nbt new file mode 100644 index 000000000..040f806f4 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_4.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_5.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_5.nbt new file mode 100644 index 000000000..de84799e7 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_5.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_6.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_6.nbt new file mode 100644 index 000000000..5342d3ea7 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_6.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_7.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_7.nbt new file mode 100644 index 000000000..a8f98f6af Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_7.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_8.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_8.nbt new file mode 100644 index 000000000..c5ca0f94d Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_small_house_8.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_stable_1.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_stable_1.nbt new file mode 100644 index 000000000..a6d5cc682 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_stable_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_stable_2.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_stable_2.nbt new file mode 100644 index 000000000..8f070f95a Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_stable_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_tannery_1.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_tannery_1.nbt new file mode 100644 index 000000000..59a78c6b2 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_tannery_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_temple_3.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_temple_3.nbt new file mode 100644 index 000000000..3142656e1 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_temple_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_temple_4.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_temple_4.nbt new file mode 100644 index 000000000..18a62db7c Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_temple_4.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_tool_smith_1.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_tool_smith_1.nbt new file mode 100644 index 000000000..8e7b42fb7 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_tool_smith_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/houses/plains_weaponsmith_1.nbt b/pumpkin-world/assets/structures/village/plains/houses/plains_weaponsmith_1.nbt new file mode 100644 index 000000000..a9a7ce4c7 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/houses/plains_weaponsmith_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/plains_lamp_1.nbt b/pumpkin-world/assets/structures/village/plains/plains_lamp_1.nbt new file mode 100644 index 000000000..d0a9c1fe0 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/plains_lamp_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/streets/corner_01.nbt b/pumpkin-world/assets/structures/village/plains/streets/corner_01.nbt new file mode 100644 index 000000000..3cac16ac7 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/streets/corner_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/streets/corner_02.nbt b/pumpkin-world/assets/structures/village/plains/streets/corner_02.nbt new file mode 100644 index 000000000..3f2f8a5fe Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/streets/corner_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/streets/corner_03.nbt b/pumpkin-world/assets/structures/village/plains/streets/corner_03.nbt new file mode 100644 index 000000000..b6d795343 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/streets/corner_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/streets/crossroad_01.nbt b/pumpkin-world/assets/structures/village/plains/streets/crossroad_01.nbt new file mode 100644 index 000000000..4ab56fbbf Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/streets/crossroad_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/streets/crossroad_02.nbt b/pumpkin-world/assets/structures/village/plains/streets/crossroad_02.nbt new file mode 100644 index 000000000..598b1c3a2 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/streets/crossroad_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/streets/crossroad_03.nbt b/pumpkin-world/assets/structures/village/plains/streets/crossroad_03.nbt new file mode 100644 index 000000000..cb59a2cb8 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/streets/crossroad_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/streets/crossroad_04.nbt b/pumpkin-world/assets/structures/village/plains/streets/crossroad_04.nbt new file mode 100644 index 000000000..93e91946c Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/streets/crossroad_04.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/streets/crossroad_05.nbt b/pumpkin-world/assets/structures/village/plains/streets/crossroad_05.nbt new file mode 100644 index 000000000..5cfb7913a Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/streets/crossroad_05.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/streets/crossroad_06.nbt b/pumpkin-world/assets/structures/village/plains/streets/crossroad_06.nbt new file mode 100644 index 000000000..6fc238a64 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/streets/crossroad_06.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/streets/straight_01.nbt b/pumpkin-world/assets/structures/village/plains/streets/straight_01.nbt new file mode 100644 index 000000000..3dea9e803 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/streets/straight_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/streets/straight_02.nbt b/pumpkin-world/assets/structures/village/plains/streets/straight_02.nbt new file mode 100644 index 000000000..6416a5534 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/streets/straight_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/streets/straight_03.nbt b/pumpkin-world/assets/structures/village/plains/streets/straight_03.nbt new file mode 100644 index 000000000..5d416771e Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/streets/straight_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/streets/straight_04.nbt b/pumpkin-world/assets/structures/village/plains/streets/straight_04.nbt new file mode 100644 index 000000000..b8432a700 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/streets/straight_04.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/streets/straight_05.nbt b/pumpkin-world/assets/structures/village/plains/streets/straight_05.nbt new file mode 100644 index 000000000..15defb23c Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/streets/straight_05.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/streets/straight_06.nbt b/pumpkin-world/assets/structures/village/plains/streets/straight_06.nbt new file mode 100644 index 000000000..02fdebedf Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/streets/straight_06.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/streets/turn_01.nbt b/pumpkin-world/assets/structures/village/plains/streets/turn_01.nbt new file mode 100644 index 000000000..4bb69e96e Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/streets/turn_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/terminators/terminator_01.nbt b/pumpkin-world/assets/structures/village/plains/terminators/terminator_01.nbt new file mode 100644 index 000000000..4f6e3f6e7 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/terminators/terminator_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/terminators/terminator_02.nbt b/pumpkin-world/assets/structures/village/plains/terminators/terminator_02.nbt new file mode 100644 index 000000000..b2e62338b Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/terminators/terminator_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/terminators/terminator_03.nbt b/pumpkin-world/assets/structures/village/plains/terminators/terminator_03.nbt new file mode 100644 index 000000000..07fc9b99b Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/terminators/terminator_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/terminators/terminator_04.nbt b/pumpkin-world/assets/structures/village/plains/terminators/terminator_04.nbt new file mode 100644 index 000000000..ecd45c435 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/terminators/terminator_04.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/town_centers/plains_fountain_01.nbt b/pumpkin-world/assets/structures/village/plains/town_centers/plains_fountain_01.nbt new file mode 100644 index 000000000..b1a8de486 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/town_centers/plains_fountain_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/town_centers/plains_meeting_point_1.nbt b/pumpkin-world/assets/structures/village/plains/town_centers/plains_meeting_point_1.nbt new file mode 100644 index 000000000..327d04994 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/town_centers/plains_meeting_point_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/town_centers/plains_meeting_point_2.nbt b/pumpkin-world/assets/structures/village/plains/town_centers/plains_meeting_point_2.nbt new file mode 100644 index 000000000..2ef81f8da Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/town_centers/plains_meeting_point_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/town_centers/plains_meeting_point_3.nbt b/pumpkin-world/assets/structures/village/plains/town_centers/plains_meeting_point_3.nbt new file mode 100644 index 000000000..c301e1872 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/town_centers/plains_meeting_point_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/villagers/baby.nbt b/pumpkin-world/assets/structures/village/plains/villagers/baby.nbt new file mode 100644 index 000000000..27ed14826 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/villagers/baby.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/villagers/nitwit.nbt b/pumpkin-world/assets/structures/village/plains/villagers/nitwit.nbt new file mode 100644 index 000000000..9f3f6a86a Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/villagers/nitwit.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/villagers/unemployed.nbt b/pumpkin-world/assets/structures/village/plains/villagers/unemployed.nbt new file mode 100644 index 000000000..7504a2d0f Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/villagers/unemployed.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_animal_pen_3.nbt b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_animal_pen_3.nbt new file mode 100644 index 000000000..65bb08966 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_animal_pen_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_big_house_1.nbt b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_big_house_1.nbt new file mode 100644 index 000000000..ba177a265 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_big_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_butcher_shop_2.nbt b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_butcher_shop_2.nbt new file mode 100644 index 000000000..1477bf565 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_butcher_shop_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_fletcher_house_1.nbt b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_fletcher_house_1.nbt new file mode 100644 index 000000000..c8065a02c Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_fletcher_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_medium_house_1.nbt b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_medium_house_1.nbt new file mode 100644 index 000000000..8712ab5a8 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_medium_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_medium_house_2.nbt b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_medium_house_2.nbt new file mode 100644 index 000000000..7b75675ea Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_medium_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_meeting_point_4.nbt b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_meeting_point_4.nbt new file mode 100644 index 000000000..adf32aa8d Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_meeting_point_4.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_meeting_point_5.nbt b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_meeting_point_5.nbt new file mode 100644 index 000000000..abea0d8e6 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_meeting_point_5.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_shepherds_house_1.nbt b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_shepherds_house_1.nbt new file mode 100644 index 000000000..1780d1c8c Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_shepherds_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_1.nbt b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_1.nbt new file mode 100644 index 000000000..7300cf54d Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_2.nbt b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_2.nbt new file mode 100644 index 000000000..536f4ff1d Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_3.nbt b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_3.nbt new file mode 100644 index 000000000..92a6533d2 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_4.nbt b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_4.nbt new file mode 100644 index 000000000..ad70ddeba Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_4.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_5.nbt b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_5.nbt new file mode 100644 index 000000000..22c70c3b3 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_5.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_6.nbt b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_6.nbt new file mode 100644 index 000000000..e0d6e886e Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_6.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_7.nbt b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_7.nbt new file mode 100644 index 000000000..78ecdda07 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_7.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_8.nbt b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_8.nbt new file mode 100644 index 000000000..3442ab514 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_small_house_8.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_stable_1.nbt b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_stable_1.nbt new file mode 100644 index 000000000..013e185a0 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/houses/plains_stable_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/streets/corner_01.nbt b/pumpkin-world/assets/structures/village/plains/zombie/streets/corner_01.nbt new file mode 100644 index 000000000..7f4192843 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/streets/corner_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/streets/corner_02.nbt b/pumpkin-world/assets/structures/village/plains/zombie/streets/corner_02.nbt new file mode 100644 index 000000000..2e8f4169f Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/streets/corner_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/streets/corner_03.nbt b/pumpkin-world/assets/structures/village/plains/zombie/streets/corner_03.nbt new file mode 100644 index 000000000..ea1833b2d Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/streets/corner_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/streets/crossroad_01.nbt b/pumpkin-world/assets/structures/village/plains/zombie/streets/crossroad_01.nbt new file mode 100644 index 000000000..f462a6053 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/streets/crossroad_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/streets/crossroad_02.nbt b/pumpkin-world/assets/structures/village/plains/zombie/streets/crossroad_02.nbt new file mode 100644 index 000000000..3b88f84a1 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/streets/crossroad_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/streets/crossroad_03.nbt b/pumpkin-world/assets/structures/village/plains/zombie/streets/crossroad_03.nbt new file mode 100644 index 000000000..fd3567140 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/streets/crossroad_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/streets/crossroad_04.nbt b/pumpkin-world/assets/structures/village/plains/zombie/streets/crossroad_04.nbt new file mode 100644 index 000000000..c4374bcb1 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/streets/crossroad_04.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/streets/crossroad_05.nbt b/pumpkin-world/assets/structures/village/plains/zombie/streets/crossroad_05.nbt new file mode 100644 index 000000000..c07b2fbb1 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/streets/crossroad_05.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/streets/crossroad_06.nbt b/pumpkin-world/assets/structures/village/plains/zombie/streets/crossroad_06.nbt new file mode 100644 index 000000000..deacfc856 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/streets/crossroad_06.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/streets/straight_01.nbt b/pumpkin-world/assets/structures/village/plains/zombie/streets/straight_01.nbt new file mode 100644 index 000000000..6d79e5af7 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/streets/straight_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/streets/straight_02.nbt b/pumpkin-world/assets/structures/village/plains/zombie/streets/straight_02.nbt new file mode 100644 index 000000000..1e79b024e Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/streets/straight_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/streets/straight_03.nbt b/pumpkin-world/assets/structures/village/plains/zombie/streets/straight_03.nbt new file mode 100644 index 000000000..1c8f2c18e Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/streets/straight_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/streets/straight_04.nbt b/pumpkin-world/assets/structures/village/plains/zombie/streets/straight_04.nbt new file mode 100644 index 000000000..6918c15be Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/streets/straight_04.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/streets/straight_05.nbt b/pumpkin-world/assets/structures/village/plains/zombie/streets/straight_05.nbt new file mode 100644 index 000000000..d4311deb8 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/streets/straight_05.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/streets/straight_06.nbt b/pumpkin-world/assets/structures/village/plains/zombie/streets/straight_06.nbt new file mode 100644 index 000000000..06bc5328d Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/streets/straight_06.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/streets/turn_01.nbt b/pumpkin-world/assets/structures/village/plains/zombie/streets/turn_01.nbt new file mode 100644 index 000000000..f8863912f Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/streets/turn_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/town_centers/plains_fountain_01.nbt b/pumpkin-world/assets/structures/village/plains/zombie/town_centers/plains_fountain_01.nbt new file mode 100644 index 000000000..4af164bcb Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/town_centers/plains_fountain_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/town_centers/plains_meeting_point_1.nbt b/pumpkin-world/assets/structures/village/plains/zombie/town_centers/plains_meeting_point_1.nbt new file mode 100644 index 000000000..b85d68302 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/town_centers/plains_meeting_point_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/town_centers/plains_meeting_point_2.nbt b/pumpkin-world/assets/structures/village/plains/zombie/town_centers/plains_meeting_point_2.nbt new file mode 100644 index 000000000..b0c82ad5d Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/town_centers/plains_meeting_point_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/town_centers/plains_meeting_point_3.nbt b/pumpkin-world/assets/structures/village/plains/zombie/town_centers/plains_meeting_point_3.nbt new file mode 100644 index 000000000..fdca4ba7a Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/town_centers/plains_meeting_point_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/villagers/nitwit.nbt b/pumpkin-world/assets/structures/village/plains/zombie/villagers/nitwit.nbt new file mode 100644 index 000000000..99b2982e6 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/villagers/nitwit.nbt differ diff --git a/pumpkin-world/assets/structures/village/plains/zombie/villagers/unemployed.nbt b/pumpkin-world/assets/structures/village/plains/zombie/villagers/unemployed.nbt new file mode 100644 index 000000000..b30562866 Binary files /dev/null and b/pumpkin-world/assets/structures/village/plains/zombie/villagers/unemployed.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_animal_pen_1.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_animal_pen_1.nbt new file mode 100644 index 000000000..ab2e108c6 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_animal_pen_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_animal_pen_2.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_animal_pen_2.nbt new file mode 100644 index 000000000..c0304dae2 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_animal_pen_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_animal_pen_3.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_animal_pen_3.nbt new file mode 100644 index 000000000..eae7634ce Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_animal_pen_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_armorer_1.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_armorer_1.nbt new file mode 100644 index 000000000..4fd8c9adb Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_armorer_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_butchers_shop_1.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_butchers_shop_1.nbt new file mode 100644 index 000000000..04f84cbb5 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_butchers_shop_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_butchers_shop_2.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_butchers_shop_2.nbt new file mode 100644 index 000000000..54d8589c5 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_butchers_shop_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_cartographer_1.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_cartographer_1.nbt new file mode 100644 index 000000000..ae4012fcc Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_cartographer_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_fisher_cottage_1.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_fisher_cottage_1.nbt new file mode 100644 index 000000000..8e9bbf45a Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_fisher_cottage_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_fletcher_house_1.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_fletcher_house_1.nbt new file mode 100644 index 000000000..1e2cb4cc5 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_fletcher_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_large_farm_1.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_large_farm_1.nbt new file mode 100644 index 000000000..fe576dbfc Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_large_farm_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_large_farm_2.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_large_farm_2.nbt new file mode 100644 index 000000000..066f20572 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_large_farm_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_library_1.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_library_1.nbt new file mode 100644 index 000000000..a8319979d Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_library_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_mason_1.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_mason_1.nbt new file mode 100644 index 000000000..fbc09b5c3 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_mason_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_medium_house_1.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_medium_house_1.nbt new file mode 100644 index 000000000..599c05f7e Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_medium_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_medium_house_2.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_medium_house_2.nbt new file mode 100644 index 000000000..772715f56 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_medium_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_shepherd_1.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_shepherd_1.nbt new file mode 100644 index 000000000..65ddfd56d Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_shepherd_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_farm.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_farm.nbt new file mode 100644 index 000000000..70c943774 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_farm.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_1.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_1.nbt new file mode 100644 index 000000000..4b3be5042 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_2.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_2.nbt new file mode 100644 index 000000000..84a916805 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_3.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_3.nbt new file mode 100644 index 000000000..36dce5a8e Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_4.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_4.nbt new file mode 100644 index 000000000..9f88ced7f Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_4.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_5.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_5.nbt new file mode 100644 index 000000000..e2954d23a Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_5.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_6.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_6.nbt new file mode 100644 index 000000000..de194c1d0 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_6.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_7.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_7.nbt new file mode 100644 index 000000000..f81c23bc4 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_7.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_8.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_8.nbt new file mode 100644 index 000000000..05700f452 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_small_house_8.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_tannery_1.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_tannery_1.nbt new file mode 100644 index 000000000..d61dcd9b2 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_tannery_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_temple_1.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_temple_1.nbt new file mode 100644 index 000000000..0f0e10dd2 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_temple_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_temple_2.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_temple_2.nbt new file mode 100644 index 000000000..c019ac774 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_temple_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_tool_smith_1.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_tool_smith_1.nbt new file mode 100644 index 000000000..837b1249f Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_tool_smith_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_weaponsmith_1.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_weaponsmith_1.nbt new file mode 100644 index 000000000..e00fa45d9 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_weaponsmith_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/houses/savanna_weaponsmith_2.nbt b/pumpkin-world/assets/structures/village/savanna/houses/savanna_weaponsmith_2.nbt new file mode 100644 index 000000000..b2a481c60 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/houses/savanna_weaponsmith_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/savanna_lamp_post_01.nbt b/pumpkin-world/assets/structures/village/savanna/savanna_lamp_post_01.nbt new file mode 100644 index 000000000..621d8bf20 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/savanna_lamp_post_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/streets/corner_01.nbt b/pumpkin-world/assets/structures/village/savanna/streets/corner_01.nbt new file mode 100644 index 000000000..90e056ba1 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/streets/corner_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/streets/corner_03.nbt b/pumpkin-world/assets/structures/village/savanna/streets/corner_03.nbt new file mode 100644 index 000000000..ba4f37887 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/streets/corner_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/streets/crossroad_02.nbt b/pumpkin-world/assets/structures/village/savanna/streets/crossroad_02.nbt new file mode 100644 index 000000000..58d17ff32 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/streets/crossroad_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/streets/crossroad_03.nbt b/pumpkin-world/assets/structures/village/savanna/streets/crossroad_03.nbt new file mode 100644 index 000000000..4f66e7ba3 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/streets/crossroad_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/streets/crossroad_04.nbt b/pumpkin-world/assets/structures/village/savanna/streets/crossroad_04.nbt new file mode 100644 index 000000000..6236111fa Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/streets/crossroad_04.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/streets/crossroad_05.nbt b/pumpkin-world/assets/structures/village/savanna/streets/crossroad_05.nbt new file mode 100644 index 000000000..5a97d9a63 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/streets/crossroad_05.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/streets/crossroad_06.nbt b/pumpkin-world/assets/structures/village/savanna/streets/crossroad_06.nbt new file mode 100644 index 000000000..f774ce053 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/streets/crossroad_06.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/streets/crossroad_07.nbt b/pumpkin-world/assets/structures/village/savanna/streets/crossroad_07.nbt new file mode 100644 index 000000000..36b7af1e1 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/streets/crossroad_07.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/streets/split_01.nbt b/pumpkin-world/assets/structures/village/savanna/streets/split_01.nbt new file mode 100644 index 000000000..a41b0ef9b Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/streets/split_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/streets/split_02.nbt b/pumpkin-world/assets/structures/village/savanna/streets/split_02.nbt new file mode 100644 index 000000000..915658b85 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/streets/split_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/streets/straight_02.nbt b/pumpkin-world/assets/structures/village/savanna/streets/straight_02.nbt new file mode 100644 index 000000000..5be6ef352 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/streets/straight_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/streets/straight_04.nbt b/pumpkin-world/assets/structures/village/savanna/streets/straight_04.nbt new file mode 100644 index 000000000..bbafa67fb Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/streets/straight_04.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/streets/straight_05.nbt b/pumpkin-world/assets/structures/village/savanna/streets/straight_05.nbt new file mode 100644 index 000000000..7cc880a25 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/streets/straight_05.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/streets/straight_06.nbt b/pumpkin-world/assets/structures/village/savanna/streets/straight_06.nbt new file mode 100644 index 000000000..3aa6d5ece Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/streets/straight_06.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/streets/straight_08.nbt b/pumpkin-world/assets/structures/village/savanna/streets/straight_08.nbt new file mode 100644 index 000000000..fe9f9d634 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/streets/straight_08.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/streets/straight_09.nbt b/pumpkin-world/assets/structures/village/savanna/streets/straight_09.nbt new file mode 100644 index 000000000..fe04bc57d Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/streets/straight_09.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/streets/straight_10.nbt b/pumpkin-world/assets/structures/village/savanna/streets/straight_10.nbt new file mode 100644 index 000000000..92d2171bf Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/streets/straight_10.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/streets/straight_11.nbt b/pumpkin-world/assets/structures/village/savanna/streets/straight_11.nbt new file mode 100644 index 000000000..97e073faf Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/streets/straight_11.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/streets/turn_01.nbt b/pumpkin-world/assets/structures/village/savanna/streets/turn_01.nbt new file mode 100644 index 000000000..de937a6c6 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/streets/turn_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/terminators/terminator_05.nbt b/pumpkin-world/assets/structures/village/savanna/terminators/terminator_05.nbt new file mode 100644 index 000000000..d2bc46679 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/terminators/terminator_05.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/town_centers/savanna_meeting_point_1.nbt b/pumpkin-world/assets/structures/village/savanna/town_centers/savanna_meeting_point_1.nbt new file mode 100644 index 000000000..60baedb38 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/town_centers/savanna_meeting_point_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/town_centers/savanna_meeting_point_2.nbt b/pumpkin-world/assets/structures/village/savanna/town_centers/savanna_meeting_point_2.nbt new file mode 100644 index 000000000..f35d27bd1 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/town_centers/savanna_meeting_point_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/town_centers/savanna_meeting_point_3.nbt b/pumpkin-world/assets/structures/village/savanna/town_centers/savanna_meeting_point_3.nbt new file mode 100644 index 000000000..e8633ae1a Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/town_centers/savanna_meeting_point_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/town_centers/savanna_meeting_point_4.nbt b/pumpkin-world/assets/structures/village/savanna/town_centers/savanna_meeting_point_4.nbt new file mode 100644 index 000000000..b98f1ef12 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/town_centers/savanna_meeting_point_4.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/villagers/baby.nbt b/pumpkin-world/assets/structures/village/savanna/villagers/baby.nbt new file mode 100644 index 000000000..4445c8b8e Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/villagers/baby.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/villagers/nitwit.nbt b/pumpkin-world/assets/structures/village/savanna/villagers/nitwit.nbt new file mode 100644 index 000000000..246d88124 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/villagers/nitwit.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/villagers/unemployed.nbt b/pumpkin-world/assets/structures/village/savanna/villagers/unemployed.nbt new file mode 100644 index 000000000..8171b6a6e Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/villagers/unemployed.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_animal_pen_2.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_animal_pen_2.nbt new file mode 100644 index 000000000..e22496f3a Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_animal_pen_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_animal_pen_3.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_animal_pen_3.nbt new file mode 100644 index 000000000..0b3ed022a Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_animal_pen_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_large_farm_2.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_large_farm_2.nbt new file mode 100644 index 000000000..9b47d8b57 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_large_farm_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_medium_house_1.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_medium_house_1.nbt new file mode 100644 index 000000000..5b7014174 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_medium_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_medium_house_2.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_medium_house_2.nbt new file mode 100644 index 000000000..63d0c05fd Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_medium_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_1.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_1.nbt new file mode 100644 index 000000000..1275309b4 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_2.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_2.nbt new file mode 100644 index 000000000..0c5e7697c Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_3.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_3.nbt new file mode 100644 index 000000000..133b06de2 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_4.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_4.nbt new file mode 100644 index 000000000..60b77374f Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_4.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_5.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_5.nbt new file mode 100644 index 000000000..264a0a51f Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_5.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_6.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_6.nbt new file mode 100644 index 000000000..b14016298 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_6.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_7.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_7.nbt new file mode 100644 index 000000000..43ea58a8f Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_7.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_8.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_8.nbt new file mode 100644 index 000000000..ccb5de4d6 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/houses/savanna_small_house_8.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/streets/corner_01.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/streets/corner_01.nbt new file mode 100644 index 000000000..eee8f2d61 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/streets/corner_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/streets/corner_03.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/streets/corner_03.nbt new file mode 100644 index 000000000..567cc71de Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/streets/corner_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/streets/crossroad_02.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/streets/crossroad_02.nbt new file mode 100644 index 000000000..c891df601 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/streets/crossroad_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/streets/crossroad_03.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/streets/crossroad_03.nbt new file mode 100644 index 000000000..d90001d29 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/streets/crossroad_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/streets/crossroad_04.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/streets/crossroad_04.nbt new file mode 100644 index 000000000..8b967add8 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/streets/crossroad_04.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/streets/crossroad_05.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/streets/crossroad_05.nbt new file mode 100644 index 000000000..ae36d373d Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/streets/crossroad_05.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/streets/crossroad_06.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/streets/crossroad_06.nbt new file mode 100644 index 000000000..32a565f5c Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/streets/crossroad_06.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/streets/crossroad_07.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/streets/crossroad_07.nbt new file mode 100644 index 000000000..3a008848c Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/streets/crossroad_07.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/streets/split_01.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/streets/split_01.nbt new file mode 100644 index 000000000..f433bad92 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/streets/split_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/streets/split_02.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/streets/split_02.nbt new file mode 100644 index 000000000..b70d637d3 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/streets/split_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_02.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_02.nbt new file mode 100644 index 000000000..7f8ac7a9f Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_04.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_04.nbt new file mode 100644 index 000000000..3ed58c129 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_04.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_05.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_05.nbt new file mode 100644 index 000000000..977bdefe5 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_05.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_06.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_06.nbt new file mode 100644 index 000000000..d4791a7d9 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_06.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_08.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_08.nbt new file mode 100644 index 000000000..95ac23ac3 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_08.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_09.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_09.nbt new file mode 100644 index 000000000..36e4bba39 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_09.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_10.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_10.nbt new file mode 100644 index 000000000..af5dfc812 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_10.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_11.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_11.nbt new file mode 100644 index 000000000..9e087b88a Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/streets/straight_11.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/streets/turn_01.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/streets/turn_01.nbt new file mode 100644 index 000000000..a260b3ab4 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/streets/turn_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/terminators/terminator_05.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/terminators/terminator_05.nbt new file mode 100644 index 000000000..dbb659bb8 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/terminators/terminator_05.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/town_centers/savanna_meeting_point_1.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/town_centers/savanna_meeting_point_1.nbt new file mode 100644 index 000000000..1da94dc66 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/town_centers/savanna_meeting_point_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/town_centers/savanna_meeting_point_2.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/town_centers/savanna_meeting_point_2.nbt new file mode 100644 index 000000000..606456a43 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/town_centers/savanna_meeting_point_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/town_centers/savanna_meeting_point_3.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/town_centers/savanna_meeting_point_3.nbt new file mode 100644 index 000000000..2e1addb6c Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/town_centers/savanna_meeting_point_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/town_centers/savanna_meeting_point_4.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/town_centers/savanna_meeting_point_4.nbt new file mode 100644 index 000000000..bdca4e05e Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/town_centers/savanna_meeting_point_4.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/villagers/nitwit.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/villagers/nitwit.nbt new file mode 100644 index 000000000..5114b33b0 Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/villagers/nitwit.nbt differ diff --git a/pumpkin-world/assets/structures/village/savanna/zombie/villagers/unemployed.nbt b/pumpkin-world/assets/structures/village/savanna/zombie/villagers/unemployed.nbt new file mode 100644 index 000000000..3347f1c8c Binary files /dev/null and b/pumpkin-world/assets/structures/village/savanna/zombie/villagers/unemployed.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_animal_pen_1.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_animal_pen_1.nbt new file mode 100644 index 000000000..912afe24a Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_animal_pen_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_animal_pen_2.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_animal_pen_2.nbt new file mode 100644 index 000000000..c7745182c Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_animal_pen_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_armorer_house_1.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_armorer_house_1.nbt new file mode 100644 index 000000000..316636986 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_armorer_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_armorer_house_2.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_armorer_house_2.nbt new file mode 100644 index 000000000..8728ebd42 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_armorer_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_butchers_shop_1.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_butchers_shop_1.nbt new file mode 100644 index 000000000..93b8c3de5 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_butchers_shop_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_butchers_shop_2.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_butchers_shop_2.nbt new file mode 100644 index 000000000..8b4da356d Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_butchers_shop_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_cartographer_house_1.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_cartographer_house_1.nbt new file mode 100644 index 000000000..d428082fd Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_cartographer_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_farm_1.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_farm_1.nbt new file mode 100644 index 000000000..01b7711ca Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_farm_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_farm_2.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_farm_2.nbt new file mode 100644 index 000000000..c8569423c Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_farm_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_fisher_cottage.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_fisher_cottage.nbt new file mode 100644 index 000000000..6855c8268 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_fisher_cottage.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_fletcher_house_1.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_fletcher_house_1.nbt new file mode 100644 index 000000000..ec47a2045 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_fletcher_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_library_1.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_library_1.nbt new file mode 100644 index 000000000..bf243ea1e Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_library_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_masons_house_1.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_masons_house_1.nbt new file mode 100644 index 000000000..0f2d62f39 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_masons_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_masons_house_2.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_masons_house_2.nbt new file mode 100644 index 000000000..9df718925 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_masons_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_medium_house_1.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_medium_house_1.nbt new file mode 100644 index 000000000..7fd3ac479 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_medium_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_medium_house_2.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_medium_house_2.nbt new file mode 100644 index 000000000..ccfe4b66c Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_medium_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_medium_house_3.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_medium_house_3.nbt new file mode 100644 index 000000000..374e2eb9f Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_medium_house_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_shepherds_house_1.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_shepherds_house_1.nbt new file mode 100644 index 000000000..b9daadf97 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_shepherds_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_1.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_1.nbt new file mode 100644 index 000000000..abcf3a86f Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_2.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_2.nbt new file mode 100644 index 000000000..fc1d52c13 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_3.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_3.nbt new file mode 100644 index 000000000..d3549da1e Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_4.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_4.nbt new file mode 100644 index 000000000..cbe7e4006 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_4.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_5.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_5.nbt new file mode 100644 index 000000000..50c57d8a8 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_5.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_6.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_6.nbt new file mode 100644 index 000000000..45ee91e8b Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_6.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_7.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_7.nbt new file mode 100644 index 000000000..e0c903065 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_7.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_8.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_8.nbt new file mode 100644 index 000000000..62972757a Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_small_house_8.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_tannery_1.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_tannery_1.nbt new file mode 100644 index 000000000..3e0dce5c5 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_tannery_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_temple_1.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_temple_1.nbt new file mode 100644 index 000000000..ddcdaaf68 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_temple_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_tool_smith_1.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_tool_smith_1.nbt new file mode 100644 index 000000000..6782de0c9 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_tool_smith_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/houses/snowy_weapon_smith_1.nbt b/pumpkin-world/assets/structures/village/snowy/houses/snowy_weapon_smith_1.nbt new file mode 100644 index 000000000..48b661fcf Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/houses/snowy_weapon_smith_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/snowy_lamp_post_01.nbt b/pumpkin-world/assets/structures/village/snowy/snowy_lamp_post_01.nbt new file mode 100644 index 000000000..f61eb6728 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/snowy_lamp_post_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/snowy_lamp_post_02.nbt b/pumpkin-world/assets/structures/village/snowy/snowy_lamp_post_02.nbt new file mode 100644 index 000000000..ed731dbe4 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/snowy_lamp_post_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/snowy_lamp_post_03.nbt b/pumpkin-world/assets/structures/village/snowy/snowy_lamp_post_03.nbt new file mode 100644 index 000000000..adef9dc82 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/snowy_lamp_post_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/streets/corner_01.nbt b/pumpkin-world/assets/structures/village/snowy/streets/corner_01.nbt new file mode 100644 index 000000000..cbea16987 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/streets/corner_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/streets/corner_02.nbt b/pumpkin-world/assets/structures/village/snowy/streets/corner_02.nbt new file mode 100644 index 000000000..de612aa0c Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/streets/corner_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/streets/corner_03.nbt b/pumpkin-world/assets/structures/village/snowy/streets/corner_03.nbt new file mode 100644 index 000000000..0bef8ec01 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/streets/corner_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/streets/crossroad_01.nbt b/pumpkin-world/assets/structures/village/snowy/streets/crossroad_01.nbt new file mode 100644 index 000000000..f949ef397 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/streets/crossroad_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/streets/crossroad_02.nbt b/pumpkin-world/assets/structures/village/snowy/streets/crossroad_02.nbt new file mode 100644 index 000000000..528672225 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/streets/crossroad_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/streets/crossroad_03.nbt b/pumpkin-world/assets/structures/village/snowy/streets/crossroad_03.nbt new file mode 100644 index 000000000..11632c4ef Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/streets/crossroad_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/streets/crossroad_04.nbt b/pumpkin-world/assets/structures/village/snowy/streets/crossroad_04.nbt new file mode 100644 index 000000000..06227c0af Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/streets/crossroad_04.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/streets/crossroad_05.nbt b/pumpkin-world/assets/structures/village/snowy/streets/crossroad_05.nbt new file mode 100644 index 000000000..f5dea1c57 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/streets/crossroad_05.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/streets/crossroad_06.nbt b/pumpkin-world/assets/structures/village/snowy/streets/crossroad_06.nbt new file mode 100644 index 000000000..80390e0ec Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/streets/crossroad_06.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/streets/square_01.nbt b/pumpkin-world/assets/structures/village/snowy/streets/square_01.nbt new file mode 100644 index 000000000..a8f9aad91 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/streets/square_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/streets/straight_01.nbt b/pumpkin-world/assets/structures/village/snowy/streets/straight_01.nbt new file mode 100644 index 000000000..0bd4b7f03 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/streets/straight_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/streets/straight_02.nbt b/pumpkin-world/assets/structures/village/snowy/streets/straight_02.nbt new file mode 100644 index 000000000..813000c46 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/streets/straight_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/streets/straight_03.nbt b/pumpkin-world/assets/structures/village/snowy/streets/straight_03.nbt new file mode 100644 index 000000000..97edf6c6f Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/streets/straight_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/streets/straight_04.nbt b/pumpkin-world/assets/structures/village/snowy/streets/straight_04.nbt new file mode 100644 index 000000000..71dd3b15f Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/streets/straight_04.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/streets/straight_06.nbt b/pumpkin-world/assets/structures/village/snowy/streets/straight_06.nbt new file mode 100644 index 000000000..6e26e00da Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/streets/straight_06.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/streets/straight_08.nbt b/pumpkin-world/assets/structures/village/snowy/streets/straight_08.nbt new file mode 100644 index 000000000..829f6881c Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/streets/straight_08.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/streets/turn_01.nbt b/pumpkin-world/assets/structures/village/snowy/streets/turn_01.nbt new file mode 100644 index 000000000..57f272f9b Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/streets/turn_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/town_centers/snowy_meeting_point_1.nbt b/pumpkin-world/assets/structures/village/snowy/town_centers/snowy_meeting_point_1.nbt new file mode 100644 index 000000000..ea2f52e17 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/town_centers/snowy_meeting_point_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/town_centers/snowy_meeting_point_2.nbt b/pumpkin-world/assets/structures/village/snowy/town_centers/snowy_meeting_point_2.nbt new file mode 100644 index 000000000..b5fd12f09 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/town_centers/snowy_meeting_point_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/town_centers/snowy_meeting_point_3.nbt b/pumpkin-world/assets/structures/village/snowy/town_centers/snowy_meeting_point_3.nbt new file mode 100644 index 000000000..2083b5f06 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/town_centers/snowy_meeting_point_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/villagers/baby.nbt b/pumpkin-world/assets/structures/village/snowy/villagers/baby.nbt new file mode 100644 index 000000000..d46cccf29 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/villagers/baby.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/villagers/nitwit.nbt b/pumpkin-world/assets/structures/village/snowy/villagers/nitwit.nbt new file mode 100644 index 000000000..bb06031e0 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/villagers/nitwit.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/villagers/unemployed.nbt b/pumpkin-world/assets/structures/village/snowy/villagers/unemployed.nbt new file mode 100644 index 000000000..14c69a8d6 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/villagers/unemployed.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_medium_house_1.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_medium_house_1.nbt new file mode 100644 index 000000000..5a26174e7 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_medium_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_medium_house_2.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_medium_house_2.nbt new file mode 100644 index 000000000..8013efe87 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_medium_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_medium_house_3.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_medium_house_3.nbt new file mode 100644 index 000000000..1df40e6f9 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_medium_house_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_1.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_1.nbt new file mode 100644 index 000000000..70d477c4d Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_2.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_2.nbt new file mode 100644 index 000000000..730dd74b1 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_3.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_3.nbt new file mode 100644 index 000000000..e9bc5126b Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_4.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_4.nbt new file mode 100644 index 000000000..b13fd936f Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_4.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_5.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_5.nbt new file mode 100644 index 000000000..df9817af1 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_5.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_6.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_6.nbt new file mode 100644 index 000000000..315eaab42 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_6.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_7.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_7.nbt new file mode 100644 index 000000000..5a1bbb706 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_7.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_8.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_8.nbt new file mode 100644 index 000000000..c768c9856 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/houses/snowy_small_house_8.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/streets/corner_01.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/streets/corner_01.nbt new file mode 100644 index 000000000..0790e6d8a Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/streets/corner_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/streets/corner_02.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/streets/corner_02.nbt new file mode 100644 index 000000000..601724ae6 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/streets/corner_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/streets/corner_03.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/streets/corner_03.nbt new file mode 100644 index 000000000..50397e8d1 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/streets/corner_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/streets/crossroad_01.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/streets/crossroad_01.nbt new file mode 100644 index 000000000..d776d6a5e Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/streets/crossroad_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/streets/crossroad_02.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/streets/crossroad_02.nbt new file mode 100644 index 000000000..e3533ff8f Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/streets/crossroad_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/streets/crossroad_03.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/streets/crossroad_03.nbt new file mode 100644 index 000000000..c71142922 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/streets/crossroad_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/streets/crossroad_04.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/streets/crossroad_04.nbt new file mode 100644 index 000000000..b650e89a6 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/streets/crossroad_04.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/streets/crossroad_05.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/streets/crossroad_05.nbt new file mode 100644 index 000000000..2614264a3 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/streets/crossroad_05.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/streets/crossroad_06.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/streets/crossroad_06.nbt new file mode 100644 index 000000000..18f1993aa Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/streets/crossroad_06.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/streets/square_01.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/streets/square_01.nbt new file mode 100644 index 000000000..23ca6b3c5 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/streets/square_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/streets/straight_01.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/streets/straight_01.nbt new file mode 100644 index 000000000..c686d975c Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/streets/straight_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/streets/straight_02.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/streets/straight_02.nbt new file mode 100644 index 000000000..52abe81dd Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/streets/straight_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/streets/straight_03.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/streets/straight_03.nbt new file mode 100644 index 000000000..631ac2c2a Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/streets/straight_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/streets/straight_04.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/streets/straight_04.nbt new file mode 100644 index 000000000..6d66f5d81 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/streets/straight_04.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/streets/straight_06.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/streets/straight_06.nbt new file mode 100644 index 000000000..1d23fe46d Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/streets/straight_06.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/streets/straight_08.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/streets/straight_08.nbt new file mode 100644 index 000000000..d611f9e46 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/streets/straight_08.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/streets/turn_01.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/streets/turn_01.nbt new file mode 100644 index 000000000..b1eb0dc6b Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/streets/turn_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/town_centers/snowy_meeting_point_1.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/town_centers/snowy_meeting_point_1.nbt new file mode 100644 index 000000000..78bcb338c Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/town_centers/snowy_meeting_point_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/town_centers/snowy_meeting_point_2.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/town_centers/snowy_meeting_point_2.nbt new file mode 100644 index 000000000..89e7aa447 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/town_centers/snowy_meeting_point_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/town_centers/snowy_meeting_point_3.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/town_centers/snowy_meeting_point_3.nbt new file mode 100644 index 000000000..9f9cf29c3 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/town_centers/snowy_meeting_point_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/villagers/nitwit.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/villagers/nitwit.nbt new file mode 100644 index 000000000..87725a945 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/villagers/nitwit.nbt differ diff --git a/pumpkin-world/assets/structures/village/snowy/zombie/villagers/unemployed.nbt b/pumpkin-world/assets/structures/village/snowy/zombie/villagers/unemployed.nbt new file mode 100644 index 000000000..6741939b9 Binary files /dev/null and b/pumpkin-world/assets/structures/village/snowy/zombie/villagers/unemployed.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_animal_pen_1.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_animal_pen_1.nbt new file mode 100644 index 000000000..9b50d4344 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_animal_pen_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_armorer_2.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_armorer_2.nbt new file mode 100644 index 000000000..9de49e587 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_armorer_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_armorer_house_1.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_armorer_house_1.nbt new file mode 100644 index 000000000..efe352961 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_armorer_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_butcher_shop_1.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_butcher_shop_1.nbt new file mode 100644 index 000000000..d4ed041f2 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_butcher_shop_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_cartographer_house_1.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_cartographer_house_1.nbt new file mode 100644 index 000000000..662d08f97 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_cartographer_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_fisher_cottage_1.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_fisher_cottage_1.nbt new file mode 100644 index 000000000..cba2427f1 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_fisher_cottage_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_fletcher_house_1.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_fletcher_house_1.nbt new file mode 100644 index 000000000..386e3b0bb Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_fletcher_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_large_farm_1.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_large_farm_1.nbt new file mode 100644 index 000000000..5e0e76b72 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_large_farm_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_large_farm_2.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_large_farm_2.nbt new file mode 100644 index 000000000..c507b0c34 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_large_farm_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_library_1.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_library_1.nbt new file mode 100644 index 000000000..a8c89461b Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_library_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_masons_house_1.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_masons_house_1.nbt new file mode 100644 index 000000000..53cab697f Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_masons_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_medium_house_1.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_medium_house_1.nbt new file mode 100644 index 000000000..c6fab7aa8 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_medium_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_medium_house_2.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_medium_house_2.nbt new file mode 100644 index 000000000..96226e761 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_medium_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_medium_house_3.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_medium_house_3.nbt new file mode 100644 index 000000000..27069f3f5 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_medium_house_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_medium_house_4.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_medium_house_4.nbt new file mode 100644 index 000000000..179cdb79c Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_medium_house_4.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_shepherds_house_1.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_shepherds_house_1.nbt new file mode 100644 index 000000000..5a7cc6181 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_shepherds_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_small_farm_1.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_small_farm_1.nbt new file mode 100644 index 000000000..566b3b9a2 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_small_farm_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_small_house_1.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_small_house_1.nbt new file mode 100644 index 000000000..013dc1203 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_small_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_small_house_2.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_small_house_2.nbt new file mode 100644 index 000000000..306444c80 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_small_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_small_house_3.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_small_house_3.nbt new file mode 100644 index 000000000..e35cb0d52 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_small_house_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_small_house_4.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_small_house_4.nbt new file mode 100644 index 000000000..2480e5519 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_small_house_4.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_small_house_5.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_small_house_5.nbt new file mode 100644 index 000000000..eda96dd3c Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_small_house_5.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_tannery_1.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_tannery_1.nbt new file mode 100644 index 000000000..85f60c0a5 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_tannery_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_temple_1.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_temple_1.nbt new file mode 100644 index 000000000..6fb8a0b07 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_temple_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_tool_smith_1.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_tool_smith_1.nbt new file mode 100644 index 000000000..27986442f Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_tool_smith_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_weaponsmith_1.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_weaponsmith_1.nbt new file mode 100644 index 000000000..d4528fe2c Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_weaponsmith_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/houses/taiga_weaponsmith_2.nbt b/pumpkin-world/assets/structures/village/taiga/houses/taiga_weaponsmith_2.nbt new file mode 100644 index 000000000..b9b752d78 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/houses/taiga_weaponsmith_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/streets/corner_01.nbt b/pumpkin-world/assets/structures/village/taiga/streets/corner_01.nbt new file mode 100644 index 000000000..f7710f02a Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/streets/corner_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/streets/corner_02.nbt b/pumpkin-world/assets/structures/village/taiga/streets/corner_02.nbt new file mode 100644 index 000000000..49ecd3040 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/streets/corner_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/streets/corner_03.nbt b/pumpkin-world/assets/structures/village/taiga/streets/corner_03.nbt new file mode 100644 index 000000000..d69ae7f98 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/streets/corner_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/streets/crossroad_01.nbt b/pumpkin-world/assets/structures/village/taiga/streets/crossroad_01.nbt new file mode 100644 index 000000000..a122e1c2a Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/streets/crossroad_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/streets/crossroad_02.nbt b/pumpkin-world/assets/structures/village/taiga/streets/crossroad_02.nbt new file mode 100644 index 000000000..b571b8934 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/streets/crossroad_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/streets/crossroad_03.nbt b/pumpkin-world/assets/structures/village/taiga/streets/crossroad_03.nbt new file mode 100644 index 000000000..4b17f2f7f Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/streets/crossroad_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/streets/crossroad_04.nbt b/pumpkin-world/assets/structures/village/taiga/streets/crossroad_04.nbt new file mode 100644 index 000000000..f83f8a3d1 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/streets/crossroad_04.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/streets/crossroad_05.nbt b/pumpkin-world/assets/structures/village/taiga/streets/crossroad_05.nbt new file mode 100644 index 000000000..097bdcf54 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/streets/crossroad_05.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/streets/crossroad_06.nbt b/pumpkin-world/assets/structures/village/taiga/streets/crossroad_06.nbt new file mode 100644 index 000000000..6ba3186eb Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/streets/crossroad_06.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/streets/straight_01.nbt b/pumpkin-world/assets/structures/village/taiga/streets/straight_01.nbt new file mode 100644 index 000000000..e066486fc Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/streets/straight_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/streets/straight_02.nbt b/pumpkin-world/assets/structures/village/taiga/streets/straight_02.nbt new file mode 100644 index 000000000..983354424 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/streets/straight_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/streets/straight_03.nbt b/pumpkin-world/assets/structures/village/taiga/streets/straight_03.nbt new file mode 100644 index 000000000..eb740e635 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/streets/straight_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/streets/straight_04.nbt b/pumpkin-world/assets/structures/village/taiga/streets/straight_04.nbt new file mode 100644 index 000000000..8b59fd8c5 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/streets/straight_04.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/streets/straight_05.nbt b/pumpkin-world/assets/structures/village/taiga/streets/straight_05.nbt new file mode 100644 index 000000000..84b541f67 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/streets/straight_05.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/streets/straight_06.nbt b/pumpkin-world/assets/structures/village/taiga/streets/straight_06.nbt new file mode 100644 index 000000000..0643c3772 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/streets/straight_06.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/streets/turn_01.nbt b/pumpkin-world/assets/structures/village/taiga/streets/turn_01.nbt new file mode 100644 index 000000000..d96210e9b Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/streets/turn_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/taiga_decoration_1.nbt b/pumpkin-world/assets/structures/village/taiga/taiga_decoration_1.nbt new file mode 100644 index 000000000..bcff4eaf8 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/taiga_decoration_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/taiga_decoration_2.nbt b/pumpkin-world/assets/structures/village/taiga/taiga_decoration_2.nbt new file mode 100644 index 000000000..c341397d6 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/taiga_decoration_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/taiga_decoration_3.nbt b/pumpkin-world/assets/structures/village/taiga/taiga_decoration_3.nbt new file mode 100644 index 000000000..693b18d8f Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/taiga_decoration_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/taiga_decoration_4.nbt b/pumpkin-world/assets/structures/village/taiga/taiga_decoration_4.nbt new file mode 100644 index 000000000..8145ec674 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/taiga_decoration_4.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/taiga_decoration_5.nbt b/pumpkin-world/assets/structures/village/taiga/taiga_decoration_5.nbt new file mode 100644 index 000000000..ef4a45b6b Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/taiga_decoration_5.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/taiga_decoration_6.nbt b/pumpkin-world/assets/structures/village/taiga/taiga_decoration_6.nbt new file mode 100644 index 000000000..618af4d5e Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/taiga_decoration_6.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/taiga_lamp_post_1.nbt b/pumpkin-world/assets/structures/village/taiga/taiga_lamp_post_1.nbt new file mode 100644 index 000000000..f2e2b661e Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/taiga_lamp_post_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/town_centers/taiga_meeting_point_1.nbt b/pumpkin-world/assets/structures/village/taiga/town_centers/taiga_meeting_point_1.nbt new file mode 100644 index 000000000..07b88e31f Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/town_centers/taiga_meeting_point_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/town_centers/taiga_meeting_point_2.nbt b/pumpkin-world/assets/structures/village/taiga/town_centers/taiga_meeting_point_2.nbt new file mode 100644 index 000000000..5abbaae82 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/town_centers/taiga_meeting_point_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/villagers/baby.nbt b/pumpkin-world/assets/structures/village/taiga/villagers/baby.nbt new file mode 100644 index 000000000..8c7decd25 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/villagers/baby.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/villagers/nitwit.nbt b/pumpkin-world/assets/structures/village/taiga/villagers/nitwit.nbt new file mode 100644 index 000000000..bf1042211 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/villagers/nitwit.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/villagers/unemployed.nbt b/pumpkin-world/assets/structures/village/taiga/villagers/unemployed.nbt new file mode 100644 index 000000000..6d0ebabec Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/villagers/unemployed.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_cartographer_house_1.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_cartographer_house_1.nbt new file mode 100644 index 000000000..7ce79f997 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_cartographer_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_fisher_cottage_1.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_fisher_cottage_1.nbt new file mode 100644 index 000000000..d93acc950 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_fisher_cottage_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_large_farm_2.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_large_farm_2.nbt new file mode 100644 index 000000000..8fcdf1659 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_large_farm_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_library_1.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_library_1.nbt new file mode 100644 index 000000000..06e4fb2ac Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_library_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_medium_house_1.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_medium_house_1.nbt new file mode 100644 index 000000000..1d03560b7 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_medium_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_medium_house_2.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_medium_house_2.nbt new file mode 100644 index 000000000..21044fa13 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_medium_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_medium_house_3.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_medium_house_3.nbt new file mode 100644 index 000000000..a7d7a0a8a Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_medium_house_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_medium_house_4.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_medium_house_4.nbt new file mode 100644 index 000000000..259dca4ae Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_medium_house_4.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_shepherds_house_1.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_shepherds_house_1.nbt new file mode 100644 index 000000000..8875c5b54 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_shepherds_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_small_house_1.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_small_house_1.nbt new file mode 100644 index 000000000..b6239867d Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_small_house_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_small_house_2.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_small_house_2.nbt new file mode 100644 index 000000000..5892ac170 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_small_house_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_small_house_3.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_small_house_3.nbt new file mode 100644 index 000000000..7d324ce6f Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_small_house_3.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_small_house_4.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_small_house_4.nbt new file mode 100644 index 000000000..3832e5569 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_small_house_4.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_small_house_5.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_small_house_5.nbt new file mode 100644 index 000000000..934cef359 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_small_house_5.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_temple_1.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_temple_1.nbt new file mode 100644 index 000000000..6fb8a0b07 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_temple_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_tool_smith_1.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_tool_smith_1.nbt new file mode 100644 index 000000000..be23feaa8 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_tool_smith_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_weaponsmith_2.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_weaponsmith_2.nbt new file mode 100644 index 000000000..6165c67ce Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/houses/taiga_weaponsmith_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/streets/corner_01.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/streets/corner_01.nbt new file mode 100644 index 000000000..7407e9280 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/streets/corner_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/streets/corner_02.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/streets/corner_02.nbt new file mode 100644 index 000000000..2d53a110d Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/streets/corner_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/streets/corner_03.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/streets/corner_03.nbt new file mode 100644 index 000000000..4b42edc6b Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/streets/corner_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/streets/crossroad_01.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/streets/crossroad_01.nbt new file mode 100644 index 000000000..5791c6935 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/streets/crossroad_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/streets/crossroad_02.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/streets/crossroad_02.nbt new file mode 100644 index 000000000..edd5947f3 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/streets/crossroad_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/streets/crossroad_03.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/streets/crossroad_03.nbt new file mode 100644 index 000000000..002f20a15 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/streets/crossroad_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/streets/crossroad_04.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/streets/crossroad_04.nbt new file mode 100644 index 000000000..19b26adb2 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/streets/crossroad_04.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/streets/crossroad_05.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/streets/crossroad_05.nbt new file mode 100644 index 000000000..80dcbc8c8 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/streets/crossroad_05.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/streets/crossroad_06.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/streets/crossroad_06.nbt new file mode 100644 index 000000000..8620881d4 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/streets/crossroad_06.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/streets/straight_01.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/streets/straight_01.nbt new file mode 100644 index 000000000..2d97d06aa Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/streets/straight_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/streets/straight_02.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/streets/straight_02.nbt new file mode 100644 index 000000000..3f5b7ad7b Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/streets/straight_02.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/streets/straight_03.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/streets/straight_03.nbt new file mode 100644 index 000000000..e5e5bb110 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/streets/straight_03.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/streets/straight_04.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/streets/straight_04.nbt new file mode 100644 index 000000000..b032f9d5c Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/streets/straight_04.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/streets/straight_05.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/streets/straight_05.nbt new file mode 100644 index 000000000..6ef80a246 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/streets/straight_05.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/streets/straight_06.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/streets/straight_06.nbt new file mode 100644 index 000000000..606e07b2f Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/streets/straight_06.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/streets/turn_01.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/streets/turn_01.nbt new file mode 100644 index 000000000..0b460bcbb Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/streets/turn_01.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/town_centers/taiga_meeting_point_1.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/town_centers/taiga_meeting_point_1.nbt new file mode 100644 index 000000000..0f67c6402 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/town_centers/taiga_meeting_point_1.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/town_centers/taiga_meeting_point_2.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/town_centers/taiga_meeting_point_2.nbt new file mode 100644 index 000000000..63b5579de Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/town_centers/taiga_meeting_point_2.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/villagers/nitwit.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/villagers/nitwit.nbt new file mode 100644 index 000000000..42dc1add1 Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/villagers/nitwit.nbt differ diff --git a/pumpkin-world/assets/structures/village/taiga/zombie/villagers/unemployed.nbt b/pumpkin-world/assets/structures/village/taiga/zombie/villagers/unemployed.nbt new file mode 100644 index 000000000..90146163c Binary files /dev/null and b/pumpkin-world/assets/structures/village/taiga/zombie/villagers/unemployed.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x1_a1.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x1_a1.nbt new file mode 100644 index 000000000..a1823e836 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x1_a1.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x1_a2.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x1_a2.nbt new file mode 100644 index 000000000..ad1f0be4a Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x1_a2.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x1_a3.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x1_a3.nbt new file mode 100644 index 000000000..0c14a3b96 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x1_a3.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x1_a4.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x1_a4.nbt new file mode 100644 index 000000000..0dff68a88 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x1_a4.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x1_a5.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x1_a5.nbt new file mode 100644 index 000000000..d1f773973 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x1_a5.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x1_as1.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x1_as1.nbt new file mode 100644 index 000000000..b985ca65f Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x1_as1.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x1_as2.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x1_as2.nbt new file mode 100644 index 000000000..1548e683c Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x1_as2.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x1_as3.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x1_as3.nbt new file mode 100644 index 000000000..b6b144d6a Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x1_as3.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x1_as4.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x1_as4.nbt new file mode 100644 index 000000000..7553e0065 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x1_as4.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x1_b1.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x1_b1.nbt new file mode 100644 index 000000000..7fa8d1b87 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x1_b1.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x1_b2.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x1_b2.nbt new file mode 100644 index 000000000..af34c86e4 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x1_b2.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x1_b3.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x1_b3.nbt new file mode 100644 index 000000000..43e919399 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x1_b3.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x1_b4.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x1_b4.nbt new file mode 100644 index 000000000..aa6dbc272 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x1_b4.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x1_b5.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x1_b5.nbt new file mode 100644 index 000000000..25671fe07 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x1_b5.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_a1.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_a1.nbt new file mode 100644 index 000000000..8fc604942 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_a1.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_a2.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_a2.nbt new file mode 100644 index 000000000..87309619d Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_a2.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_a3.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_a3.nbt new file mode 100644 index 000000000..6682e5ef4 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_a3.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_a4.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_a4.nbt new file mode 100644 index 000000000..aee26807a Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_a4.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_a5.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_a5.nbt new file mode 100644 index 000000000..b585e8107 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_a5.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_a6.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_a6.nbt new file mode 100644 index 000000000..71def5993 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_a6.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_a7.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_a7.nbt new file mode 100644 index 000000000..d1e587b30 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_a7.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_a8.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_a8.nbt new file mode 100644 index 000000000..ecd9a9578 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_a8.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_a9.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_a9.nbt new file mode 100644 index 000000000..9fead00ed Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_a9.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_b1.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_b1.nbt new file mode 100644 index 000000000..63b4ea3f7 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_b1.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_b2.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_b2.nbt new file mode 100644 index 000000000..a6a702fc1 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_b2.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_b3.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_b3.nbt new file mode 100644 index 000000000..d0b6eb033 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_b3.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_b4.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_b4.nbt new file mode 100644 index 000000000..0d4f0cc54 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_b4.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_b5.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_b5.nbt new file mode 100644 index 000000000..44f1730f6 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_b5.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_c1.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_c1.nbt new file mode 100644 index 000000000..ff5594e20 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_c1.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_c2.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_c2.nbt new file mode 100644 index 000000000..a093c5992 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_c2.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_c3.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_c3.nbt new file mode 100644 index 000000000..5f978aefd Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_c3.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_c4.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_c4.nbt new file mode 100644 index 000000000..6a83e7fd2 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_c4.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_c_stairs.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_c_stairs.nbt new file mode 100644 index 000000000..f5dc93943 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_c_stairs.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_d1.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_d1.nbt new file mode 100644 index 000000000..2f0fd1f7d Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_d1.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_d2.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_d2.nbt new file mode 100644 index 000000000..f0164e0d9 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_d2.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_d3.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_d3.nbt new file mode 100644 index 000000000..a257b0fab Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_d3.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_d4.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_d4.nbt new file mode 100644 index 000000000..9bf4a7e27 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_d4.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_d5.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_d5.nbt new file mode 100644 index 000000000..8c1436fa5 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_d5.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_d_stairs.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_d_stairs.nbt new file mode 100644 index 000000000..cd7adeb11 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_d_stairs.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_s1.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_s1.nbt new file mode 100644 index 000000000..947a79fad Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_s1.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_s2.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_s2.nbt new file mode 100644 index 000000000..eade3cb18 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_s2.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/1x2_se1.nbt b/pumpkin-world/assets/structures/woodland_mansion/1x2_se1.nbt new file mode 100644 index 000000000..0e7669495 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/1x2_se1.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/2x2_a1.nbt b/pumpkin-world/assets/structures/woodland_mansion/2x2_a1.nbt new file mode 100644 index 000000000..bb7a99ae1 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/2x2_a1.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/2x2_a2.nbt b/pumpkin-world/assets/structures/woodland_mansion/2x2_a2.nbt new file mode 100644 index 000000000..56fe528c0 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/2x2_a2.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/2x2_a3.nbt b/pumpkin-world/assets/structures/woodland_mansion/2x2_a3.nbt new file mode 100644 index 000000000..0b0d7fcb6 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/2x2_a3.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/2x2_a4.nbt b/pumpkin-world/assets/structures/woodland_mansion/2x2_a4.nbt new file mode 100644 index 000000000..b2f35a735 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/2x2_a4.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/2x2_b1.nbt b/pumpkin-world/assets/structures/woodland_mansion/2x2_b1.nbt new file mode 100644 index 000000000..d172f47f7 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/2x2_b1.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/2x2_b2.nbt b/pumpkin-world/assets/structures/woodland_mansion/2x2_b2.nbt new file mode 100644 index 000000000..65fd25645 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/2x2_b2.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/2x2_b3.nbt b/pumpkin-world/assets/structures/woodland_mansion/2x2_b3.nbt new file mode 100644 index 000000000..14c8a7fe8 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/2x2_b3.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/2x2_b4.nbt b/pumpkin-world/assets/structures/woodland_mansion/2x2_b4.nbt new file mode 100644 index 000000000..aa1ea3ea5 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/2x2_b4.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/2x2_b5.nbt b/pumpkin-world/assets/structures/woodland_mansion/2x2_b5.nbt new file mode 100644 index 000000000..0ab980d4b Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/2x2_b5.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/2x2_s1.nbt b/pumpkin-world/assets/structures/woodland_mansion/2x2_s1.nbt new file mode 100644 index 000000000..6785fd071 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/2x2_s1.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/carpet_east.nbt b/pumpkin-world/assets/structures/woodland_mansion/carpet_east.nbt new file mode 100644 index 000000000..441d61ef3 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/carpet_east.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/carpet_north.nbt b/pumpkin-world/assets/structures/woodland_mansion/carpet_north.nbt new file mode 100644 index 000000000..548b8ce62 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/carpet_north.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/carpet_south_1.nbt b/pumpkin-world/assets/structures/woodland_mansion/carpet_south_1.nbt new file mode 100644 index 000000000..3fac45f85 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/carpet_south_1.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/carpet_south_2.nbt b/pumpkin-world/assets/structures/woodland_mansion/carpet_south_2.nbt new file mode 100644 index 000000000..11ee9b323 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/carpet_south_2.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/carpet_west_1.nbt b/pumpkin-world/assets/structures/woodland_mansion/carpet_west_1.nbt new file mode 100644 index 000000000..f818b70d0 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/carpet_west_1.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/carpet_west_2.nbt b/pumpkin-world/assets/structures/woodland_mansion/carpet_west_2.nbt new file mode 100644 index 000000000..a31f7d326 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/carpet_west_2.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/corridor_floor.nbt b/pumpkin-world/assets/structures/woodland_mansion/corridor_floor.nbt new file mode 100644 index 000000000..0f4d0cda6 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/corridor_floor.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/entrance.nbt b/pumpkin-world/assets/structures/woodland_mansion/entrance.nbt new file mode 100644 index 000000000..06d5acc08 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/entrance.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/indoors_door_1.nbt b/pumpkin-world/assets/structures/woodland_mansion/indoors_door_1.nbt new file mode 100644 index 000000000..e1094b671 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/indoors_door_1.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/indoors_door_2.nbt b/pumpkin-world/assets/structures/woodland_mansion/indoors_door_2.nbt new file mode 100644 index 000000000..a6db591e0 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/indoors_door_2.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/indoors_wall_1.nbt b/pumpkin-world/assets/structures/woodland_mansion/indoors_wall_1.nbt new file mode 100644 index 000000000..f15541599 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/indoors_wall_1.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/indoors_wall_2.nbt b/pumpkin-world/assets/structures/woodland_mansion/indoors_wall_2.nbt new file mode 100644 index 000000000..37a040fe2 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/indoors_wall_2.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/roof.nbt b/pumpkin-world/assets/structures/woodland_mansion/roof.nbt new file mode 100644 index 000000000..7998618a9 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/roof.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/roof_corner.nbt b/pumpkin-world/assets/structures/woodland_mansion/roof_corner.nbt new file mode 100644 index 000000000..48153b9a8 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/roof_corner.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/roof_front.nbt b/pumpkin-world/assets/structures/woodland_mansion/roof_front.nbt new file mode 100644 index 000000000..e664a9563 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/roof_front.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/roof_inner_corner.nbt b/pumpkin-world/assets/structures/woodland_mansion/roof_inner_corner.nbt new file mode 100644 index 000000000..287df02fd Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/roof_inner_corner.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/small_wall.nbt b/pumpkin-world/assets/structures/woodland_mansion/small_wall.nbt new file mode 100644 index 000000000..1d2a59c62 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/small_wall.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/small_wall_corner.nbt b/pumpkin-world/assets/structures/woodland_mansion/small_wall_corner.nbt new file mode 100644 index 000000000..9bbab5c10 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/small_wall_corner.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/wall_corner.nbt b/pumpkin-world/assets/structures/woodland_mansion/wall_corner.nbt new file mode 100644 index 000000000..64b39892f Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/wall_corner.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/wall_flat.nbt b/pumpkin-world/assets/structures/woodland_mansion/wall_flat.nbt new file mode 100644 index 000000000..908646cac Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/wall_flat.nbt differ diff --git a/pumpkin-world/assets/structures/woodland_mansion/wall_window.nbt b/pumpkin-world/assets/structures/woodland_mansion/wall_window.nbt new file mode 100644 index 000000000..425491294 Binary files /dev/null and b/pumpkin-world/assets/structures/woodland_mansion/wall_window.nbt differ diff --git a/pumpkin-world/benches/chunk_gen.rs b/pumpkin-world/benches/chunk_gen.rs index 5148e0cb5..fe0194d98 100644 --- a/pumpkin-world/benches/chunk_gen.rs +++ b/pumpkin-world/benches/chunk_gen.rs @@ -25,6 +25,24 @@ impl WorldPortalExt for BlockRegistry { true } + fn mirror( + &self, + block: &pumpkin_data::Block, + state_id: u16, + mirror: pumpkin_data::Mirror, + ) -> &'static pumpkin_data::BlockState { + block.mirror(state_id, mirror) + } + + fn rotate( + &self, + block: &pumpkin_data::Block, + state_id: u16, + rotation: pumpkin_data::Rotation, + ) -> &'static pumpkin_data::BlockState { + block.rotate(state_id, rotation) + } + fn spawn_mobs_for_chunk_generation( &self, _cache: &mut dyn pumpkin_world::generation::proto_chunk::GenerationCache, diff --git a/pumpkin-world/benches/chunk_gen_concurrent.rs b/pumpkin-world/benches/chunk_gen_concurrent.rs index 73c794a8d..fbcb6437a 100644 --- a/pumpkin-world/benches/chunk_gen_concurrent.rs +++ b/pumpkin-world/benches/chunk_gen_concurrent.rs @@ -25,6 +25,24 @@ impl WorldPortalExt for BlockRegistry { true } + fn mirror( + &self, + block: &pumpkin_data::Block, + state_id: u16, + mirror: pumpkin_data::Mirror, + ) -> &'static pumpkin_data::BlockState { + block.mirror(state_id, mirror) + } + + fn rotate( + &self, + block: &pumpkin_data::Block, + state_id: u16, + rotation: pumpkin_data::Rotation, + ) -> &'static pumpkin_data::BlockState { + block.rotate(state_id, rotation) + } + fn spawn_mobs_for_chunk_generation( &self, _cache: &mut dyn pumpkin_world::generation::proto_chunk::GenerationCache, diff --git a/pumpkin-world/benches/noise_router.rs b/pumpkin-world/benches/noise_router.rs index 15f22731d..9052a4ba5 100644 --- a/pumpkin-world/benches/noise_router.rs +++ b/pumpkin-world/benches/noise_router.rs @@ -16,7 +16,8 @@ fn bench_noise_router_creation(c: &mut Criterion) { let proto_routers = ProtoNoiseRouters::generate(base_routers, &random_config); let proto_noise_router = proto_routers.noise; - let builder_options = ChunkNoiseFunctionBuilderOptions::new(4, 8, 4, 4, 0, 0, 3); + let builder_options = + ChunkNoiseFunctionBuilderOptions::new(4, 8, 4, 4, 0, 0, 3, vec![], vec![], None); // Benchmarking c.bench_function("noise_router_creation_with_pooling", |b| { diff --git a/pumpkin-world/build.rs b/pumpkin-world/build.rs new file mode 100644 index 000000000..ea68b01fc --- /dev/null +++ b/pumpkin-world/build.rs @@ -0,0 +1,79 @@ +use std::env; +use std::fs; +use std::path::Path; + +fn main() { + let out_dir = env::var_os("OUT_DIR").unwrap(); + let dest_path = Path::new(&out_dir).join("template_embeddings.rs"); + + let mut code = String::from( + "pub fn get_template_bytes(path: &str) -> Option<&'static [u8]> {\n match path {\n", + ); + let mut pool_code = String::from( + "pub fn get_pool_elements(pool_id: &str) -> Option<&'static [&'static str]> {\n match pool_id {\n", + ); + + let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + let assets_dir = Path::new(&manifest_dir).join("assets/structures"); + if assets_dir.exists() { + let mut pools = std::collections::BTreeMap::new(); + process_dir(&assets_dir, "", &mut code, &mut pools); + + for (pool_id, elements) in pools { + pool_code.push_str(&format!( + " \"minecraft:{}\" | \"{}\" => Some(&[\n", + pool_id, pool_id + )); + for element in elements { + pool_code.push_str(&format!(" \"{}\",\n", element)); + } + pool_code.push_str(" ]),\n"); + } + } + + code.push_str(" _ => None,\n"); + code.push_str(" }\n}\n"); + + pool_code.push_str(" _ => None,\n"); + pool_code.push_str(" }\n}\n"); + + fs::write(&dest_path, format!("{}\n{}", code, pool_code)).unwrap(); + println!("cargo:rerun-if-changed=assets/structures"); +} + +fn process_dir( + dir: &Path, + prefix: &str, + code: &mut String, + pools: &mut std::collections::BTreeMap>, +) { + for entry in fs::read_dir(dir).unwrap() { + let entry = entry.unwrap(); + let path = entry.path(); + let name = entry.file_name().into_string().unwrap(); + + if path.is_dir() { + let new_prefix = if prefix.is_empty() { + name + } else { + format!("{}/{}", prefix, name) + }; + process_dir(&path, &new_prefix, code, pools); + } else if name.ends_with(".nbt") { + let template_name = format!("{}/{}", prefix, name.strip_suffix(".nbt").unwrap()); + let abs_path = path.canonicalize().unwrap(); + code.push_str(&format!( + " \"{}\" => Some(include_bytes!(\"{}\")),\n", + template_name, + abs_path.display() + )); + + if !prefix.is_empty() { + pools + .entry(prefix.to_string()) + .or_default() + .push(template_name); + } + } + } +} diff --git a/pumpkin-world/src/chunk_system/generation.rs b/pumpkin-world/src/chunk_system/generation.rs index 0c6d2212d..23c468bf6 100644 --- a/pumpkin-world/src/chunk_system/generation.rs +++ b/pumpkin-world/src/chunk_system/generation.rs @@ -83,6 +83,24 @@ mod tests { true } + fn mirror( + &self, + block: &pumpkin_data::Block, + state_id: u16, + mirror: pumpkin_data::Mirror, + ) -> &'static pumpkin_data::BlockState { + block.mirror(state_id, mirror) + } + + fn rotate( + &self, + block: &pumpkin_data::Block, + state_id: u16, + rotation: pumpkin_data::Rotation, + ) -> &'static pumpkin_data::BlockState { + block.rotate(state_id, rotation) + } + fn spawn_mobs_for_chunk_generation( &self, _cache: &mut dyn crate::generation::proto_chunk::GenerationCache, diff --git a/pumpkin-world/src/generation/noise/aquifer_sampler.rs b/pumpkin-world/src/generation/noise/aquifer_sampler.rs index b7e8c82fa..4e0e26a48 100644 --- a/pumpkin-world/src/generation/noise/aquifer_sampler.rs +++ b/pumpkin-world/src/generation/noise/aquifer_sampler.rs @@ -734,6 +734,9 @@ mod random_positions_and_hypot { sampler, true, true, + Vec::new(), + Vec::new(), + None, ); let options = ChunkNoiseFunctionSampleOptions::new(false, SampleAction::SkipCellCaches, 0, 0, 0); diff --git a/pumpkin-world/src/generation/noise/mod.rs b/pumpkin-world/src/generation/noise/mod.rs index ec822771a..c1e8f1fd7 100644 --- a/pumpkin-world/src/generation/noise/mod.rs +++ b/pumpkin-world/src/generation/noise/mod.rs @@ -4,10 +4,7 @@ pub mod perlin; pub mod router; use pumpkin_data::{Block, BlockState, chunk_gen_settings::GenerationShapeConfig}; -use pumpkin_util::{ - math::{floor_div, floor_mod, vector3::Vector3}, - random::xoroshiro128::XoroshiroSplitter, -}; +use pumpkin_util::{math::vector3::Vector3, random::xoroshiro128::XoroshiroSplitter}; use crate::generation::{ noise::{ @@ -134,12 +131,12 @@ impl IndexToNoisePos for ChunkIndexMapper { index: usize, sample_options: Option<&mut ChunkNoiseFunctionSampleOptions>, ) -> Vector3 { - let cell_z_position = floor_mod(index, self.horizontal_cell_block_count); - let xy_portion = floor_div(index, self.horizontal_cell_block_count); - let cell_x_position = floor_mod(xy_portion, self.horizontal_cell_block_count); - let cell_y_position = self.vertical_cell_block_count - - 1 - - floor_div(xy_portion, self.horizontal_cell_block_count); + // Matches vanilla mathematical index mapping (yInCell, xInCell, zInCell) + let cell_z_position = index % self.horizontal_cell_block_count; + let xy_portion = index / self.horizontal_cell_block_count; + let cell_x_position = xy_portion % self.horizontal_cell_block_count; + let cell_y_position = + self.vertical_cell_block_count - 1 - (xy_portion / self.horizontal_cell_block_count); if let Some(sample_options) = sample_options { sample_options.fill_index = index; @@ -185,27 +182,27 @@ impl<'a> ChunkNoiseGenerator<'a> { level_sampler: StandardChunkFluidLevelSampler, aquifers: bool, ore_veins: bool, + beardifier_structures: Vec< + crate::generation::noise::router::density_function::beardifier::BeardifierStructure, + >, + beardifier_junctions: Vec< + crate::generation::noise::router::density_function::beardifier::BeardifierJunction, + >, + affected_box: Option, ) -> Self { - let start_cell_pos_x = floor_div( - start_block_x, - generation_shape.horizontal_cell_block_count() as i32, - ); - let start_cell_pos_z = floor_div( - start_block_z, - generation_shape.horizontal_cell_block_count() as i32, - ); + let start_cell_pos_x = + start_block_x / generation_shape.horizontal_cell_block_count() as i32; + let start_cell_pos_z = + start_block_z / generation_shape.horizontal_cell_block_count() as i32; let horizontal_biome_end = biome_coords::from_block( horizontal_cell_count as i32 * generation_shape.horizontal_cell_block_count() as i32, ); - let vertical_cell_count = floor_div( - generation_shape.height as usize, - generation_shape.vertical_cell_block_count() as usize, - ); - let minimum_cell_y = floor_div( - generation_shape.min_y as i32, - generation_shape.vertical_cell_block_count() as i32, - ); + let vertical_cell_count = (generation_shape.height as usize) + / (generation_shape.vertical_cell_block_count() as usize); + let minimum_cell_y = + (generation_shape.min_y as i32) / (generation_shape.vertical_cell_block_count() as i32); + let vertical_cell_block_count = generation_shape.vertical_cell_block_count(); let horizontal_cell_block_count = generation_shape.horizontal_cell_block_count(); @@ -217,6 +214,9 @@ impl<'a> ChunkNoiseGenerator<'a> { biome_coords::from_block(start_block_x), biome_coords::from_block(start_block_z), horizontal_biome_end as usize, + beardifier_structures, + beardifier_junctions, + affected_box, ); let aquifer_sampler = if aquifers { @@ -387,7 +387,6 @@ impl<'a> ChunkNoiseGenerator<'a> { cell_z: i32, height_estimator: &mut SurfaceHeightEstimateSampler, ) -> Option<&'static BlockState> { - //TODO: Fix this when Blender is added let pos = Vector3::new(start_x + cell_x, start_y + cell_y, start_z + cell_z); let options = ChunkNoiseFunctionSampleOptions::new( diff --git a/pumpkin-world/src/generation/noise/router/chunk_density_function.rs b/pumpkin-world/src/generation/noise/router/chunk_density_function.rs index 6db7d0faa..98163f969 100644 --- a/pumpkin-world/src/generation/noise/router/chunk_density_function.rs +++ b/pumpkin-world/src/generation/noise/router/chunk_density_function.rs @@ -151,11 +151,17 @@ pub struct ChunkNoiseFunctionBuilderOptions { // Number of biome regions per chunk per axis pub horizontal_biome_end: usize, -} + pub beardifier_structures: + Vec, + pub beardifier_junctions: + Vec, + pub affected_box: Option, +} impl ChunkNoiseFunctionBuilderOptions { #[must_use] - pub const fn new( + #[allow(clippy::too_many_arguments)] + pub fn new( horizontal_cell_block_count: usize, vertical_cell_block_count: usize, vertical_cell_count: usize, @@ -163,6 +169,13 @@ impl ChunkNoiseFunctionBuilderOptions { start_biome_x: i32, start_biome_z: i32, horizontal_biome_end: usize, + beardifier_structures: Vec< + crate::generation::noise::router::density_function::beardifier::BeardifierStructure, + >, + beardifier_junctions: Vec< + crate::generation::noise::router::density_function::beardifier::BeardifierJunction, + >, + affected_box: Option, ) -> Self { Self { horizontal_cell_block_count, @@ -172,6 +185,9 @@ impl ChunkNoiseFunctionBuilderOptions { start_biome_x, start_biome_z, horizontal_biome_end, + beardifier_structures, + beardifier_junctions, + affected_box, } } } @@ -732,4 +748,5 @@ pub enum ChunkSpecificNoiseFunctionComponent { Cache2D(Cache2D), CacheOnce(CacheOnce), CellCache(CellCache), + Beardifier(crate::generation::noise::router::density_function::beardifier::Beardifier), } diff --git a/pumpkin-world/src/generation/noise/router/chunk_noise_router.rs b/pumpkin-world/src/generation/noise/router/chunk_noise_router.rs index 0b428f5e9..8e78c8956 100644 --- a/pumpkin-world/src/generation/noise/router/chunk_noise_router.rs +++ b/pumpkin-world/src/generation/noise/router/chunk_noise_router.rs @@ -349,6 +349,17 @@ impl<'a> ChunkNoiseRouter<'a> { ProtoNoiseFunctionComponent::PassThrough(pass_through) => { ChunkNoiseFunctionComponent::PassThrough(pass_through.clone()) } + ProtoNoiseFunctionComponent::Beardifier(_) => { + ChunkNoiseFunctionComponent::Chunk( + ChunkSpecificNoiseFunctionComponent::Beardifier( + crate::generation::noise::router::density_function::beardifier::Beardifier::new( + build_options.beardifier_structures.clone(), + build_options.beardifier_junctions.clone(), + build_options.affected_box, + ), + ), + ) + } ProtoNoiseFunctionComponent::Wrapper(wrapper) => { let min_value = component_stack[wrapper.input_index].min(); let max_value = component_stack[wrapper.input_index].max(); diff --git a/pumpkin-world/src/generation/noise/router/density_function/beardifier.rs b/pumpkin-world/src/generation/noise/router/density_function/beardifier.rs new file mode 100644 index 000000000..1f377c2a2 --- /dev/null +++ b/pumpkin-world/src/generation/noise/router/density_function/beardifier.rs @@ -0,0 +1,217 @@ +use crate::generation::noise::router::chunk_density_function::ChunkNoiseFunctionSampleOptions; +use crate::generation::noise::router::chunk_noise_router::{ + ChunkNoiseFunctionComponent, MutableChunkNoiseFunctionComponentImpl, +}; +use pumpkin_util::math::{block_box::BlockBox, vector3::Vector3}; +use std::sync::OnceLock; + +use super::{NoiseFunctionComponentRange, StaticIndependentChunkNoiseFunctionComponentImpl}; + +const BEARD_KERNEL_RADIUS: i32 = 12; +const BEARD_KERNEL_SIZE: i32 = 24; + +static BEARD_KERNEL: OnceLock<[f64; 13824]> = OnceLock::new(); + +fn get_beard_kernel() -> &'static [f64; 13824] { + BEARD_KERNEL.get_or_init(|| { + let mut kernel = [0.0; 13824]; + for zi in 0..BEARD_KERNEL_SIZE { + for xi in 0..BEARD_KERNEL_SIZE { + for yi in 0..BEARD_KERNEL_SIZE { + kernel[(zi * 24 * 24 + xi * 24 + yi) as usize] = compute_beard_contribution( + xi - BEARD_KERNEL_RADIUS, + (yi - BEARD_KERNEL_RADIUS) as f64 + 0.5, + zi - BEARD_KERNEL_RADIUS, + ); + } + } + } + kernel + }) +} + +fn compute_beard_contribution(dx: i32, dy: f64, dz: i32) -> f64 { + let distance_sqr = (dx as f64).powi(2) + dy.powi(2) + (dz as f64).powi(2); + std::f64::consts::E.powf(-distance_sqr / 16.0) +} + +fn get_bury_contribution(dx: f64, dy: f64, dz: f64) -> f64 { + let distance = (dx * dx + dy * dy + dz * dz).sqrt(); + + // Equivalent to Mth.clampedMap(distance, 0.0, 6.0, 1.0, 0.0) + if distance < 0.0 { + 1.0 + } else if distance > 6.0 { + 0.0 + } else { + 1.0 - (distance / 6.0) + } +} + +fn get_beard_contribution(dx: i32, dy: i32, dz: i32, y_to_ground: i32) -> f64 { + let xi = dx + BEARD_KERNEL_RADIUS; + let yi = dy + BEARD_KERNEL_RADIUS; + let zi = dz + BEARD_KERNEL_RADIUS; + + if (0..BEARD_KERNEL_SIZE).contains(&xi) + && (0..BEARD_KERNEL_SIZE).contains(&yi) + && (0..BEARD_KERNEL_SIZE).contains(&zi) + { + let dy_with_offset = y_to_ground as f64 + 0.5; + let distance_sqr = (dx as f64).powi(2) + dy_with_offset.powi(2) + (dz as f64).powi(2); + + // Equivalent to: -dyWithOffset * Mth.fastInvSqrt(distanceSqr / 2.0) / 2.0 + let value = -dy_with_offset * (distance_sqr / 2.0).sqrt().recip() / 2.0; + + let kernel = get_beard_kernel(); + value * kernel[(zi * 24 * 24 + xi * 24 + yi) as usize] + } else { + 0.0 + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub enum TerrainAdaptation { + None, + BeardThin, + BeardBox, + Bury, + Encapsulate, +} + +impl TerrainAdaptation { + pub fn from_str(s: &str) -> Self { + match s { + "beard_thin" => Self::BeardThin, + "beard_box" => Self::BeardBox, + "bury" => Self::Bury, + "encapsulate" => Self::Encapsulate, + _ => Self::None, + } + } +} + +#[derive(Clone, Debug)] +pub struct BeardifierJunction { + pub x: i32, + pub ground_y: i32, + pub z: i32, +} + +// Corresponds to Beardifier.Rigid in Java +#[derive(Clone, Debug)] +pub struct BeardifierStructure { + pub bounding_box: BlockBox, + pub terrain_adaptation: TerrainAdaptation, + pub ground_level_delta: i32, +} + +#[derive(Clone)] +pub struct Beardifier { + pub structures: Vec, + pub junctions: Vec, + pub affected_box: Option, +} + +impl Beardifier { + pub fn new( + structures: Vec, + junctions: Vec, + affected_box: Option, + ) -> Self { + Self { + structures, + junctions, + affected_box, + } + } +} + +impl StaticIndependentChunkNoiseFunctionComponentImpl for Beardifier { + fn sample(&self, pos: &Vector3) -> f64 { + let affected_box = match self.affected_box { + Some(b) => b, + None => return 0.0, + }; + + let block_x = pos.x; + let block_y = pos.y; + let block_z = pos.z; + + if !affected_box.contains(block_x, block_y, block_z) { + return 0.0; + } + + let mut weight = 0.0; + + for structure in &self.structures { + let box_min_x = structure.bounding_box.min.x; + let box_min_y = structure.bounding_box.min.y; + let box_min_z = structure.bounding_box.min.z; + let box_max_x = structure.bounding_box.max.x; + let box_max_y = structure.bounding_box.max.y; + let box_max_z = structure.bounding_box.max.z; + + let ground_level_delta = structure.ground_level_delta; + + let dx = 0.max((box_min_x - block_x).max(block_x - box_max_x)); + let dz = 0.max((box_min_z - block_z).max(block_z - box_max_z)); + let ground_y = box_min_y + ground_level_delta; + let dy_to_ground = block_y - ground_y; + + let dy = match structure.terrain_adaptation { + TerrainAdaptation::None => 0, + TerrainAdaptation::Bury | TerrainAdaptation::BeardThin => dy_to_ground, + TerrainAdaptation::BeardBox => 0.max((ground_y - block_y).max(block_y - box_max_y)), + TerrainAdaptation::Encapsulate => { + 0.max((box_min_y - block_y).max(block_y - box_max_y)) + } + }; + + let contrib = match structure.terrain_adaptation { + TerrainAdaptation::None => 0.0, + TerrainAdaptation::Bury => { + get_bury_contribution(dx as f64, dy as f64 / 2.0, dz as f64) + } + TerrainAdaptation::BeardThin | TerrainAdaptation::BeardBox => { + get_beard_contribution(dx, dy, dz, dy_to_ground) * 0.8 + } + TerrainAdaptation::Encapsulate => { + get_bury_contribution(dx as f64 / 2.0, dy as f64 / 2.0, dz as f64 / 2.0) * 0.8 + } + }; + weight += contrib; + } + + for junction in &self.junctions { + let j_dx = block_x - junction.x; + let j_dy = block_y - junction.ground_y; + let j_dz = block_z - junction.z; + + weight += get_beard_contribution(j_dx, j_dy, j_dz, j_dy) * 0.4; + } + + weight + } +} + +impl MutableChunkNoiseFunctionComponentImpl for Beardifier { + fn sample( + &mut self, + _component_stack: &mut [ChunkNoiseFunctionComponent], + pos: &Vector3, + _sample_options: &ChunkNoiseFunctionSampleOptions, + ) -> f64 { + StaticIndependentChunkNoiseFunctionComponentImpl::sample(self, pos) + } +} + +impl NoiseFunctionComponentRange for Beardifier { + fn min(&self) -> f64 { + f64::NEG_INFINITY + } + + fn max(&self) -> f64 { + f64::INFINITY + } +} diff --git a/pumpkin-world/src/generation/noise/router/density_function/mod.rs b/pumpkin-world/src/generation/noise/router/density_function/mod.rs index 11bba0422..631acf821 100644 --- a/pumpkin-world/src/generation/noise/router/density_function/mod.rs +++ b/pumpkin-world/src/generation/noise/router/density_function/mod.rs @@ -7,6 +7,7 @@ use super::chunk_density_function::{ ChunkNoiseFunctionSampleOptions, ChunkSpecificNoiseFunctionComponent, }; +pub(crate) mod beardifier; pub(crate) mod math; pub(crate) mod misc; pub(crate) mod noise; diff --git a/pumpkin-world/src/generation/noise/router/find_top_surface.rs b/pumpkin-world/src/generation/noise/router/find_top_surface.rs index ab2e899f2..ced24a0b3 100644 --- a/pumpkin-world/src/generation/noise/router/find_top_surface.rs +++ b/pumpkin-world/src/generation/noise/router/find_top_surface.rs @@ -32,6 +32,21 @@ impl FindTopSurface { data, } } + + #[must_use] + pub fn density_index(&self) -> usize { + self.density_index + } + + #[must_use] + pub fn upper_bound_index(&self) -> usize { + self.upper_bound_index + } + + #[must_use] + pub fn cell_height(&self) -> i32 { + self.data.cell_height + } } impl NoiseFunctionComponentRange for FindTopSurface { @@ -59,6 +74,15 @@ impl StaticChunkNoiseFunctionComponentImpl for FindTopSurface { sample_options, ); + let density = ChunkNoiseFunctionComponent::sample_from_stack( + &mut component_stack[..=self.density_index], + &Vector3::new(pos.x, upper.floor() as i32, pos.z), + sample_options, + ); + if density > 0.0 { + return upper; + } + let cell_height = self.data.cell_height; let lower_bound = self.data.lower_bound; diff --git a/pumpkin-world/src/generation/noise/router/multi_noise_sampler.rs b/pumpkin-world/src/generation/noise/router/multi_noise_sampler.rs index 80f28ca1e..482b61409 100644 --- a/pumpkin-world/src/generation/noise/router/multi_noise_sampler.rs +++ b/pumpkin-world/src/generation/noise/router/multi_noise_sampler.rs @@ -136,6 +136,13 @@ impl<'a> MultiNoiseSampler<'a> { ProtoNoiseFunctionComponent::PassThrough(pass_through) => { ChunkNoiseFunctionComponent::PassThrough(pass_through.clone()) } + ProtoNoiseFunctionComponent::Beardifier(_) => ChunkNoiseFunctionComponent::Independent( + Box::leak(Box::new( + crate::generation::noise::router::proto_noise_router::IndependentProtoNoiseFunctionComponent::Constant( + crate::generation::noise::router::density_function::math::Constant::new(0.0), + ), + )), + ), ProtoNoiseFunctionComponent::Wrapper(wrapper) => { //NOTE: Due to our previous invariant with the proto-function, it is guaranteed // that the wrapped function is already on the stack diff --git a/pumpkin-world/src/generation/noise/router/proto_noise_router.rs b/pumpkin-world/src/generation/noise/router/proto_noise_router.rs index 0995c9d73..1628eadc3 100644 --- a/pumpkin-world/src/generation/noise/router/proto_noise_router.rs +++ b/pumpkin-world/src/generation/noise/router/proto_noise_router.rs @@ -21,6 +21,7 @@ use super::{ density_function::{ IndexToNoisePos, NoiseFunctionComponentRange, PassThrough, StaticIndependentChunkNoiseFunctionComponentImpl, Wrapper, + beardifier::Beardifier, math::{Binary, Clamp, Constant, Linear, Unary}, misc::{ClampedYGradient, EndIsland, RangeChoice, WeirdScaled}, noise::{InterpolatedNoiseSampler, Noise, ShiftA, ShiftB, ShiftedNoise}, @@ -62,6 +63,7 @@ pub enum ProtoNoiseFunctionComponent { Dependent(DependentProtoNoiseFunctionComponent), Wrapper(Wrapper), PassThrough(PassThrough), + Beardifier(Beardifier), } pub struct DoublePerlinNoiseBuilder; @@ -230,12 +232,9 @@ impl ProtoNoiseRouters { IndependentProtoNoiseFunctionComponent::Constant(Constant::new(0.0)), ) } - BaseNoiseFunctionComponent::Beardifier => { - // TODO: Replace this when world structures are implemented - ProtoNoiseFunctionComponent::Independent( - IndependentProtoNoiseFunctionComponent::Constant(Constant::new(0.0)), - ) - } + BaseNoiseFunctionComponent::Beardifier => ProtoNoiseFunctionComponent::Beardifier( + Beardifier::new(Vec::new(), Vec::new(), None), + ), BaseNoiseFunctionComponent::ShiftedNoise { shift_x_index, shift_y_index, diff --git a/pumpkin-world/src/generation/noise/router/surface_height_sampler.rs b/pumpkin-world/src/generation/noise/router/surface_height_sampler.rs index b29e93ea3..0e0ed5890 100644 --- a/pumpkin-world/src/generation/noise/router/surface_height_sampler.rs +++ b/pumpkin-world/src/generation/noise/router/surface_height_sampler.rs @@ -80,12 +80,66 @@ impl<'a> SurfaceHeightEstimateSampler<'a> { let sample_options = ChunkNoiseFunctionSampleOptions::new(false, SampleAction::SkipCellCaches, 0, 0, 0); let pos = Vector3::new(aligned_x, 0, aligned_z); + + // If the top-most component is FindTopSurface, we want to perform a precise search + // rather than the coarse cell-stepping search it does internally. + if let Some(ChunkNoiseFunctionComponent::Dependent( + crate::generation::noise::router::proto_noise_router::DependentProtoNoiseFunctionComponent::FindTopSurface(fts), + )) = self.component_stack.last() + { + let upper = ChunkNoiseFunctionComponent::sample_from_stack( + &mut self.component_stack[..=fts.upper_bound_index()], + &pos, + &sample_options, + ); + + let mut low = self.minimum_y; + let mut high = upper.ceil() as i32; + + // First find the coarse cell that contains the surface + let cell_height = fts.cell_height(); + let mut y = (upper / cell_height as f64).floor() as i32 * cell_height; + while y >= self.minimum_y { + let density = ChunkNoiseFunctionComponent::sample_from_stack( + &mut self.component_stack[..=fts.density_index()], + &Vector3::new(aligned_x, y, aligned_z), + &sample_options, + ); + if density > 0.0 { + low = y; + high = (y + cell_height).min(high); + break; + } + y -= cell_height; + } + + if y < self.minimum_y { + return self.minimum_y; + } + + // Binary search for precise surface + while high - low > 1 { + let mid = low + (high - low) / 2; + let density = ChunkNoiseFunctionComponent::sample_from_stack( + &mut self.component_stack[..=fts.density_index()], + &Vector3::new(aligned_x, mid, aligned_z), + &sample_options, + ); + if density > 0.0 { + low = mid; + } else { + high = mid; + } + } + return low + 1; + } + let surface_y = ChunkNoiseFunctionComponent::sample_from_stack( &mut self.component_stack, &pos, &sample_options, ); - surface_y.floor() as i32 + surface_y.floor() as i32 + 1 } #[must_use] @@ -109,6 +163,13 @@ impl<'a> SurfaceHeightEstimateSampler<'a> { ProtoNoiseFunctionComponent::PassThrough(pass_through) => { ChunkNoiseFunctionComponent::PassThrough(pass_through.clone()) } + ProtoNoiseFunctionComponent::Beardifier(_) => ChunkNoiseFunctionComponent::Independent( + Box::leak(Box::new( + crate::generation::noise::router::proto_noise_router::IndependentProtoNoiseFunctionComponent::Constant( + crate::generation::noise::router::density_function::math::Constant::new(0.0), + ), + )), + ), ProtoNoiseFunctionComponent::Wrapper(wrapper) => { //NOTE: Due to our previous invariant with the proto-function, it is guaranteed // that the wrapped function is already on the stack diff --git a/pumpkin-world/src/generation/proto_chunk.rs b/pumpkin-world/src/generation/proto_chunk.rs index be575ba13..7da1589aa 100644 --- a/pumpkin-world/src/generation/proto_chunk.rs +++ b/pumpkin-world/src/generation/proto_chunk.rs @@ -14,7 +14,7 @@ use pumpkin_util::random::xoroshiro128::XoroshiroSplitter; use pumpkin_util::random::{RandomImpl, get_carver_seed}; use pumpkin_util::{ HeightMap, - math::{position::BlockPos, vector3::Vector3}, + math::{block_box::BlockBox, position::BlockPos, vector3::Vector3}, random::{RandomGenerator, get_decorator_seed, xoroshiro128::Xoroshiro}, }; use rustc_hash::FxHashMap; @@ -124,58 +124,25 @@ impl FluidLevelSamplerImpl for StandardChunkFluidLevelSampler { } } -/// Vanilla Chunk Steps -/// -/// 1. empty: The chunk is not yet loaded or generated. -/// -/// 2. `structures_starts`: This step calculates the starting points for structure pieces. For structures that are the starting in this chunk, the position of all pieces are generated and stored. -/// -/// 3. `structures_references`: A reference to nearby chunks that have a structures' starting point are stored. -/// -/// 4. biomes: Biomes are determined and stored. No terrain is generated at this stage. -/// -/// 5. noise: The base terrain shape and liquid bodies are placed. -/// -/// 6. surface: The surface of the terrain is replaced with biome-dependent blocks. -/// -/// 7. carvers: Carvers carve certain parts of the terrain and replace solid blocks with air. -/// -/// 8. features: Features and structure pieces are placed and heightmaps are generated. -/// -/// 9. `initialize_light`: The lighting engine is initialized and light sources are identified. -/// -/// 10. light: The lighting engine calculates the light level for blocks. -/// -/// 11. spawn: Mobs are spawned. -/// -/// 12. full: Generation is done and a chunk can now be loaded. The proto-chunk is now converted to a level chunk and all block updates deferred in the above steps are executed. -/// pub struct ProtoChunk { pub x: i32, pub z: i32, pub default_block: &'static BlockState, biome_mixer_seed: i64, - // These are local positions flat_block_map: Box<[BlockStateId]>, pub flat_biome_map: Box<[u8]>, - /// HEIGHTMAPS - /// - /// Top block that is not air pub flat_surface_height_map: [i16; CHUNK_AREA], flat_ocean_floor_height_map: [i16; CHUNK_AREA], pub flat_motion_blocking_height_map: [i16; CHUNK_AREA], pub flat_motion_blocking_no_leaves_height_map: [i16; CHUNK_AREA], structure_starts: FxHashMap, - // Height of the chunk for indexing height: u16, bottom_y: i8, pub stage: StagedChunkEnum, pub light: ChunkLight, pub carving_mask: crate::generation::carver::mask::CarvingMask, pub blending_data: Option, - /// Block entities pending creation when the chunk is finalized. - /// These are created from structure templates during world generation. pub pending_block_entities: Vec, } @@ -237,18 +204,9 @@ impl ProtoChunk { stage: StagedChunkEnum::Empty, light: ChunkLight { sky_light: (0..section_count) - .map(|_| { - if dimension.has_skylight { - // Sky light starts at 0 and is calculated by the lighting engine - LightContainer::new_empty(0) - } else { - // No skylight in Nether/End - LightContainer::new_empty(0) - } - }) + .map(|_| LightContainer::new_empty(0)) .collect(), block_light: (0..section_count) - // Block light starts at 0 and is set by emissive blocks .map(|_| LightContainer::new_empty(0)) .collect(), }, @@ -260,6 +218,7 @@ impl ProtoChunk { pending_block_entities: Vec::new(), } } + #[must_use] pub fn from_chunk_data( chunk_data: &ChunkData, @@ -300,15 +259,12 @@ impl ProtoChunk { for y in 0..4 { for z in 0..4 { let biome_id = biome_palette.get(x, y, z); - let biome_y_idx = (section_idx * 4) + y; - let index = proto_chunk.local_biome_pos_to_biome_index( x as i32, biome_y_idx as i32, z as i32, ); - proto_chunk.flat_biome_map[index] = biome_id; } } @@ -346,6 +302,7 @@ impl ProtoChunk { proto_chunk.stage = StagedChunkEnum::from(chunk_data.status); proto_chunk } + #[inline] #[must_use] pub const fn stage_id(&self) -> u8 { @@ -362,14 +319,10 @@ impl ProtoChunk { self.bottom_y } - /// Adds a pending block entity to be created when the chunk is finalized. - /// - /// The NBT compound should include the block entity's position (x, y, z) and id fields. pub fn add_block_entity(&mut self, nbt: NbtCompound) { self.pending_block_entities.push(nbt); } - /// Takes all pending block entities, leaving an empty Vec. pub fn take_pending_block_entities(&mut self) -> Vec { std::mem::take(&mut self.pending_block_entities) } @@ -410,25 +363,19 @@ impl ProtoChunk { #[must_use] pub const fn top_block_height_exclusive(&self, x: i32, z: i32) -> i32 { - let local_x = x & 15; - let local_z = z & 15; - let index = Self::local_position_to_height_map_index(local_x, local_z); + let index = Self::local_position_to_height_map_index(x & 15, z & 15); self.flat_surface_height_map[index] as i32 + 1 } #[must_use] pub const fn ocean_floor_height_exclusive(&self, x: i32, z: i32) -> i32 { - let local_x = x & 15; - let local_z = z & 15; - let index = Self::local_position_to_height_map_index(local_x, local_z); + let index = Self::local_position_to_height_map_index(x & 15, z & 15); self.flat_ocean_floor_height_map[index] as i32 + 1 } #[must_use] pub const fn top_motion_blocking_block_height_exclusive(&self, x: i32, z: i32) -> i32 { - let local_x = x & 15; - let local_z = z & 15; - let index = Self::local_position_to_height_map_index(local_x, local_z); + let index = Self::local_position_to_height_map_index(x & 15, z & 15); self.flat_motion_blocking_height_map[index] as i32 + 1 } @@ -438,9 +385,7 @@ impl ProtoChunk { x: i32, z: i32, ) -> i32 { - let local_x = x & 15; - let local_z = z & 15; - let index = Self::local_position_to_height_map_index(local_x, local_z); + let index = Self::local_position_to_height_map_index(x & 15, z & 15); self.flat_motion_blocking_no_leaves_height_map[index] as i32 + 1 } @@ -451,10 +396,6 @@ impl ProtoChunk { #[inline] fn local_pos_to_block_index(&self, x: i32, y: i32, z: i32) -> usize { - debug_assert!((0..16).contains(&x), "x out of bounds: {x}"); - debug_assert!((0..16).contains(&z), "z out of bounds: {z}"); - debug_assert!(y >= 0 && y < self.height() as i32, "y out of bounds: {y}"); - self.height() as usize * CHUNK_DIM as usize * x as usize + CHUNK_DIM as usize * y as usize + z as usize @@ -464,14 +405,6 @@ impl ProtoChunk { #[must_use] pub fn local_biome_pos_to_biome_index(&self, x: i32, y: i32, z: i32) -> usize { let biome_height = self.height() as usize >> 2; - - debug_assert!((0..4).contains(&x), "Biome X out of bounds: {x}"); - debug_assert!((0..4).contains(&z), "Biome Z out of bounds: {z}"); - debug_assert!( - y >= 0 && y < biome_height as i32, - "Biome Y out of bounds: {y}" - ); - biome_height * biome_coords::from_block(CHUNK_DIM as i32) as usize * x as usize + biome_coords::from_block(CHUNK_DIM as i32) as usize * y as usize + z as usize @@ -583,6 +516,130 @@ impl ProtoChunk { FluidLevel::new(-54, &Block::LAVA), ); + let mut beardifier_structures = Vec::new(); + let mut beardifier_junctions = Vec::new(); + let mut any_piece_bounding_box: Option = None; + + let chunk_start_x = self.start_block_x(); + let chunk_start_z = self.start_block_z(); + + for (key, instance) in &self.structure_starts { + let structure = pumpkin_data::structures::Structure::get(key); + let terrain_adaptation = match structure.terrain_adaptation { + pumpkin_data::structures::TerrainAdaptation::None => { + crate::generation::noise::router::density_function::beardifier::TerrainAdaptation::None + } + pumpkin_data::structures::TerrainAdaptation::BeardThin => { + crate::generation::noise::router::density_function::beardifier::TerrainAdaptation::BeardThin + } + pumpkin_data::structures::TerrainAdaptation::BeardBox => { + crate::generation::noise::router::density_function::beardifier::TerrainAdaptation::BeardBox + } + pumpkin_data::structures::TerrainAdaptation::Bury => { + crate::generation::noise::router::density_function::beardifier::TerrainAdaptation::Bury + } + pumpkin_data::structures::TerrainAdaptation::Encapsulate => { + crate::generation::noise::router::density_function::beardifier::TerrainAdaptation::Encapsulate + } + }; + + // Vanilla strictly skips filtering Beardifier parts if adaptation is None early-on + if terrain_adaptation == crate::generation::noise::router::density_function::beardifier::TerrainAdaptation::None { + continue; + } + + let collector = match instance { + StructureInstance::Start(pos) => &pos.collector, + StructureInstance::Reference(collector) => collector, + }; + + let collector = collector.lock().unwrap(); + for piece in &collector.pieces { + let bounding_box = piece.get_structure_piece().bounding_box; + + // Match `piece.isCloseToChunk(chunkPos, 12)` + // Validates if an expansion 12 blocks out covers the chunk borders + if !bounding_box.intersects_raw_xz( + chunk_start_x - 12, + chunk_start_z - 12, + chunk_start_x + 15 + 12, + chunk_start_z + 15 + 12, + ) { + continue; + } + + let mut ground_level_delta = 0; + + if let Some(jigsaw_piece) = piece.as_any().downcast_ref::() { + // Java only adds to rigids if projection is RIGID + if jigsaw_piece.projection == crate::generation::structure::structures::jigsaw::JigsawProjection::Rigid { + ground_level_delta = jigsaw_piece.ground_level_delta; + any_piece_bounding_box = match any_piece_bounding_box { + Some(mut b) => { + b.encompass(&bounding_box); + Some(b) + } + None => Some(bounding_box), + }; + + beardifier_structures.push( + crate::generation::noise::router::density_function::beardifier::BeardifierStructure { + bounding_box, + terrain_adaptation, + ground_level_delta, + } + ); + } + + for j in &jigsaw_piece.junctions { + let j_x = j.source_x; + let j_z = j.source_z; + // Junction bounds filter (match vanilla proximity checks) + if j_x > chunk_start_x - 12 + && j_z > chunk_start_z - 12 + && j_x < chunk_start_x + 15 + 12 + && j_z < chunk_start_z + 15 + 12 + { + beardifier_junctions.push( + crate::generation::noise::router::density_function::beardifier::BeardifierJunction { + x: j_x, + ground_y: j.source_ground_y, + z: j_z, + } + ); + let junction_box = BlockBox::from_pos(BlockPos::new(j_x, j.source_ground_y, j_z)); + any_piece_bounding_box = match any_piece_bounding_box { + Some(mut b) => { + b.encompass(&junction_box); + Some(b) + } + None => Some(junction_box), + }; + } + } + } else { + any_piece_bounding_box = match any_piece_bounding_box { + Some(mut b) => { + b.encompass(&bounding_box); + Some(b) + } + None => Some(bounding_box), + }; + + beardifier_structures.push( + crate::generation::noise::router::density_function::beardifier::BeardifierStructure { + bounding_box, + terrain_adaptation, + ground_level_delta, + } + ); + } + } + } + + let affected_box = any_piece_bounding_box.map(|b| b.expand(24, 24, 24)); + + // Passed the newly mapped beardifier structures & junctions arrays independently! let mut noise_sampler = ChunkNoiseGenerator::new( &generator.base_router.noise, &generator.random_config, @@ -593,6 +650,9 @@ impl ProtoChunk { sampler, settings.aquifers_enabled, settings.ore_veins_enabled, + beardifier_structures, + beardifier_junctions, + affected_box, ); let horizontal_biome_end = biome_coords::from_block( @@ -622,7 +682,6 @@ impl ProtoChunk { pub fn step_to_surface(&mut self, generator: &super::generator::VanillaGenerator) { debug_assert_eq!(self.stage, StagedChunkEnum::Noise); - // Build surface let start_x = start_block_x(self.x); let start_z = start_block_z(self.z); let generation_shape = &generator.settings.shape; @@ -662,7 +721,6 @@ impl ProtoChunk { multi_noise_sampler: &mut MultiNoiseSampler, ) { let dimension = &generator.dimension; - // Instantiate ONLY the supplier we actually need let active_supplier = if dimension == &Dimension::THE_END { ActiveSupplier::End(TheEndBiomeSupplier) } else if dimension == &Dimension::THE_NETHER { @@ -670,7 +728,6 @@ impl ProtoChunk { } else { ActiveSupplier::Overworld(MultiNoiseBiomeSupplier::OVERWORLD) }; - // Extract the safe trait object reference let base_supplier: &dyn BiomeSupplier = match &active_supplier { ActiveSupplier::End(s) => s, ActiveSupplier::Nether(s) => s, @@ -733,7 +790,6 @@ impl ProtoChunk { let delta_y_step = 1.0 / v_count as f64; let delta_x_z_step = 1.0 / h_count as f64; - // TODO: Block state updates when we implement those noise_sampler.sample_start_density(); for cell_x in 0..horizontal_cells { noise_sampler.sample_end_density(cell_x); @@ -801,7 +857,6 @@ impl ProtoChunk { #[must_use] pub fn get_terrain_gen_biome_id(&self, x: i32, y: i32, z: i32) -> u8 { - // TODO: See if we can cache this value let seed_biome_pos = biome::get_biome_blend( self.bottom_y(), self.height(), @@ -819,10 +874,6 @@ impl ProtoChunk { Biome::from_id(self.get_terrain_gen_biome_id(x, y, z)).unwrap() } - /// Constructs the terrain surface, although "surface" is a misnomer as it also places underground blocks like bedrock and deepslate. - /// This stage also generates larger decorative structures, such as badlands pillars and icebergs. - /// - /// It is crucial that biome assignments are determined before this process begins. pub fn build_surface( &mut self, generator: &super::generator::VanillaGenerator, @@ -865,7 +916,6 @@ impl ProtoChunk { .terrain_builder .place_badlands_pillar(self, x, z, top_block); - // Get the top block again if we placed a pillar! top_block = self.top_block_height_exclusive(local_x, local_z); } @@ -902,7 +952,6 @@ impl ProtoChunk { .get_block_state(&Vector3::new(local_x, search_y, local_z)) .to_block_id(); - // TODO: Is there a better way to check that its not a fluid? if !(state != AIR_BLOCK && state != WATER_BLOCK && state != LAVA_BLOCK) { min = search_y + 1; @@ -911,11 +960,9 @@ impl ProtoChunk { } } - // let biome_pos = Vector3::new(x, biome_y as i32, z); stone_depth_above += 1; let stone_depth_below = y - min + 1; context.init_vertical(stone_depth_above, stone_depth_below, y, fluid_height); - // panic!("Blending with biome {:?} at: {:?}", biome, biome_pos); if state.id == self.default_block.id { context.biome = self.get_terrain_gen_biome( @@ -954,15 +1001,6 @@ impl ProtoChunk { } } - /// This generates "Structure Pieces" and "Features" also known as decorations, which include things like trees, grass, ores, and more. - /// Essentially, it encompasses everything above the surface or underground. It's crucial that this step is executed after biomes are generated, - /// as the decoration directly depends on the biome. Similarly, running this after the surface is built is logical, as it often involves checking block types. - /// For example, flowers are typically placed only on grass blocks. - /// - /// Features are defined across two separate asset files, each serving a distinct purpose: - /// - /// 1. First, we determine **whether** to generate a feature and **at which block positions** to place it. - /// 2. Then, using the second file, we determine **how** to generate the feature. pub fn generate_features_and_structure( cache: &mut T, block_registry: &dyn WorldPortalExt, @@ -970,7 +1008,7 @@ impl ProtoChunk { ) { let (center_x, center_z, min_y, height, biomes_in_chunk) = { let chunk = cache.get_center_chunk(); - let mut unique_biomes = Vec::with_capacity(4); // Usually few biomes per chunk + let mut unique_biomes = Vec::with_capacity(4); for &biome_id in &chunk.flat_biome_map { if !unique_biomes.contains(&biome_id) { unique_biomes.push(biome_id); @@ -993,7 +1031,13 @@ impl ProtoChunk { Xoroshiro::get_population_seed(random_config.seed, start_block_x, start_block_z); for step in 0..11 { - Self::generate_structure_step(cache, step, population_seed, random_config.seed as i64); + Self::generate_structure_step( + cache, + block_registry, + step, + population_seed, + random_config.seed as i64, + ); let mut features_to_run = Vec::new(); for biome_id in &biomes_in_chunk { @@ -1033,6 +1077,7 @@ impl ProtoChunk { fn generate_structure_step( cache: &mut T, + block_registry: &dyn WorldPortalExt, step: usize, population_seed: u64, world_seed: i64, @@ -1113,7 +1158,7 @@ impl ProtoChunk { let chunk = cache.get_center_chunk_mut(); for collector_arc in tasks { let mut collector = collector_arc.lock().unwrap(); - collector.generate_in_chunk(chunk, &mut random, world_seed); + collector.generate_in_chunk(chunk, block_registry, &mut random, world_seed); } } @@ -1144,6 +1189,18 @@ impl ProtoChunk { let seed = random_config.seed; + let mut height_sampler = crate::generation::noise::router::surface_height_sampler::SurfaceHeightEstimateSampler::generate( + &generator.base_router.surface_estimator, + &crate::generation::noise::router::surface_height_sampler::SurfaceHeightSamplerBuilderOptions::new( + crate::generation::biome_coords::from_block(crate::generation::positions::chunk_pos::start_block_x(self.x)), + crate::generation::biome_coords::from_block(crate::generation::positions::chunk_pos::start_block_z(self.z)), + 4, + settings.shape.min_y as i32, + settings.shape.height as i32, + (settings.shape.height / settings.shape.vertical_cell_block_count() as u16) as usize, + ), + ); + for (i, set) in StructureSet::ALL.iter().enumerate() { let allowed_biomes = &generator.structure_allowed_biomes[&i]; @@ -1161,7 +1218,12 @@ impl ProtoChunk { if set.structures.len() == 1 { if let Some(entry) = set.structures.first() { - self.try_set_structure_start(settings.sea_level, entry, random_config); + self.try_set_structure_start( + settings.sea_level, + entry, + random_config, + &mut height_sampler, + ); } continue; } @@ -1187,7 +1249,12 @@ impl ProtoChunk { let selected_entry = &candidates[selected_idx]; - if self.try_set_structure_start(settings.sea_level, selected_entry, random_config) { + if self.try_set_structure_start( + settings.sea_level, + selected_entry, + random_config, + &mut height_sampler, + ) { break; } @@ -1203,6 +1270,7 @@ impl ProtoChunk { sea_level: i32, entry: &WeightedEntry, random_config: &GlobalRandomConfig, + height_sampler: &mut crate::generation::noise::router::surface_height_sampler::SurfaceHeightEstimateSampler<'_>, ) -> bool { let structure = Structure::get(&entry.structure); let position = try_generate_structure( @@ -1211,6 +1279,7 @@ impl ProtoChunk { random_config.seed as i64, self, sea_level, + Some(height_sampler), ); if let Some(pos) = position { @@ -1236,7 +1305,6 @@ impl ProtoChunk { let seed = random_config.seed as i64; - // 1. Initialize mathematical biome tools (No DAG requirements!) let active_supplier = if *dimension == Dimension::THE_END { ActiveSupplier::End(TheEndBiomeSupplier) } else if *dimension == Dimension::THE_NETHER { @@ -1252,24 +1320,32 @@ impl ProtoChunk { }; let blender = Blender::empty(); let biome_supplier = blender.get_biome_supplier(base_supplier); - // Use an empty offset sampler since we are querying arbitrary world coordinates let multi_noise_config = MultiNoiseSamplerBuilderOptions::new(0, 0, 0); let mut multi_noise_sampler = MultiNoiseSampler::generate(&noise_router.multi_noise, &multi_noise_config); + let mut height_sampler = crate::generation::noise::router::surface_height_sampler::SurfaceHeightEstimateSampler::generate( + &noise_router.surface_estimator, + &crate::generation::noise::router::surface_height_sampler::SurfaceHeightSamplerBuilderOptions::new( + crate::generation::biome_coords::from_block(start_x), + crate::generation::biome_coords::from_block(start_z), + 4, + settings.shape.min_y as i32, + settings.shape.height as i32, + (settings.shape.height / settings.shape.vertical_cell_block_count() as u16) as usize, + ), + ); + let mut references = Vec::new(); - // 2. Iterate through all structures for set in StructureSet::ALL { let mut candidate_chunks = Vec::new(); - // 3. Collect Candidate Chunks based on Placement Type match &set.placement.placement_type { StructurePlacementType::RandomSpread(spread) => { let region_x = pumpkin_util::math::floor_div(self.x, spread.spacing); let region_z = pumpkin_util::math::floor_div(self.z, spread.spacing); - // Check the 3x3 region grid for rx in (region_x - 1)..=(region_x + 1) { for rz in (region_z - 1)..=(region_z + 1) { candidate_chunks.push( @@ -1293,7 +1369,6 @@ impl ProtoChunk { &allowed_biomes, ); for &(cx, cz) in strongholds { - // Quick heuristic filter to avoid evaluating far strongholds if (cx - self.x).abs() <= 8 && (cz - self.z).abs() <= 8 { candidate_chunks.push((cx, cz)); } @@ -1301,7 +1376,6 @@ impl ProtoChunk { } } - // 4. Process all gathered candidate chunks for (candidate_chunk_x, candidate_chunk_z) in candidate_chunks { if (candidate_chunk_x - self.x).abs() <= 8 && (candidate_chunk_z - self.z).abs() <= 8 @@ -1316,6 +1390,8 @@ impl ProtoChunk { random: create_chunk_random(seed, candidate_chunk_x, candidate_chunk_z), sea_level: settings.sea_level, min_y: self.bottom_y() as i32, + height_sampler: Some(&mut height_sampler), + structure_key: Some(entry.structure), }; if let Some(start_data) = lazily_generate_structure( @@ -1324,22 +1400,18 @@ impl ProtoChunk { context, &biome_supplier, &mut multi_noise_sampler, - ) { - // Bounding Box check - if start_data - .get_bounding_box() - .intersects_raw_xz(start_x, start_z, end_x, end_z) - { - references.push((entry.structure, start_data.collector.clone())); - break; - } + ) && start_data + .get_bounding_box() + .intersects_raw_xz(start_x, start_z, end_x, end_z) + { + references.push((entry.structure, start_data.collector.clone())); + break; } } } } } - // Apply the resolved references to this chunk for (key, pos) in references { self.structure_starts .entry(key) diff --git a/pumpkin-world/src/generation/proto_chunk_test.rs b/pumpkin-world/src/generation/proto_chunk_test.rs index 5c21f1ad1..50b0e7e51 100644 --- a/pumpkin-world/src/generation/proto_chunk_test.rs +++ b/pumpkin-world/src/generation/proto_chunk_test.rs @@ -33,18 +33,29 @@ mod test { macro_rules! set_wrappers { ($stack: expr) => { $stack.iter_mut().for_each(|component| { - if let ProtoNoiseFunctionComponent::Wrapper(wrapper) = component { - match wrapper.wrapper_type { - WrapperType::CellCache => (), - _ => { - *component = - ProtoNoiseFunctionComponent::PassThrough(PassThrough::new( - wrapper.input_index, - wrapper.min(), - wrapper.max(), - )); + match component { + ProtoNoiseFunctionComponent::Wrapper(wrapper) => { + match wrapper.wrapper_type { + WrapperType::CellCache => (), + _ => { + *component = ProtoNoiseFunctionComponent::PassThrough( + PassThrough::new( + wrapper.input_index, + wrapper.min(), + wrapper.max(), + ), + ); + } } } + ProtoNoiseFunctionComponent::Beardifier(_) => { + *component = ProtoNoiseFunctionComponent::Independent( + IndependentProtoNoiseFunctionComponent::Constant(Constant::new( + 0.0, + )), + ); + } + _ => (), } }); }; @@ -92,19 +103,30 @@ mod test { macro_rules! set_wrappers { ($stack: expr) => { $stack.iter_mut().for_each(|component| { - if let ProtoNoiseFunctionComponent::Wrapper(wrapper) = component { - match wrapper.wrapper_type { - WrapperType::CellCache => (), - WrapperType::Cache2D => (), - _ => { - *component = - ProtoNoiseFunctionComponent::PassThrough(PassThrough::new( - wrapper.input_index, - wrapper.min(), - wrapper.max(), - )); + match component { + ProtoNoiseFunctionComponent::Wrapper(wrapper) => { + match wrapper.wrapper_type { + WrapperType::CellCache => (), + WrapperType::Cache2D => (), + _ => { + *component = ProtoNoiseFunctionComponent::PassThrough( + PassThrough::new( + wrapper.input_index, + wrapper.min(), + wrapper.max(), + ), + ); + } } } + ProtoNoiseFunctionComponent::Beardifier(_) => { + *component = ProtoNoiseFunctionComponent::Independent( + IndependentProtoNoiseFunctionComponent::Constant(Constant::new( + 0.0, + )), + ); + } + _ => (), } }); }; @@ -152,19 +174,30 @@ mod test { macro_rules! set_wrappers { ($stack: expr) => { $stack.iter_mut().for_each(|component| { - if let ProtoNoiseFunctionComponent::Wrapper(wrapper) = component { - match wrapper.wrapper_type { - WrapperType::CellCache => (), - WrapperType::CacheFlat => (), - _ => { - *component = - ProtoNoiseFunctionComponent::PassThrough(PassThrough::new( - wrapper.input_index, - wrapper.min(), - wrapper.max(), - )); + match component { + ProtoNoiseFunctionComponent::Wrapper(wrapper) => { + match wrapper.wrapper_type { + WrapperType::CellCache => (), + WrapperType::CacheFlat => (), + _ => { + *component = ProtoNoiseFunctionComponent::PassThrough( + PassThrough::new( + wrapper.input_index, + wrapper.min(), + wrapper.max(), + ), + ); + } } } + ProtoNoiseFunctionComponent::Beardifier(_) => { + *component = ProtoNoiseFunctionComponent::Independent( + IndependentProtoNoiseFunctionComponent::Constant(Constant::new( + 0.0, + )), + ); + } + _ => (), } }); }; @@ -212,19 +245,30 @@ mod test { macro_rules! set_wrappers { ($stack: expr) => { $stack.iter_mut().for_each(|component| { - if let ProtoNoiseFunctionComponent::Wrapper(wrapper) = component { - match wrapper.wrapper_type { - WrapperType::CellCache => (), - WrapperType::CacheOnce => (), - _ => { - *component = - ProtoNoiseFunctionComponent::PassThrough(PassThrough::new( - wrapper.input_index, - wrapper.min(), - wrapper.max(), - )); + match component { + ProtoNoiseFunctionComponent::Wrapper(wrapper) => { + match wrapper.wrapper_type { + WrapperType::CellCache => (), + WrapperType::CacheOnce => (), + _ => { + *component = ProtoNoiseFunctionComponent::PassThrough( + PassThrough::new( + wrapper.input_index, + wrapper.min(), + wrapper.max(), + ), + ); + } } } + ProtoNoiseFunctionComponent::Beardifier(_) => { + *component = ProtoNoiseFunctionComponent::Independent( + IndependentProtoNoiseFunctionComponent::Constant(Constant::new( + 0.0, + )), + ); + } + _ => (), } }); }; @@ -272,19 +316,30 @@ mod test { macro_rules! set_wrappers { ($stack: expr) => { $stack.iter_mut().for_each(|component| { - if let ProtoNoiseFunctionComponent::Wrapper(wrapper) = component { - match wrapper.wrapper_type { - WrapperType::CellCache => (), - WrapperType::Interpolated => (), - _ => { - *component = - ProtoNoiseFunctionComponent::PassThrough(PassThrough::new( - wrapper.input_index, - wrapper.min(), - wrapper.max(), - )); + match component { + ProtoNoiseFunctionComponent::Wrapper(wrapper) => { + match wrapper.wrapper_type { + WrapperType::CellCache => (), + WrapperType::Interpolated => (), + _ => { + *component = ProtoNoiseFunctionComponent::PassThrough( + PassThrough::new( + wrapper.input_index, + wrapper.min(), + wrapper.max(), + ), + ); + } } } + ProtoNoiseFunctionComponent::Beardifier(_) => { + *component = ProtoNoiseFunctionComponent::Independent( + IndependentProtoNoiseFunctionComponent::Constant(Constant::new( + 0.0, + )), + ); + } + _ => (), } }); }; diff --git a/pumpkin-world/src/generation/structure/mod.rs b/pumpkin-world/src/generation/structure/mod.rs index 97ea31359..4fc9c66c6 100644 --- a/pumpkin-world/src/generation/structure/mod.rs +++ b/pumpkin-world/src/generation/structure/mod.rs @@ -12,7 +12,7 @@ use crate::{ structure::structures::{ StructureGenerator, StructureGeneratorContext, StructurePosition, buried_treasure::BuriedTreasureGenerator, create_chunk_random, - desert_pyramid::DesertPyramidGenerator, igloo::IglooGenerator, + desert_pyramid::DesertPyramidGenerator, igloo::IglooGenerator, jigsaw::JigsawGenerator, jungle_temple::JungleTempleGenerator, nether_fortress::NetherFortressGenerator, nether_fossil::NetherFossilGenerator, stronghold::StrongholdGenerator, swamp_hut::SwampHutGenerator, @@ -33,6 +33,7 @@ pub fn try_generate_structure( seed: i64, chunk: &ProtoChunk, sea_level: i32, + height_sampler: Option<&mut dyn crate::generation::structure::structures::HeightSampler>, ) -> Option { let random = create_chunk_random(seed, chunk.x, chunk.z); let context = StructureGeneratorContext { @@ -42,6 +43,8 @@ pub fn try_generate_structure( random, sea_level, min_y: chunk.bottom_y() as i32, + height_sampler, + structure_key: Some(*key), }; let structure_pos = match key { StructureKeys::BuriedTreasure => { @@ -62,6 +65,32 @@ pub fn try_generate_structure( StructureKeys::Igloo => IglooGenerator::get_structure_position(&IglooGenerator, context), StructureKeys::DesertPyramid => DesertPyramidGenerator.get_structure_position(context), StructureKeys::JunglePyramid => JungleTempleGenerator.get_structure_position(context), + StructureKeys::VillagePlains + | StructureKeys::VillageDesert + | StructureKeys::VillageSavanna + | StructureKeys::VillageSnowy + | StructureKeys::VillageTaiga => { + let generator = JigsawGenerator::new( + structure + .start_pool + .expect("Jigsaw structure must have a start pool"), + structure.size.expect("Jigsaw structure must have a size"), + ); + generator.get_structure_position(context) + } + StructureKeys::AncientCity + | StructureKeys::BastionRemnant + | StructureKeys::PillagerOutpost + | StructureKeys::TrailRuins + | StructureKeys::TrialChambers => { + let generator = JigsawGenerator::new( + structure + .start_pool + .expect("Jigsaw structure must have a start pool"), + structure.size.expect("Jigsaw structure must have a size"), + ); + generator.get_structure_position(context) + } // TODO: Implement other structure types _ => None, }; @@ -127,6 +156,24 @@ pub fn lazily_generate_structure( StructureKeys::Igloo => IglooGenerator::get_structure_position(&IglooGenerator, context), StructureKeys::DesertPyramid => DesertPyramidGenerator.get_structure_position(context), StructureKeys::JunglePyramid => JungleTempleGenerator.get_structure_position(context), + StructureKeys::VillagePlains + | StructureKeys::VillageDesert + | StructureKeys::VillageSavanna + | StructureKeys::VillageSnowy + | StructureKeys::VillageTaiga + | StructureKeys::AncientCity + | StructureKeys::BastionRemnant + | StructureKeys::PillagerOutpost + | StructureKeys::TrailRuins + | StructureKeys::TrialChambers => { + let generator = JigsawGenerator::new( + structure + .start_pool + .expect("Jigsaw structure must have a start pool"), + structure.size.expect("Jigsaw structure must have a size"), + ); + generator.get_structure_position(context) + } // TODO: Implement other structure types _ => None, }; diff --git a/pumpkin-world/src/generation/structure/structures/buried_treasure.rs b/pumpkin-world/src/generation/structure/structures/buried_treasure.rs index b6b7e74fb..aa69e5218 100644 --- a/pumpkin-world/src/generation/structure/structures/buried_treasure.rs +++ b/pumpkin-world/src/generation/structure/structures/buried_treasure.rs @@ -15,7 +15,7 @@ use crate::{ piece::StructurePieceType, structures::{ StructureGenerator, StructureGeneratorContext, StructurePiece, StructurePieceBase, - StructurePiecesCollector, StructurePosition, + StructurePiecesCollector, StructurePosition, WorldPortalExt, }, }, }, @@ -26,7 +26,7 @@ pub struct BuriedTreasureGenerator; impl StructureGenerator for BuriedTreasureGenerator { fn get_structure_position( &self, - context: StructureGeneratorContext, + context: StructureGeneratorContext<'_>, ) -> Option { let x = get_center_x(context.chunk_x); let z = get_center_z(context.chunk_z); @@ -51,9 +51,13 @@ pub struct BuriedTreasurePiece { } impl StructurePieceBase for BuriedTreasurePiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, _random: &mut RandomGenerator, _seed: i64, _chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/desert_pyramid.rs b/pumpkin-world/src/generation/structure/structures/desert_pyramid.rs index 07b820223..c137d1d5f 100644 --- a/pumpkin-world/src/generation/structure/structures/desert_pyramid.rs +++ b/pumpkin-world/src/generation/structure/structures/desert_pyramid.rs @@ -34,7 +34,7 @@ pub struct DesertPyramidGenerator; impl StructureGenerator for DesertPyramidGenerator { fn get_structure_position( &self, - mut context: StructureGeneratorContext, + mut context: StructureGeneratorContext<'_>, ) -> Option { let x = start_block_x(context.chunk_x); let z = start_block_z(context.chunk_z); @@ -445,6 +445,9 @@ impl DesertPyramidPiece { } impl StructurePieceBase for DesertPyramidPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece } @@ -457,6 +460,7 @@ impl StructurePieceBase for DesertPyramidPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn crate::world::WorldPortalExt, random: &mut RandomGenerator, seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/igloo.rs b/pumpkin-world/src/generation/structure/structures/igloo.rs index c93e014f9..a71dc9a8a 100644 --- a/pumpkin-world/src/generation/structure/structures/igloo.rs +++ b/pumpkin-world/src/generation/structure/structures/igloo.rs @@ -8,6 +8,7 @@ use std::sync::Arc; +use pumpkin_data::block_rotation::Rotation; use pumpkin_util::{ math::{block_box::BlockBox, position::BlockPos, vector3::Vector3}, random::RandomGenerator, @@ -23,9 +24,9 @@ use crate::{ shiftable_piece::ShiftableStructurePiece, structures::{ StructureGenerator, StructureGeneratorContext, StructurePiece, StructurePieceBase, - StructurePiecesCollector, StructurePosition, + StructurePiecesCollector, StructurePosition, WorldPortalExt, }, - template::{BlockRotation, StructureTemplate, get_template, place_template}, + template::{StructureTemplate, get_template, place_template}, }, }, }; @@ -63,7 +64,7 @@ pub struct IglooGenerator; impl StructureGenerator for IglooGenerator { fn get_structure_position( &self, - mut context: StructureGeneratorContext, + mut context: StructureGeneratorContext<'_>, ) -> Option { let chunk_center_x = get_center_x(context.chunk_x); let chunk_center_z = get_center_z(context.chunk_z); @@ -75,7 +76,7 @@ impl StructureGenerator for IglooGenerator { // IMPORTANT: Random call order must match vanilla for deterministic placement: // 1. Rotation first (vanilla: BlockRotation.random(random) calls nextInt(4)) let rotation_index = context.random.next_bounded_i32(4) as u8; - let rotation = BlockRotation::from_index(rotation_index); + let rotation = Rotation::from_index(rotation_index); // 2. Basement check (vanilla: random.nextDouble() < 0.5) let has_basement = context.random.next_f64() < 0.5; @@ -134,15 +135,19 @@ pub struct IglooPiece { top_template: Arc, middle_template: Option>, bottom_template: Option>, - rotation: BlockRotation, + rotation: Rotation, has_basement: bool, ladder_segments: u8, } impl StructurePieceBase for IglooPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, _random: &mut RandomGenerator, _seed: i64, _chunk_box: &BlockBox, @@ -173,6 +178,8 @@ impl StructurePieceBase for IglooPiece { (0, 0), self.rotation, false, + &[], + Some(_chunk_box), ); // Place basement components if present @@ -202,6 +209,8 @@ impl StructurePieceBase for IglooPiece { (SHAFT_OFFSET_X, SHAFT_OFFSET_Z), self.rotation, false, + &[], + Some(_chunk_box), ); } } @@ -218,6 +227,8 @@ impl StructurePieceBase for IglooPiece { (BASEMENT_OFFSET_X, BASEMENT_OFFSET_Z), self.rotation, false, + &[], + Some(_chunk_box), ); } } diff --git a/pumpkin-world/src/generation/structure/structures/jigsaw.rs b/pumpkin-world/src/generation/structure/structures/jigsaw.rs new file mode 100644 index 000000000..b4fd4e286 --- /dev/null +++ b/pumpkin-world/src/generation/structure/structures/jigsaw.rs @@ -0,0 +1,369 @@ +use super::jigsaw_placement::{ + DimensionPadding, JigsawPlacement, LiquidSettings, MaxDistance, PoolAliasLookup, +}; +use crate::generation::structure::structures::{ + StructureGenerator, StructureGeneratorContext, StructurePieceBase, StructurePosition, +}; +use crate::generation::structure::template::{ + BlockMirror, BlockRotation, BlockStateResolver, PaletteEntry, StructureTemplate, +}; +use pumpkin_util::math::position::BlockPos; +use pumpkin_util::random::RandomImpl; +use std::sync::Arc; + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub enum JigsawProjection { + Rigid, + TerrainMatching, +} + +#[derive(Clone)] +pub struct TemplatePool { + pub id: String, + pub fallback: String, + pub elements: Vec, +} + +#[derive(Clone)] +pub struct PoolElement { + pub template: &'static str, + pub weight: u32, + pub projection: JigsawProjection, +} + +impl TemplatePool { + pub fn get_random_element( + &self, + random: &mut pumpkin_util::random::RandomGenerator, + ) -> &PoolElement { + let total_weight: u32 = self.elements.iter().map(|e| e.weight).sum(); + if total_weight == 0 { + return &self.elements[0]; + } + let mut r = random.next_bounded_i32(total_weight as i32) as u32; + for element in &self.elements { + if r < element.weight { + return element; + } + r -= element.weight; + } + &self.elements[0] + } + + /// Discovers a pool from the filesystem/embedded assets. + pub fn discover(id: &str) -> Option { + let elements = crate::generation::structure::template::get_pool_elements(id)?; + + // Heuristic: roads and streets are usually TerrainMatching + let projection = if id.contains("streets") { + JigsawProjection::TerrainMatching + } else { + JigsawProjection::Rigid + }; + + Some(Self { + id: id.to_string(), + fallback: "minecraft:empty".to_string(), + elements: elements + .iter() + .map(|e| PoolElement { + template: e, + weight: 1, + projection, + }) + .collect(), + }) + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub enum JigsawJointType { + Rollable, + Aligned, +} + +impl JigsawJointType { + #[allow(clippy::should_implement_trait)] + pub fn from_str(s: &str) -> Self { + match s { + "aligned" => Self::Aligned, + _ => Self::Rollable, + } + } +} + +#[derive(Clone)] +pub struct JigsawBlock { + pub pos: BlockPos, + pub name: String, + pub target: String, + pub pool: String, + pub final_state: String, + pub joint: JigsawJointType, + pub facing: pumpkin_util::BlockDirection, + pub up: pumpkin_util::BlockDirection, + pub selection_priority: i32, + pub placement_priority: i32, +} + +impl JigsawBlock { + pub fn from_template_block( + block: &crate::generation::structure::template::TemplateBlock, + palette: &PaletteEntry, + ) -> Option { + if palette.name != "minecraft:jigsaw" { + return None; + } + + let nbt = block.nbt.as_ref()?; + + // Resolve facing from properties + let facing_str = palette + .properties + .iter() + .find(|(k, _)| *k == "orientation") + .map(|(_, v)| v.clone()) + .unwrap_or_else(|| "north_up".to_string()); + + let mut parts = facing_str.split('_'); + let facing_part = parts.next().unwrap_or("north"); + let up_part = parts.next().unwrap_or("up"); + + let facing = match facing_part { + "north" => pumpkin_util::BlockDirection::North, + "south" => pumpkin_util::BlockDirection::South, + "east" => pumpkin_util::BlockDirection::East, + "west" => pumpkin_util::BlockDirection::West, + "up" => pumpkin_util::BlockDirection::Up, + "down" => pumpkin_util::BlockDirection::Down, + _ => pumpkin_util::BlockDirection::North, + }; + + let up = match up_part { + "north" => pumpkin_util::BlockDirection::North, + "south" => pumpkin_util::BlockDirection::South, + "east" => pumpkin_util::BlockDirection::East, + "west" => pumpkin_util::BlockDirection::West, + "up" => pumpkin_util::BlockDirection::Up, + "down" => pumpkin_util::BlockDirection::Down, + _ => pumpkin_util::BlockDirection::Up, + }; + + Some(Self { + pos: BlockPos(block.pos), + name: nbt.get_string("name").unwrap_or_default().to_string(), + target: nbt.get_string("target").unwrap_or_default().to_string(), + pool: nbt.get_string("pool").unwrap_or_default().to_string(), + final_state: nbt + .get_string("final_state") + .unwrap_or_default() + .to_string(), + joint: JigsawJointType::from_str(nbt.get_string("joint").unwrap_or_default()), + facing, + up, + selection_priority: nbt.get_int("selection_priority").unwrap_or(0), + placement_priority: nbt.get_int("placement_priority").unwrap_or(0), + }) + } + + pub fn can_attach( + source: &Self, + target_facing: pumpkin_util::BlockDirection, + target_name: &str, + ) -> bool { + source.facing.opposite() == target_facing && source.target == target_name + } +} + +#[derive(Clone)] +pub struct JigsawJunction { + pub source_x: i32, + pub source_ground_y: i32, + pub source_z: i32, + pub delta_y: i32, + pub projection: JigsawProjection, +} + +pub struct PoolElementStructurePiece { + pub piece: crate::generation::structure::structures::StructurePiece, + pub template: Arc, + pub pos: BlockPos, + pub rotation: BlockRotation, + pub mirror: BlockMirror, + pub jigsaw_blocks: Vec, + pub junctions: Vec, + pub ground_level_delta: i32, + pub liquid_settings: LiquidSettings, + pub projection: JigsawProjection, +} + +impl StructurePieceBase for PoolElementStructurePiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } + fn get_structure_piece(&self) -> &crate::generation::structure::structures::StructurePiece { + &self.piece + } + + fn get_structure_piece_mut( + &mut self, + ) -> &mut crate::generation::structure::structures::StructurePiece { + &mut self.piece + } + + fn place( + &mut self, + chunk: &mut crate::ProtoChunk, + _block_registry: &dyn crate::world::WorldPortalExt, + _random: &mut pumpkin_util::random::RandomGenerator, + _seed: i64, + _chunk_box: &pumpkin_util::math::block_box::BlockBox, + ) { + let origin = + pumpkin_util::math::vector3::Vector3::new(self.pos.0.x, self.pos.0.y, self.pos.0.z); + + let processors: Vec> = + vec![Box::new( + crate::generation::structure::template::processor::GravityProcessor { + heightmap: pumpkin_util::HeightMap::WorldSurfaceWg, + offset: -1, + }, + )]; + + crate::generation::structure::template::place_template( + chunk, + &self.template, + origin, + (0, 0), + self.rotation, + false, + &processors, + Some(_chunk_box), + ); + + // Post-process: replace jigsaw blocks with their final_state + for jigsaw in &self.jigsaw_blocks { + let wx = jigsaw.pos.0.x; + let wy = jigsaw.pos.0.y; + let wz = jigsaw.pos.0.z; + if wx < _chunk_box.min.x + || wx > _chunk_box.max.x + || wy < _chunk_box.min.y + || wy > _chunk_box.max.y + || wz < _chunk_box.min.z + || wz > _chunk_box.max.z + { + continue; + } + if jigsaw.final_state == "minecraft:air" || jigsaw.final_state == "air" { + chunk.set_block_state(wx, wy, wz, pumpkin_data::Block::AIR.default_state); + continue; + } + + let entry = PaletteEntry::from_string(&jigsaw.final_state); + if let Some(state) = BlockStateResolver::resolve(&entry, self.rotation, self.mirror) { + chunk.set_block_state(wx, wy, wz, state); + } + } + } +} + +impl PoolElementStructurePiece { + pub fn add_junction(&mut self, junction: JigsawJunction) { + self.junctions.push(junction); + } +} + +pub struct JigsawGenerator { + pub start_pool: String, + pub size: i32, + pub start_jigsaw_name: Option, + pub use_expansion_hack: bool, +} + +impl JigsawGenerator { + pub fn new(start_pool: &str, size: i32) -> Self { + Self { + start_pool: start_pool.to_string(), + size, + start_jigsaw_name: None, + use_expansion_hack: false, + } + } + + pub fn with_start_jigsaw(mut self, name: &str) -> Self { + self.start_jigsaw_name = Some(name.to_string()); + self + } + + pub fn with_expansion_hack(mut self, use_hack: bool) -> Self { + self.use_expansion_hack = use_hack; + self + } +} + +impl StructureGenerator for JigsawGenerator { + fn get_structure_position( + &self, + context: StructureGeneratorContext<'_>, + ) -> Option { + let mut context = context; + let structure = context + .structure_key + .map(|key| pumpkin_data::structures::Structure::get(&key)); + + let start_y = if let Some(s) = structure { + s.start_height.unwrap_or(context.sea_level as i16) as i32 + } else { + context.sea_level + }; + + let start_pos = BlockPos::new( + crate::generation::positions::chunk_pos::start_block_x(context.chunk_x), + start_y, + crate::generation::positions::chunk_pos::start_block_z(context.chunk_z), + ); + + let project_start_to_heightmap = structure + .and_then(|s| s.project_start_to_heightmap) + .is_some(); + + let max_distance = structure + .and_then(|s| s.max_distance_from_center) + .unwrap_or(80); // Vanilla default is 80 + + let liquid_settings = structure + .and_then(|s| s.liquid_settings) + .map(|ls| match ls { + "apply_waterlogging" => LiquidSettings::ApplyWaterlog, + "ignore_waterlogging" => LiquidSettings::IgnoreWaterlogDone, + _ => LiquidSettings::ApplyWaterlog, + }) + .unwrap_or(LiquidSettings::ApplyWaterlog); + + let dimension_padding = structure + .and_then(|s| s.dimension_padding) + .map(|dp| DimensionPadding { + top: dp, + bottom: dp, + }) + .unwrap_or(DimensionPadding::ZERO); + + JigsawPlacement::add_pieces( + &mut context, + &self.start_pool, + self.start_jigsaw_name.as_deref(), + self.size, + start_pos, + self.use_expansion_hack, + project_start_to_heightmap, + MaxDistance { + horizontal: max_distance, + vertical: max_distance, + }, + dimension_padding, + liquid_settings, + &PoolAliasLookup, + ) + } +} diff --git a/pumpkin-world/src/generation/structure/structures/jigsaw_placement.rs b/pumpkin-world/src/generation/structure/structures/jigsaw_placement.rs new file mode 100644 index 000000000..e86868228 --- /dev/null +++ b/pumpkin-world/src/generation/structure/structures/jigsaw_placement.rs @@ -0,0 +1,675 @@ +use pumpkin_data::{Mirror, Rotation}; + +use crate::generation::structure::{ + structures::{StructureGeneratorContext, StructurePosition}, + template::{StructureTemplate, get_template}, +}; +use pumpkin_util::math::block_box::BlockBox; +use pumpkin_util::math::position::BlockPos; +use pumpkin_util::random::RandomImpl; +use std::collections::BinaryHeap; +use std::sync::Arc; + +use super::jigsaw::{ + JigsawBlock, JigsawJointType, JigsawJunction, JigsawProjection, PoolElementStructurePiece, + TemplatePool, +}; + +pub struct JigsawPlacement; + +pub struct DimensionPadding { + pub top: i32, + pub bottom: i32, +} + +impl DimensionPadding { + pub const ZERO: Self = Self { top: 0, bottom: 0 }; +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub enum LiquidSettings { + IgnoreWaterlogDone, + ApplyWaterlog, +} + +pub struct MaxDistance { + pub horizontal: i32, + pub vertical: i32, +} + +impl MaxDistance { + pub fn new(horizontal: i32) -> Self { + Self { + horizontal, + vertical: 384, // Default Y_SIZE (min_y to max_y) + } + } +} + +pub const MAX_TOTAL_STRUCTURE_RANGE: i32 = 128; +pub const MIN_DEPTH: i32 = 0; +pub const MAX_DEPTH: i32 = 20; + +/// Simple lookup for Pool Aliases introduced in 1.20+ +pub struct PoolAliasLookup; + +impl PoolAliasLookup { + pub fn lookup<'a>(&self, id: &'a str) -> &'a str { + // In a complete implementation, this would look up the alias in the context/registry. + // Returning the ID directly acts as a fallback/default behavior. + id + } +} + +impl JigsawPlacement { + #[expect(clippy::too_many_arguments)] + pub fn add_pieces( + context: &mut StructureGeneratorContext, + start_pool_id: &str, + start_jigsaw: Option<&str>, + max_depth: i32, + position: BlockPos, + do_expansion_hack: bool, + project_start_to_heightmap: bool, + max_distance_from_center: MaxDistance, + dimension_padding: DimensionPadding, + liquid_settings: LiquidSettings, + pool_alias_lookup: &PoolAliasLookup, + ) -> Option { + if max_distance_from_center.horizontal > MAX_TOTAL_STRUCTURE_RANGE { + return None; + } + + let max_depth = max_depth.clamp(MIN_DEPTH, MAX_DEPTH); + + let actual_start_pool_id = pool_alias_lookup.lookup(start_pool_id); + let pool = TemplatePool::discover(actual_start_pool_id)?; + let element = pool.get_random_element(&mut context.random); + let template = get_template(element.template)?; + + let rotation = Rotation::from_index(context.random.next_bounded_i32(4) as u8); + + let mut anchored_position = position; + if let Some(target_jigsaw_id) = start_jigsaw { + let mut found_anchor = None; + let jigsaws = get_jigsaw_blocks(&template); + for jigsaw in jigsaws { + if jigsaw.name == target_jigsaw_id { + let rotated_pos = rotation.transform_pos(jigsaw.pos.0, template.size); + found_anchor = Some(position.add(rotated_pos.x, rotated_pos.y, rotated_pos.z)); + break; + } + } + + if let Some(anchor) = found_anchor { + anchored_position = anchor; + } else { + return None; + } + } + + let local_anchor_position = anchored_position.0.sub(&position.0); + let adjusted_position = BlockPos(position.0.sub(&local_anchor_position)); + + let rotated_size = rotation.transform_size(template.size); + let mut box_ = BlockBox::new( + adjusted_position.0.x, + adjusted_position.0.y, + adjusted_position.0.z, + adjusted_position.0.x + rotated_size.x - 1, + adjusted_position.0.y + rotated_size.y - 1, + adjusted_position.0.z + rotated_size.z - 1, + ); + + let center_x = (box_.max.x + box_.min.x) / 2; + let center_z = (box_.max.z + box_.min.z) / 2; + + let bottom_y = if project_start_to_heightmap { + if let Some(sampler) = &mut context.height_sampler { + sampler + .estimate_height(center_x, center_z) + .max(context.sea_level) + } else { + adjusted_position.0.y + } + } else { + adjusted_position.0.y + }; + + let old_min_y = box_.min.y; + box_.move_pos(0, bottom_y - old_min_y, 0); + + if box_.min.y < context.min_y + dimension_padding.bottom + || box_.max.y > context.min_y + 320 - dimension_padding.top + { + return None; + } + + let center_y = bottom_y + local_anchor_position.y; + + let global_bounding_box = BlockBox::new( + center_x - max_distance_from_center.horizontal, + (center_y - max_distance_from_center.vertical) + .max(context.min_y + dimension_padding.bottom), + center_z - max_distance_from_center.horizontal, + center_x + max_distance_from_center.horizontal + 1, + (center_y + max_distance_from_center.vertical + 1) + .min(context.min_y + 320 - dimension_padding.top), + center_z + max_distance_from_center.horizontal + 1, + ); + + let mut jigsaw_blocks = Vec::new(); + for block in &template.blocks { + if let Some(mut jigsaw) = + JigsawBlock::from_template_block(block, &template.palette[block.state as usize]) + { + let rotated_pos = rotation.transform_pos(jigsaw.pos.0, template.size); + jigsaw.pos = BlockPos(rotated_pos).add( + adjusted_position.0.x, + bottom_y, + adjusted_position.0.z, + ); + jigsaw.facing = rotate_direction(jigsaw.facing, rotation); + jigsaw.up = rotate_direction(jigsaw.up, rotation); + jigsaw_blocks.push(jigsaw); + } + } + + let first_piece = Box::new(PoolElementStructurePiece { + piece: crate::generation::structure::structures::StructurePiece::new( + crate::generation::structure::piece::StructurePieceType::Jigsaw, + box_, + 0, + ), + template: Arc::clone(&template), + pos: BlockPos::new(adjusted_position.0.x, bottom_y, adjusted_position.0.z), + rotation, + mirror: Mirror::None, + jigsaw_blocks, + junctions: Vec::new(), + ground_level_delta: 0, + liquid_settings, + projection: element.projection, + }); + + let mut collector = super::StructurePiecesCollector::new(); + let mut pieces = Vec::new(); + let mut piece_projections = Vec::new(); + + pieces.push(first_piece); + piece_projections.push(element.projection); + + if max_depth > 0 { + let mut placing = BinaryHeap::new(); + let mut sequence = 0; + + placing.push(PieceState { + piece_idx: 0, + depth: 0, + priority: 0, + sequence, + }); + + while let Some(state) = placing.pop() { + let depth = state.depth; + + let source_piece_idx = state.piece_idx; + let mut source_jigsaws = + std::mem::take(&mut pieces[source_piece_idx].jigsaw_blocks); + + for i in (1..source_jigsaws.len()).rev() { + let j = context.random.next_bounded_i32(i as i32 + 1) as usize; + source_jigsaws.swap(i, j); + } + source_jigsaws.sort_by_key(|j| std::cmp::Reverse(j.selection_priority)); + + let source_box = pieces[source_piece_idx].piece.bounding_box; + let source_projection = piece_projections[source_piece_idx]; + let source_rigid = source_projection == JigsawProjection::Rigid; + + 'jigsaw_loop: for source_jigsaw in source_jigsaws.iter() { + let raw_pool_id = &source_jigsaw.pool; + if raw_pool_id == "minecraft:empty" || raw_pool_id.is_empty() { + continue; + } + + let target_pool_id = pool_alias_lookup.lookup(raw_pool_id); + let target_pool = match TemplatePool::discover(target_pool_id) { + Some(p) => p, + None => continue, + }; + + let mut target_elements = Vec::new(); + if depth < max_depth { + let mut main_elements = target_pool.elements.clone(); + for i in (1..main_elements.len()).rev() { + let j = context.random.next_bounded_i32(i as i32 + 1) as usize; + main_elements.swap(i, j); + } + target_elements.extend(main_elements); + } + + let fallback_pool_id = pool_alias_lookup.lookup(&target_pool.fallback); + if let Some(fallback_pool) = TemplatePool::discover(fallback_pool_id) { + let mut fallback_elements = fallback_pool.elements.clone(); + for i in (1..fallback_elements.len()).rev() { + let j = context.random.next_bounded_i32(i as i32 + 1) as usize; + fallback_elements.swap(i, j); + } + target_elements.extend(fallback_elements); + } + + for element in target_elements { + if element.template == "minecraft:empty" { + break; + } + + let target_template_arc = match get_template(element.template) { + Some(t) => t, + None => continue, + }; + let target_template = target_template_arc.as_ref(); + let target_projection = element.projection; + let target_rigid = target_projection == JigsawProjection::Rigid; + + let mut rotations = [ + Rotation::None, + Rotation::Clockwise90, + Rotation::Rotate180, + Rotation::CounterClockwise90, + ]; + + for i in (1..4).rev() { + let j = context.random.next_bounded_i32(i as i32 + 1) as usize; + rotations.swap(i, j); + } + + for target_rotation in rotations { + let target_jigsaws = get_jigsaw_blocks(target_template); + + let mut target_jigsaws_shuffled = target_jigsaws.clone(); + for i in (1..target_jigsaws_shuffled.len()).rev() { + let j = context.random.next_bounded_i32(i as i32 + 1) as usize; + target_jigsaws_shuffled.swap(i, j); + } + + for target_jigsaw in target_jigsaws_shuffled { + if !can_attach(source_jigsaw, &target_jigsaw, target_rotation) { + continue; + } + + let source_facing = source_jigsaw.facing; + let source_jigsaw_pos = source_jigsaw.pos; + let target_jigsaw_pos = source_jigsaw_pos.add( + source_facing.to_vector().x, + source_facing.to_vector().y, + source_facing.to_vector().z, + ); + + let source_jigsaw_local_y = + source_jigsaw_pos.0.y - source_box.min.y; + let target_jigsaw_local_pos = target_rotation + .transform_pos(target_jigsaw.pos.0, target_template.size); + let target_jigsaw_local_y = target_jigsaw_local_pos.y; + + let delta_y = source_jigsaw_local_y - target_jigsaw_local_y + + source_facing.to_vector().y; + + let target_box_y; + let mut source_jigsaw_base_height = i32::MIN; + + if source_rigid && target_rigid { + target_box_y = source_box.min.y + delta_y; + } else { + if source_jigsaw_base_height == i32::MIN { + source_jigsaw_base_height = + if let Some(sampler) = &mut context.height_sampler { + let height = sampler.estimate_height( + source_jigsaw_pos.0.x, + source_jigsaw_pos.0.z, + ); + if project_start_to_heightmap { + height.max(context.sea_level) + } else { + height + } + } else { + source_jigsaw_pos.0.y + }; + } + target_box_y = + source_jigsaw_base_height - target_jigsaw_local_y; + } + + let raw_target_pos = BlockPos::new( + target_jigsaw_pos.0.x - target_jigsaw_local_pos.x, + target_jigsaw_pos.0.y - target_jigsaw_local_pos.y, + target_jigsaw_pos.0.z - target_jigsaw_local_pos.z, + ); + let y_offset = target_box_y - raw_target_pos.0.y; + + let mut target_pos = raw_target_pos; + target_pos.0.y += y_offset; + + let rotated_target_size = + target_rotation.transform_size(target_template.size); + let mut target_box = BlockBox::new( + target_pos.0.x, + target_pos.0.y, + target_pos.0.z, + target_pos.0.x + rotated_target_size.x - 1, + target_pos.0.y + rotated_target_size.y - 1, + target_pos.0.z + rotated_target_size.z - 1, + ); + + let mut expand_to = 0; + if do_expansion_hack + && (target_box.max.y - target_box.min.y + 1) <= 16 + { + for tj in &target_jigsaws { + let tj_facing = + rotate_direction(tj.facing, target_rotation); + let rotated_tj_pos = target_rotation + .transform_pos(tj.pos.0, target_template.size); + let rotated_tj_target_pos = + rotated_tj_pos.add(&tj_facing.to_vector()); + + let rotated_size = + target_rotation.transform_size(target_template.size); + let hack_box = BlockBox::new( + 0, + 0, + 0, + rotated_size.x - 1, + rotated_size.y - 1, + rotated_size.z - 1, + ); + + if hack_box.contains( + rotated_tj_target_pos.x, + rotated_tj_target_pos.y, + rotated_tj_target_pos.z, + ) { + let child_pool_id = pool_alias_lookup.lookup(&tj.pool); + let child_pool_max_y = + get_pool_max_y_size(child_pool_id); + + let mut child_fallback_max_y = 0; + if let Some(cp) = TemplatePool::discover(child_pool_id) + { + child_fallback_max_y = get_pool_max_y_size( + pool_alias_lookup.lookup(&cp.fallback), + ); + } + + expand_to = expand_to + .max(child_pool_max_y) + .max(child_fallback_max_y); + } + } + } + + if expand_to > 0 { + let new_size = (expand_to + 1) + .max(target_box.max.y - target_box.min.y + 1); + target_box.max.y = target_box.min.y + new_size - 1; + } + + if !is_box_inside(&global_bounding_box, &target_box) { + continue; + } + + if !intersects_any(&pieces, &target_box) { + let mut child_jigsaw_blocks = Vec::new(); + for block in &target_template.blocks { + if let Some(mut cj) = JigsawBlock::from_template_block( + block, + &target_template.palette[block.state as usize], + ) { + let rotated_pos = target_rotation + .transform_pos(cj.pos.0, target_template.size); + cj.pos = BlockPos(rotated_pos).add( + target_pos.0.x, + target_pos.0.y, + target_pos.0.z, + ); + cj.facing = + rotate_direction(cj.facing, target_rotation); + cj.up = rotate_direction(cj.up, target_rotation); + child_jigsaw_blocks.push(cj); + } + } + + let source_ground_level_delta = + pieces[source_piece_idx].ground_level_delta; + let target_ground_level_delta = if target_rigid { + source_ground_level_delta - delta_y + } else { + 0 + }; + + let target_piece = Box::new(PoolElementStructurePiece { + piece: crate::generation::structure::structures::StructurePiece::new( + crate::generation::structure::piece::StructurePieceType::Jigsaw, + target_box, + depth as u32 + 1, + ), + template: target_template_arc.clone(), + pos: target_pos, + rotation: target_rotation, + mirror: Mirror::None, + jigsaw_blocks: child_jigsaw_blocks, + junctions: Vec::new(), + ground_level_delta: target_ground_level_delta, + liquid_settings, + projection: target_projection, + }); + + let target_piece_idx = pieces.len(); + pieces.push(target_piece); + piece_projections.push(target_projection); + + let junction_y = if source_rigid { + source_box.min.y + source_jigsaw_local_y + } else if target_rigid { + target_box_y + target_jigsaw_local_y + } else { + if source_jigsaw_base_height == i32::MIN { + source_jigsaw_base_height = if let Some(sampler) = + &mut context.height_sampler + { + let height = sampler.estimate_height( + source_jigsaw_pos.0.x, + source_jigsaw_pos.0.z, + ); + if project_start_to_heightmap { + height.max(context.sea_level) + } else { + height + } + } else { + source_jigsaw_pos.0.y + }; + } + source_jigsaw_base_height + delta_y / 2 + }; + + pieces[source_piece_idx].add_junction(JigsawJunction { + source_x: target_jigsaw_pos.0.x, + source_ground_y: junction_y - source_jigsaw_local_y + + source_ground_level_delta, + source_z: target_jigsaw_pos.0.z, + delta_y, + projection: target_projection, + }); + pieces[target_piece_idx].add_junction(JigsawJunction { + source_x: source_jigsaw_pos.0.x, + source_ground_y: junction_y - target_jigsaw_local_y + + target_ground_level_delta, + source_z: source_jigsaw_pos.0.z, + delta_y: -delta_y, + projection: source_projection, + }); + + sequence += 1; + if depth < max_depth { + placing.push(PieceState { + piece_idx: target_piece_idx, + depth: depth + 1, + priority: source_jigsaw.placement_priority, + sequence, + }); + } + + continue 'jigsaw_loop; + } + } + } + } + } + pieces[source_piece_idx].jigsaw_blocks = source_jigsaws; + } + } + + for piece in pieces { + collector.add_piece(piece); + } + + Some(StructurePosition { + start_pos: BlockPos::new(center_x, center_y, center_z), + collector: Arc::new(std::sync::Mutex::new(collector)), + }) + } +} + +// Helper to determine the max Y height of a pool for the expansion hack +fn get_pool_max_y_size(pool_id: &str) -> i32 { + let pool = match TemplatePool::discover(pool_id) { + Some(p) => p, + None => return 0, + }; + + let mut max_y = 0; + for element in &pool.elements { + if element.template == "minecraft:empty" { + continue; + } + if let Some(template) = get_template(element.template) { + max_y = max_y.max(template.size.y); + } + } + max_y +} + +fn is_box_inside(outer: &BlockBox, inner: &BlockBox) -> bool { + inner.min.x >= outer.min.x + && inner.max.x <= outer.max.x + && inner.min.y >= outer.min.y + && inner.max.y <= outer.max.y + && inner.min.z >= outer.min.z + && inner.max.z <= outer.max.z +} + +fn intersects_exclusive(a: &BlockBox, b: &BlockBox) -> bool { + // Strictly greater/less than checks perfectly emulate Vanilla's AABB deflate(0.25) + // by completely ignoring touching boundaries where coords are equal. + a.max.x > b.min.x + && a.min.x < b.max.x + && a.max.y > b.min.y + && a.min.y < b.max.y + && a.max.z > b.min.z + && a.min.z < b.max.z +} + +fn intersects_any(pieces: &[Box], box_: &BlockBox) -> bool { + pieces + .iter() + .any(|piece| intersects_exclusive(&piece.piece.bounding_box, box_)) +} + +struct PieceState { + piece_idx: usize, + depth: i32, + priority: i32, + sequence: usize, +} + +impl PartialEq for PieceState { + fn eq(&self, other: &Self) -> bool { + self.priority == other.priority && self.sequence == other.sequence + } +} + +impl Eq for PieceState {} + +impl PartialOrd for PieceState { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for PieceState { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.priority + .cmp(&other.priority) + .then_with(|| other.sequence.cmp(&self.sequence)) + } +} + +fn get_jigsaw_blocks(template: &StructureTemplate) -> Vec { + let mut jigsaws = Vec::new(); + for block in &template.blocks { + if let Some(jigsaw) = + JigsawBlock::from_template_block(block, &template.palette[block.state as usize]) + { + jigsaws.push(jigsaw); + } + } + jigsaws +} + +fn can_attach(source: &JigsawBlock, target: &JigsawBlock, target_rotation: Rotation) -> bool { + if source.target != target.name || target.target != source.name { + return false; + } + let rotated_target_facing = rotate_direction(target.facing, target_rotation); + if source.facing.opposite() != rotated_target_facing { + return false; + } + + // Joint alignment for vertical connections + if (source.joint == JigsawJointType::Aligned || target.joint == JigsawJointType::Aligned) + && (source.facing == pumpkin_util::BlockDirection::Up + || source.facing == pumpkin_util::BlockDirection::Down) + { + let rotated_target_up = rotate_direction(target.up, target_rotation); + return source.up == rotated_target_up; + } + + true +} + +fn rotate_direction( + dir: pumpkin_util::BlockDirection, + rotation: Rotation, +) -> pumpkin_util::BlockDirection { + use pumpkin_util::BlockDirection; + match rotation { + Rotation::None => dir, + Rotation::Clockwise90 => match dir { + BlockDirection::North => BlockDirection::East, + BlockDirection::East => BlockDirection::South, + BlockDirection::South => BlockDirection::West, + BlockDirection::West => BlockDirection::North, + _ => dir, + }, + Rotation::Rotate180 => dir.opposite(), + Rotation::CounterClockwise90 => match dir { + BlockDirection::North => BlockDirection::West, + BlockDirection::West => BlockDirection::South, + BlockDirection::South => BlockDirection::East, + BlockDirection::East => BlockDirection::North, + _ => dir, + }, + } +} diff --git a/pumpkin-world/src/generation/structure/structures/jungle_temple.rs b/pumpkin-world/src/generation/structure/structures/jungle_temple.rs index c0fb9c0d8..406cf32c1 100644 --- a/pumpkin-world/src/generation/structure/structures/jungle_temple.rs +++ b/pumpkin-world/src/generation/structure/structures/jungle_temple.rs @@ -23,7 +23,7 @@ use crate::{ piece::StructurePieceType, structures::{ StructureGenerator, StructureGeneratorContext, StructurePiece, StructurePieceBase, - StructurePiecesCollector, StructurePosition, + StructurePiecesCollector, StructurePosition, WorldPortalExt, }, }, }, @@ -38,7 +38,7 @@ pub struct JungleTempleGenerator; impl StructureGenerator for JungleTempleGenerator { fn get_structure_position( &self, - mut context: StructureGeneratorContext, + mut context: StructureGeneratorContext<'_>, ) -> Option { let x = start_block_x(context.chunk_x); let z = start_block_z(context.chunk_z); @@ -78,6 +78,9 @@ pub struct JungleTemplePiece { placed_trap_2: bool, } impl StructurePieceBase for JungleTemplePiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece } @@ -90,6 +93,7 @@ impl StructurePieceBase for JungleTemplePiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/mod.rs b/pumpkin-world/src/generation/structure/structures/mod.rs index 131de3a9f..b17e55397 100644 --- a/pumpkin-world/src/generation/structure/structures/mod.rs +++ b/pumpkin-world/src/generation/structure/structures/mod.rs @@ -2,6 +2,7 @@ use std::sync::{Arc, Mutex}; use pumpkin_data::Block; use pumpkin_data::BlockState; +use pumpkin_data::{Mirror, Rotation}; use pumpkin_util::HeightMap; use pumpkin_util::{ BlockDirection, @@ -11,10 +12,10 @@ use pumpkin_util::{ use tracing::debug; use crate::generation::structure::structures::stronghold::StrongholdPieceType; +pub use crate::world::WorldPortalExt; use crate::{ ProtoChunk, generation::{ - height_limit::HeightLimitView, positions::chunk_pos::{start_block_x, start_block_z}, structure::piece::StructurePieceType, }, @@ -23,6 +24,8 @@ use crate::{ pub mod buried_treasure; pub mod desert_pyramid; pub mod igloo; +pub mod jigsaw; +pub mod jigsaw_placement; pub mod jungle_temple; pub mod nether_fortress; pub mod nether_fossil; @@ -39,6 +42,8 @@ pub trait StructurePieceBase: Send + Sync { fn get_structure_piece_mut(&mut self) -> &mut StructurePiece; + fn as_any(&self) -> &dyn std::any::Any; + fn bounding_box(&self) -> BlockBox { self.get_structure_piece().bounding_box } @@ -51,6 +56,7 @@ pub trait StructurePieceBase: Send + Sync { fn place( &mut self, chunk: &mut ProtoChunk, + block_registry: &dyn WorldPortalExt, random: &mut RandomGenerator, seed: i64, _chunk_box: &BlockBox, @@ -92,6 +98,8 @@ pub struct StructurePiece { pub r#type: StructurePieceType, pub bounding_box: BlockBox, pub facing: Option, + pub mirror: Mirror, + pub rotation: Rotation, pub chain_length: u32, } @@ -106,12 +114,32 @@ impl StructurePiece { r#type, bounding_box, facing: None, + mirror: Mirror::None, + rotation: Rotation::None, chain_length, } } pub const fn set_facing(&mut self, facing: Option) { self.facing = facing; + match facing { + Some(BlockDirection::South) => { + self.mirror = Mirror::LeftRight; + self.rotation = Rotation::None; + } + Some(BlockDirection::West) => { + self.mirror = Mirror::LeftRight; + self.rotation = Rotation::Clockwise90; + } + Some(BlockDirection::East) => { + self.mirror = Mirror::None; + self.rotation = Rotation::Clockwise90; + } + _ => { + self.mirror = Mirror::None; + self.rotation = Rotation::None; + } + } } const fn offset_pos(&self, x: i32, y: i32, z: i32) -> Vector3 { @@ -147,6 +175,30 @@ impl StructurePiece { } } + #[allow(clippy::too_many_arguments)] + pub fn place_block( + &self, + chunk: &mut ProtoChunk, + block_registry: &dyn WorldPortalExt, + mut block_state: &'static BlockState, + x: i32, + y: i32, + z: i32, + chunk_box: &BlockBox, + ) { + let pos = self.offset_pos(x, y, z); + if chunk_box.contains(pos.x, pos.y, pos.z) { + let block = Block::from_state_id(block_state.id); + if self.mirror != Mirror::None { + block_state = block_registry.mirror(block, block_state.id, self.mirror); + } + if self.rotation != Rotation::None { + block_state = block_registry.rotate(block, block_state.id, self.rotation); + } + chunk.set_block_state(pos.x, pos.y, pos.z, block_state); + } + } + #[expect(clippy::too_many_arguments)] pub fn fill_outline_random( &self, @@ -447,9 +499,14 @@ impl StructurePiece { } impl StructurePieceBase for StructurePiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } + fn place( &mut self, _chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, _random: &mut RandomGenerator, _seed: i64, _chunk_box: &BlockBox, @@ -507,6 +564,7 @@ impl StructurePiecesCollector { pub fn generate_in_chunk( &mut self, chunk: &mut ProtoChunk, + block_registry: &dyn WorldPortalExt, random: &mut RandomGenerator, seed: i64, ) { @@ -514,16 +572,16 @@ impl StructurePiecesCollector { let chunk_z = start_block_z(chunk.z); let chunk_box = BlockBox::new( chunk_x, - chunk.bottom_y() as i32 + 1, + chunk.bottom_y() as i32, chunk_z, chunk_x + 15, - chunk.bottom_y() as i32 + chunk.top_y() as i32 - 1, + chunk.bottom_y() as i32 + chunk.height() as i32 - 1, chunk_z + 15, ); for piece in &mut self.pieces { if piece.bounding_box().intersects(&chunk_box) { - piece.place(chunk, random, seed, &chunk_box); + piece.place(chunk, block_registry, random, seed, &chunk_box); } } } @@ -598,17 +656,31 @@ impl StructurePosition { pub trait StructureGenerator { fn get_structure_position( &self, - context: StructureGeneratorContext, + context: StructureGeneratorContext<'_>, ) -> Option; } -pub struct StructureGeneratorContext { +pub trait HeightSampler { + fn estimate_height(&mut self, block_x: i32, block_z: i32) -> i32; +} + +impl HeightSampler + for crate::generation::noise::router::surface_height_sampler::SurfaceHeightEstimateSampler<'_> +{ + fn estimate_height(&mut self, block_x: i32, block_z: i32) -> i32 { + self.estimate_height(block_x, block_z) + } +} + +pub struct StructureGeneratorContext<'a> { pub seed: i64, pub chunk_x: i32, pub chunk_z: i32, pub random: RandomGenerator, pub sea_level: i32, pub min_y: i32, + pub height_sampler: Option<&'a mut dyn HeightSampler>, + pub structure_key: Option, } #[must_use] diff --git a/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge.rs b/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge.rs index 26364c4ac..0b5885825 100644 --- a/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge.rs +++ b/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge.rs @@ -17,6 +17,7 @@ use crate::{ nether_fortress::{NetherFortressPiece, NetherFortressPieceType, PieceWeight}, }, }, + world::WorldPortalExt, }; /// Straight exterior bridge segment (5 × 10 × 19). @@ -49,6 +50,9 @@ impl BridgePiece { } impl StructurePieceBase for BridgePiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -84,6 +88,7 @@ impl StructurePieceBase for BridgePiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, _random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge_crossing.rs b/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge_crossing.rs index d7c763a7c..fafa169c9 100644 --- a/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge_crossing.rs +++ b/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge_crossing.rs @@ -14,6 +14,7 @@ use crate::{ nether_fortress::{NetherFortressPiece, NetherFortressPieceType, PieceWeight}, }, }, + world::WorldPortalExt, }; /// 4-way exterior bridge crossing (19 × 10 × 19). @@ -106,6 +107,9 @@ impl BridgeCrossingPiece { } impl StructurePieceBase for BridgeCrossingPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -136,6 +140,7 @@ impl StructurePieceBase for BridgeCrossingPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, _random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge_end.rs b/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge_end.rs index cb9a47bde..803afb1eb 100644 --- a/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge_end.rs +++ b/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge_end.rs @@ -14,6 +14,7 @@ use crate::{ nether_fortress::{NetherFortressPiece, PieceWeight}, }, }, + world::WorldPortalExt, }; /// Dead-end / terminator piece for the exterior bridge (5 × 10 × 8). @@ -53,6 +54,9 @@ impl BridgeEndPiece { } impl StructurePieceBase for BridgeEndPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -76,6 +80,7 @@ impl StructurePieceBase for BridgeEndPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, _random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge_platform.rs b/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge_platform.rs index 154d4ce40..453fe83b9 100644 --- a/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge_platform.rs +++ b/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge_platform.rs @@ -14,6 +14,7 @@ use crate::{ nether_fortress::{NetherFortressPiece, PieceWeight}, }, }, + world::WorldPortalExt, }; /// Exterior platform with a Blaze mob-spawner (7 × 8 × 9). @@ -51,6 +52,9 @@ impl BridgePlatformPiece { } impl StructurePieceBase for BridgePlatformPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -74,6 +78,7 @@ impl StructurePieceBase for BridgePlatformPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, _random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge_small_crossing.rs b/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge_small_crossing.rs index 1d2117dfc..9afe4327b 100644 --- a/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge_small_crossing.rs +++ b/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge_small_crossing.rs @@ -13,6 +13,7 @@ use crate::{ nether_fortress::{NetherFortressPiece, NetherFortressPieceType, PieceWeight}, }, }, + world::WorldPortalExt, }; /// Small 3-way crossing for the exterior bridge network (7 × 9 × 7). @@ -46,6 +47,9 @@ impl BridgeSmallCrossingPiece { } impl StructurePieceBase for BridgeSmallCrossingPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -105,6 +109,7 @@ impl StructurePieceBase for BridgeSmallCrossingPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, _random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge_stairs.rs b/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge_stairs.rs index 2abedd8ae..4dced22f6 100644 --- a/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge_stairs.rs +++ b/pumpkin-world/src/generation/structure/structures/nether_fortress/bridge_stairs.rs @@ -13,6 +13,7 @@ use crate::{ nether_fortress::{NetherFortressPiece, NetherFortressPieceType, PieceWeight}, }, }, + world::WorldPortalExt, }; /// Stairway that transitions from bridge level to interior level (7 × 11 × 7). @@ -46,6 +47,9 @@ impl BridgeStairsPiece { } impl StructurePieceBase for BridgeStairsPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -82,6 +86,7 @@ impl StructurePieceBase for BridgeStairsPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, _random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_balcony.rs b/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_balcony.rs index c52042e69..bb5e7f83a 100644 --- a/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_balcony.rs +++ b/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_balcony.rs @@ -13,7 +13,7 @@ use crate::{ generation::structure::{ piece::StructurePieceType, structures::{ - StructurePiece, StructurePieceBase, StructurePiecesCollector, + StructurePiece, StructurePieceBase, StructurePiecesCollector, WorldPortalExt, nether_fortress::{NetherFortressPiece, NetherFortressPieceType, PieceWeight}, }, }, @@ -50,6 +50,9 @@ impl CorridorBalconyPiece { } impl StructurePieceBase for CorridorBalconyPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -107,6 +110,7 @@ impl StructurePieceBase for CorridorBalconyPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, _random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_crossing.rs b/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_crossing.rs index 2bee87748..2de4e6aa8 100644 --- a/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_crossing.rs +++ b/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_crossing.rs @@ -6,7 +6,7 @@ use crate::{ generation::structure::{ piece::StructurePieceType, structures::{ - StructurePiece, StructurePieceBase, StructurePiecesCollector, + StructurePiece, StructurePieceBase, StructurePiecesCollector, WorldPortalExt, nether_fortress::{NetherFortressPiece, NetherFortressPieceType, PieceWeight}, }, }, @@ -43,6 +43,9 @@ impl CorridorCrossingPiece { } impl StructurePieceBase for CorridorCrossingPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -102,6 +105,7 @@ impl StructurePieceBase for CorridorCrossingPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, _random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_exit.rs b/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_exit.rs index 53664e462..8b35ceef8 100644 --- a/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_exit.rs +++ b/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_exit.rs @@ -13,7 +13,7 @@ use crate::{ generation::structure::{ piece::StructurePieceType, structures::{ - StructurePiece, StructurePieceBase, StructurePiecesCollector, + StructurePiece, StructurePieceBase, StructurePiecesCollector, WorldPortalExt, nether_fortress::{NetherFortressPiece, NetherFortressPieceType, PieceWeight}, }, }, @@ -51,6 +51,9 @@ impl CorridorExitPiece { } impl StructurePieceBase for CorridorExitPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -86,6 +89,7 @@ impl StructurePieceBase for CorridorExitPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, _random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_left_turn.rs b/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_left_turn.rs index b2fc57b68..9c5f4bc28 100644 --- a/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_left_turn.rs +++ b/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_left_turn.rs @@ -13,7 +13,7 @@ use crate::{ generation::structure::{ piece::StructurePieceType, structures::{ - StructurePiece, StructurePieceBase, StructurePiecesCollector, + StructurePiece, StructurePieceBase, StructurePiecesCollector, WorldPortalExt, nether_fortress::{NetherFortressPiece, NetherFortressPieceType, PieceWeight}, }, }, @@ -56,6 +56,9 @@ impl CorridorLeftTurnPiece { } impl StructurePieceBase for CorridorLeftTurnPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -91,6 +94,7 @@ impl StructurePieceBase for CorridorLeftTurnPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_nether_warts_room.rs b/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_nether_warts_room.rs index 864f02e39..c6ac1e852 100644 --- a/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_nether_warts_room.rs +++ b/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_nether_warts_room.rs @@ -11,7 +11,7 @@ use crate::{ generation::structure::{ piece::StructurePieceType, structures::{ - StructurePiece, StructurePieceBase, StructurePiecesCollector, + StructurePiece, StructurePieceBase, StructurePiecesCollector, WorldPortalExt, nether_fortress::{NetherFortressPiece, NetherFortressPieceType, PieceWeight}, }, }, @@ -48,6 +48,9 @@ impl CorridorNetherWartsRoomPiece { } impl StructurePieceBase for CorridorNetherWartsRoomPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -96,6 +99,7 @@ impl StructurePieceBase for CorridorNetherWartsRoomPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, _random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_right_turn.rs b/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_right_turn.rs index 1fedd8923..dc4d26952 100644 --- a/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_right_turn.rs +++ b/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_right_turn.rs @@ -13,7 +13,7 @@ use crate::{ generation::structure::{ piece::StructurePieceType, structures::{ - StructurePiece, StructurePieceBase, StructurePiecesCollector, + StructurePiece, StructurePieceBase, StructurePiecesCollector, WorldPortalExt, nether_fortress::{NetherFortressPiece, NetherFortressPieceType, PieceWeight}, }, }, @@ -56,6 +56,9 @@ impl CorridorRightTurnPiece { } impl StructurePieceBase for CorridorRightTurnPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -91,6 +94,7 @@ impl StructurePieceBase for CorridorRightTurnPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_stairs.rs b/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_stairs.rs index 97041f146..adc610eae 100644 --- a/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_stairs.rs +++ b/pumpkin-world/src/generation/structure/structures/nether_fortress/corridor_stairs.rs @@ -11,7 +11,7 @@ use crate::{ generation::structure::{ piece::StructurePieceType, structures::{ - StructurePiece, StructurePieceBase, StructurePiecesCollector, + StructurePiece, StructurePieceBase, StructurePiecesCollector, WorldPortalExt, nether_fortress::{NetherFortressPiece, NetherFortressPieceType, PieceWeight}, }, }, @@ -49,6 +49,9 @@ impl CorridorStairsPiece { } impl StructurePieceBase for CorridorStairsPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -84,6 +87,7 @@ impl StructurePieceBase for CorridorStairsPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, _random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/nether_fortress/mod.rs b/pumpkin-world/src/generation/structure/structures/nether_fortress/mod.rs index 2d869d314..8d3979641 100644 --- a/pumpkin-world/src/generation/structure/structures/nether_fortress/mod.rs +++ b/pumpkin-world/src/generation/structure/structures/nether_fortress/mod.rs @@ -37,7 +37,7 @@ pub struct NetherFortressGenerator; impl StructureGenerator for NetherFortressGenerator { fn get_structure_position( &self, - context: StructureGeneratorContext, + context: StructureGeneratorContext<'_>, ) -> Option { let mut collector = StructurePiecesCollector::default(); let mut random = context.random; diff --git a/pumpkin-world/src/generation/structure/structures/nether_fortress/small_corridor.rs b/pumpkin-world/src/generation/structure/structures/nether_fortress/small_corridor.rs index caf820235..ae9867789 100644 --- a/pumpkin-world/src/generation/structure/structures/nether_fortress/small_corridor.rs +++ b/pumpkin-world/src/generation/structure/structures/nether_fortress/small_corridor.rs @@ -9,7 +9,7 @@ use crate::{ generation::structure::{ piece::StructurePieceType, structures::{ - StructurePiece, StructurePieceBase, StructurePiecesCollector, + StructurePiece, StructurePieceBase, StructurePiecesCollector, WorldPortalExt, nether_fortress::{NetherFortressPiece, NetherFortressPieceType, PieceWeight}, }, }, @@ -47,6 +47,9 @@ impl SmallCorridorPiece { } impl StructurePieceBase for SmallCorridorPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -82,6 +85,7 @@ impl StructurePieceBase for SmallCorridorPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, _random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/nether_fossil.rs b/pumpkin-world/src/generation/structure/structures/nether_fossil.rs index cb316c84e..61049d903 100644 --- a/pumpkin-world/src/generation/structure/structures/nether_fossil.rs +++ b/pumpkin-world/src/generation/structure/structures/nether_fossil.rs @@ -20,6 +20,7 @@ use crate::{ template::{BlockRotation, StructureTemplate, get_template, place_template}, }, }, + world::WorldPortalExt, }; const TEMPLATE_NAMES: [&str; 14] = [ @@ -50,7 +51,7 @@ pub struct NetherFossilGenerator; impl StructureGenerator for NetherFossilGenerator { fn get_structure_position( &self, - mut context: StructureGeneratorContext, + mut context: StructureGeneratorContext<'_>, ) -> Option { // Vanilla random call order: // 1. nextInt(16) for X offset within chunk @@ -155,9 +156,13 @@ impl NetherFossilPiece { } impl StructurePieceBase for NetherFossilPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, _random: &mut RandomGenerator, seed: i64, _chunk_box: &BlockBox, @@ -176,11 +181,20 @@ impl StructurePieceBase for NetherFossilPiece { let origin = self.shiftable_structure_piece.piece.bounding_box.min; // Vanilla uses IGNORE_AIR_AND_STRUCTURE_BLOCKS processor - place_template(chunk, &self.template, origin, (0, 0), self.rotation, true); + place_template( + chunk, + &self.template, + origin, + (0, 0), + self.rotation, + true, + &[], + Some(_chunk_box), + ); // Vanilla: 50% chance to place a dried ghast block at the fossil base. // Uses a deterministic random seeded from world seed + bounding box center. - self.try_place_dried_ghast(chunk, seed); + self.try_place_dried_ghast(chunk, _block_registry, seed); } fn get_structure_piece(&self) -> &StructurePiece { @@ -193,7 +207,12 @@ impl StructurePieceBase for NetherFossilPiece { } impl NetherFossilPiece { - fn try_place_dried_ghast(&self, chunk: &mut ProtoChunk, seed: i64) { + fn try_place_dried_ghast( + &self, + chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, + seed: i64, + ) { use pumpkin_util::random::xoroshiro128::Xoroshiro; let bbox = self.shiftable_structure_piece.piece.bounding_box; diff --git a/pumpkin-world/src/generation/structure/structures/stronghold/chest_corridor.rs b/pumpkin-world/src/generation/structure/structures/stronghold/chest_corridor.rs index 0a25e9f62..39681ef29 100644 --- a/pumpkin-world/src/generation/structure/structures/stronghold/chest_corridor.rs +++ b/pumpkin-world/src/generation/structure/structures/stronghold/chest_corridor.rs @@ -19,6 +19,8 @@ use crate::{ }, }; +use crate::world::WorldPortalExt; + pub struct ChestCorridorPiece { pub piece: StrongholdPiece, pub chest_generated: bool, @@ -58,6 +60,9 @@ impl ChestCorridorPiece { } impl StructurePieceBase for ChestCorridorPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -93,6 +98,7 @@ impl StructurePieceBase for ChestCorridorPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/stronghold/corridor.rs b/pumpkin-world/src/generation/structure/structures/stronghold/corridor.rs index f960e0f32..d09abf36c 100644 --- a/pumpkin-world/src/generation/structure/structures/stronghold/corridor.rs +++ b/pumpkin-world/src/generation/structure/structures/stronghold/corridor.rs @@ -19,6 +19,8 @@ use crate::{ }, }; +use crate::world::WorldPortalExt; + pub struct CorridorPiece { piece: StrongholdPiece, left_exit: bool, @@ -60,6 +62,9 @@ impl CorridorPiece { } impl StructurePieceBase for CorridorPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -121,6 +126,7 @@ impl StructurePieceBase for CorridorPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, @@ -232,6 +238,9 @@ impl SmallCorridorPiece { } impl StructurePieceBase for SmallCorridorPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &crate::generation::structure::structures::StructurePiece { &self.piece.piece } @@ -245,6 +254,7 @@ impl StructurePieceBase for SmallCorridorPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, _random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/stronghold/five_way_crossing.rs b/pumpkin-world/src/generation/structure/structures/stronghold/five_way_crossing.rs index 40f89044a..c3b631d9f 100644 --- a/pumpkin-world/src/generation/structure/structures/stronghold/five_way_crossing.rs +++ b/pumpkin-world/src/generation/structure/structures/stronghold/five_way_crossing.rs @@ -22,6 +22,8 @@ use crate::{ }, }; +use crate::world::WorldPortalExt; + pub struct FiveWayCrossingPiece { pub piece: StrongholdPiece, pub lower_left_exists: bool, @@ -67,6 +69,9 @@ impl FiveWayCrossingPiece { } impl StructurePieceBase for FiveWayCrossingPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -161,6 +166,7 @@ impl StructurePieceBase for FiveWayCrossingPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/stronghold/left_turn.rs b/pumpkin-world/src/generation/structure/structures/stronghold/left_turn.rs index acf36ca7f..086c47fd3 100644 --- a/pumpkin-world/src/generation/structure/structures/stronghold/left_turn.rs +++ b/pumpkin-world/src/generation/structure/structures/stronghold/left_turn.rs @@ -19,6 +19,8 @@ use crate::{ }, }; +use crate::world::WorldPortalExt; + pub struct LeftTurnPiece { pub piece: StrongholdPiece, } @@ -54,6 +56,9 @@ impl LeftTurnPiece { } impl StructurePieceBase for LeftTurnPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -103,6 +108,7 @@ impl StructurePieceBase for LeftTurnPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/stronghold/library.rs b/pumpkin-world/src/generation/structure/structures/stronghold/library.rs index bbe3dc0c3..251abf7b3 100644 --- a/pumpkin-world/src/generation/structure/structures/stronghold/library.rs +++ b/pumpkin-world/src/generation/structure/structures/stronghold/library.rs @@ -62,6 +62,9 @@ impl LibraryPiece { } impl StructurePieceBase for LibraryPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -73,6 +76,7 @@ impl StructurePieceBase for LibraryPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn crate::world::WorldPortalExt, random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/stronghold/mod.rs b/pumpkin-world/src/generation/structure/structures/stronghold/mod.rs index 5ab12c603..c05792864 100644 --- a/pumpkin-world/src/generation/structure/structures/stronghold/mod.rs +++ b/pumpkin-world/src/generation/structure/structures/stronghold/mod.rs @@ -60,7 +60,7 @@ pub struct StrongholdGenerator; impl StructureGenerator for StrongholdGenerator { fn get_structure_position( &self, - context: StructureGeneratorContext, + context: StructureGeneratorContext<'_>, ) -> Option { let mut collector = StructurePiecesCollector::default(); let mut random = context.random; diff --git a/pumpkin-world/src/generation/structure/structures/stronghold/portal_room.rs b/pumpkin-world/src/generation/structure/structures/stronghold/portal_room.rs index c4fa0737f..d24f1412e 100644 --- a/pumpkin-world/src/generation/structure/structures/stronghold/portal_room.rs +++ b/pumpkin-world/src/generation/structure/structures/stronghold/portal_room.rs @@ -26,6 +26,8 @@ use crate::{ }, }; +use crate::world::WorldPortalExt; + pub struct PortalRoomPiece { pub piece: StrongholdPiece, pub spawner_placed: bool, @@ -64,6 +66,9 @@ impl PortalRoomPiece { } impl StructurePieceBase for PortalRoomPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -90,6 +95,7 @@ impl StructurePieceBase for PortalRoomPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/stronghold/prison_hall.rs b/pumpkin-world/src/generation/structure/structures/stronghold/prison_hall.rs index 03597b0c2..13396e416 100644 --- a/pumpkin-world/src/generation/structure/structures/stronghold/prison_hall.rs +++ b/pumpkin-world/src/generation/structure/structures/stronghold/prison_hall.rs @@ -22,6 +22,8 @@ use crate::{ }, }; +use crate::world::WorldPortalExt; + pub struct PrisonHallPiece { piece: StrongholdPiece, } @@ -58,6 +60,9 @@ impl PrisonHallPiece { } impl StructurePieceBase for PrisonHallPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -94,6 +99,7 @@ impl StructurePieceBase for PrisonHallPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/stronghold/right_turn.rs b/pumpkin-world/src/generation/structure/structures/stronghold/right_turn.rs index 7aafa7451..573df52c9 100644 --- a/pumpkin-world/src/generation/structure/structures/stronghold/right_turn.rs +++ b/pumpkin-world/src/generation/structure/structures/stronghold/right_turn.rs @@ -19,6 +19,8 @@ use crate::{ }, }; +use crate::world::WorldPortalExt; + pub struct RightTurnPiece { pub piece: StrongholdPiece, } @@ -55,6 +57,9 @@ impl RightTurnPiece { } impl StructurePieceBase for RightTurnPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -104,6 +109,7 @@ impl StructurePieceBase for RightTurnPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/stronghold/spiral_staircase.rs b/pumpkin-world/src/generation/structure/structures/stronghold/spiral_staircase.rs index 47f9b0f21..c2eb237e2 100644 --- a/pumpkin-world/src/generation/structure/structures/stronghold/spiral_staircase.rs +++ b/pumpkin-world/src/generation/structure/structures/stronghold/spiral_staircase.rs @@ -88,6 +88,9 @@ impl SpiralStaircasePiece { } impl StructurePieceBase for SpiralStaircasePiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -123,6 +126,7 @@ impl StructurePieceBase for SpiralStaircasePiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn crate::world::WorldPortalExt, random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/stronghold/square_room.rs b/pumpkin-world/src/generation/structure/structures/stronghold/square_room.rs index 900c6ff19..16bd64994 100644 --- a/pumpkin-world/src/generation/structure/structures/stronghold/square_room.rs +++ b/pumpkin-world/src/generation/structure/structures/stronghold/square_room.rs @@ -22,6 +22,8 @@ use crate::{ }, }; +use crate::world::WorldPortalExt; + pub struct SquareRoomPiece { piece: StrongholdPiece, room_type: u32, @@ -62,6 +64,9 @@ impl SquareRoomPiece { } impl StructurePieceBase for SquareRoomPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -125,6 +130,7 @@ impl StructurePieceBase for SquareRoomPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/stronghold/stairs.rs b/pumpkin-world/src/generation/structure/structures/stronghold/stairs.rs index e4a2d372c..f2a419839 100644 --- a/pumpkin-world/src/generation/structure/structures/stronghold/stairs.rs +++ b/pumpkin-world/src/generation/structure/structures/stronghold/stairs.rs @@ -57,6 +57,9 @@ impl StairsPiece { } impl StructurePieceBase for StairsPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } @@ -92,6 +95,7 @@ impl StructurePieceBase for StairsPiece { fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn crate::world::WorldPortalExt, random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/structures/swamp_hut.rs b/pumpkin-world/src/generation/structure/structures/swamp_hut.rs index 78cf15585..3400bf7fd 100644 --- a/pumpkin-world/src/generation/structure/structures/swamp_hut.rs +++ b/pumpkin-world/src/generation/structure/structures/swamp_hut.rs @@ -29,7 +29,7 @@ pub struct SwampHutGenerator; impl StructureGenerator for SwampHutGenerator { fn get_structure_position( &self, - mut context: StructureGeneratorContext, + mut context: StructureGeneratorContext<'_>, ) -> Option { let x = get_center_x(context.chunk_x); let z = get_center_z(context.chunk_z); @@ -60,9 +60,13 @@ pub struct SwampHutPiece { } impl StructurePieceBase for SwampHutPiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn crate::world::WorldPortalExt, _random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, diff --git a/pumpkin-world/src/generation/structure/template/block_state_resolver.rs b/pumpkin-world/src/generation/structure/template/block_state_resolver.rs index 381b2c9c5..1fecd2e8f 100644 --- a/pumpkin-world/src/generation/structure/template/block_state_resolver.rs +++ b/pumpkin-world/src/generation/structure/template/block_state_resolver.rs @@ -4,10 +4,10 @@ //! to the runtime block state IDs used by the world, with support for rotation //! and mirroring transformations. -use pumpkin_data::{Block, BlockState}; +use pumpkin_data::{Block, BlockState, Mirror, Rotation}; use tracing::warn; -use super::{BlockMirror, BlockRotation, PaletteEntry}; +use super::PaletteEntry; /// Resolves template palette entries to block state IDs. /// @@ -24,8 +24,8 @@ impl BlockStateResolver { #[must_use] pub fn resolve( entry: &PaletteEntry, - rotation: BlockRotation, - mirror: BlockMirror, + rotation: Rotation, + mirror: Mirror, ) -> Option<&'static BlockState> { // Strip minecraft: prefix if present let block_name = entry.name.strip_prefix("minecraft:").unwrap_or(&entry.name); @@ -68,15 +68,15 @@ impl BlockStateResolver { /// Resolves a palette entry without any transformation. #[must_use] pub fn resolve_simple(entry: &PaletteEntry) -> Option<&'static BlockState> { - Self::resolve(entry, BlockRotation::None, BlockMirror::None) + Self::resolve(entry, Rotation::None, Mirror::None) } /// Transforms a property value based on rotation and mirror. fn transform_property( key: &str, value: &str, - rotation: BlockRotation, - mirror: BlockMirror, + rotation: Rotation, + mirror: Mirror, ) -> &'static str { match key { // Horizontal facing properties @@ -217,8 +217,7 @@ mod tests { ); // Get state with rotation - let rotated = - BlockStateResolver::resolve(&entry, BlockRotation::Clockwise90, BlockMirror::None); + let rotated = BlockStateResolver::resolve(&entry, Rotation::Clockwise90, Mirror::None); assert!(rotated.is_some()); // The rotated block should have facing=east after 90 degree clockwise rotation diff --git a/pumpkin-world/src/generation/structure/template/cache.rs b/pumpkin-world/src/generation/structure/template/cache.rs index b50969428..99c59b50d 100644 --- a/pumpkin-world/src/generation/structure/template/cache.rs +++ b/pumpkin-world/src/generation/structure/template/cache.rs @@ -116,69 +116,12 @@ impl TemplateCache { /// This function maps template names to their embedded byte data. /// Add new templates here as they are added to the assets. fn load_template_bytes(path: &str) -> Option<&'static [u8]> { - // Map template names to embedded files - // Templates are stored in pumpkin-world/assets/structures/ - match path { - // Nether fossil templates - "nether_fossils/fossil_1" => Some(include_bytes!( - "../../../../assets/structures/nether_fossils/fossil_1.nbt" - )), - "nether_fossils/fossil_2" => Some(include_bytes!( - "../../../../assets/structures/nether_fossils/fossil_2.nbt" - )), - "nether_fossils/fossil_3" => Some(include_bytes!( - "../../../../assets/structures/nether_fossils/fossil_3.nbt" - )), - "nether_fossils/fossil_4" => Some(include_bytes!( - "../../../../assets/structures/nether_fossils/fossil_4.nbt" - )), - "nether_fossils/fossil_5" => Some(include_bytes!( - "../../../../assets/structures/nether_fossils/fossil_5.nbt" - )), - "nether_fossils/fossil_6" => Some(include_bytes!( - "../../../../assets/structures/nether_fossils/fossil_6.nbt" - )), - "nether_fossils/fossil_7" => Some(include_bytes!( - "../../../../assets/structures/nether_fossils/fossil_7.nbt" - )), - "nether_fossils/fossil_8" => Some(include_bytes!( - "../../../../assets/structures/nether_fossils/fossil_8.nbt" - )), - "nether_fossils/fossil_9" => Some(include_bytes!( - "../../../../assets/structures/nether_fossils/fossil_9.nbt" - )), - "nether_fossils/fossil_10" => Some(include_bytes!( - "../../../../assets/structures/nether_fossils/fossil_10.nbt" - )), - "nether_fossils/fossil_11" => Some(include_bytes!( - "../../../../assets/structures/nether_fossils/fossil_11.nbt" - )), - "nether_fossils/fossil_12" => Some(include_bytes!( - "../../../../assets/structures/nether_fossils/fossil_12.nbt" - )), - "nether_fossils/fossil_13" => Some(include_bytes!( - "../../../../assets/structures/nether_fossils/fossil_13.nbt" - )), - "nether_fossils/fossil_14" => Some(include_bytes!( - "../../../../assets/structures/nether_fossils/fossil_14.nbt" - )), - - // Igloo templates - "igloo/top" => Some(include_bytes!( - "../../../../assets/structures/igloo/top.nbt" - )), - "igloo/middle" => Some(include_bytes!( - "../../../../assets/structures/igloo/middle.nbt" - )), - "igloo/bottom" => Some(include_bytes!( - "../../../../assets/structures/igloo/bottom.nbt" - )), - - _ => None, - } + get_template_bytes(path) } } +include!(concat!(env!("OUT_DIR"), "/template_embeddings.rs")); + /// Global template cache instance. /// /// This provides a singleton cache that can be used throughout the codebase @@ -199,75 +142,3 @@ pub fn global_cache() -> &'static TemplateCache { pub fn get_template(name: &'static str) -> Option> { global_cache().get(name) } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_cache_creation() { - let cache = TemplateCache::new(); - assert!(cache.is_empty()); - } - - #[test] - fn test_unknown_template_returns_none() { - let cache = TemplateCache::new(); - assert!(cache.get("nonexistent/template").is_none()); - } - - #[test] - fn test_load_igloo_top() { - let cache = TemplateCache::new(); - let template = cache.get("igloo/top").expect("Failed to load igloo/top"); - - // Verify vanilla igloo/top dimensions (7x5x8) - assert_eq!(template.size.x, 7); - assert_eq!(template.size.y, 5); - assert_eq!(template.size.z, 8); - - // Verify it has blocks - assert!(!template.blocks.is_empty()); - // Verify it has a palette - assert!(!template.palette.is_empty()); - } - - #[test] - fn test_load_igloo_middle() { - let cache = TemplateCache::new(); - let template = cache - .get("igloo/middle") - .expect("Failed to load igloo/middle"); - - // Verify vanilla igloo/middle dimensions (3x3x3) - assert_eq!(template.size.x, 3); - assert_eq!(template.size.y, 3); - assert_eq!(template.size.z, 3); - } - - #[test] - fn test_load_igloo_bottom() { - let cache = TemplateCache::new(); - let template = cache - .get("igloo/bottom") - .expect("Failed to load igloo/bottom"); - - // Verify vanilla igloo/bottom dimensions (7x6x9) - assert_eq!(template.size.x, 7); - assert_eq!(template.size.y, 6); - assert_eq!(template.size.z, 9); - } - - #[test] - fn test_cache_reuses_templates() { - let cache = TemplateCache::new(); - - // Load twice - let first = cache.get("igloo/top").expect("First load failed"); - let second = cache.get("igloo/top").expect("Second load failed"); - - // Should be the same Arc (pointer equality) - assert!(Arc::ptr_eq(&first, &second)); - assert_eq!(cache.len(), 1); - } -} diff --git a/pumpkin-world/src/generation/structure/template/mod.rs b/pumpkin-world/src/generation/structure/template/mod.rs index b90987e5a..21a15feee 100644 --- a/pumpkin-world/src/generation/structure/template/mod.rs +++ b/pumpkin-world/src/generation/structure/template/mod.rs @@ -8,13 +8,14 @@ //! //! - [`StructureTemplate`]: Represents a loaded NBT template with size, palette, and blocks //! - [`TemplatePiece`]: A structure piece that places blocks from a template -//! - [`BlockRotation`] and [`BlockMirror`]: Transform positions and block properties +//! - [`Rotation`] and [`Mirror`]: Transform positions and block properties //! - [`TemplateCache`]: Lazy-loading cache for embedded template files //! //! # Example Usage //! //! ```ignore -//! use pumpkin_world::generation::structure::template::{TemplateCache, TemplatePiece, BlockRotation}; +//! use pumpkin_world::generation::structure::template::{TemplateCache, TemplatePiece}; +//! use pumpkin_data::Rotation; //! //! // Load a template from the cache //! let template = TemplateCache::get("igloo/top").expect("Template not found"); @@ -25,18 +26,20 @@ mod block_state_resolver; mod cache; -mod rotation; +pub mod processor; mod structure_template; mod template_piece; +use pumpkin_data::Rotation; use pumpkin_nbt::compound::NbtCompound; use pumpkin_util::math::vector3::Vector3; use crate::ProtoChunk; pub use block_state_resolver::BlockStateResolver; -pub use cache::{TemplateCache, get_template, global_cache}; -pub use rotation::{BlockMirror, BlockRotation}; +pub use cache::{TemplateCache, get_pool_elements, get_template, global_cache}; +pub use processor::StructureProcessor; +pub use pumpkin_data::{Mirror as BlockMirror, Rotation as BlockRotation}; pub use structure_template::{PaletteEntry, StructureTemplate, TemplateBlock, TemplateEntity}; pub use template_piece::TemplatePiece; @@ -50,13 +53,16 @@ pub use template_piece::TemplatePiece; /// /// `origin` is the base world position (x, y, z). /// `offset` is the un-rotated XZ offset from origin (`x_offset`, `z_offset`) - rotation is applied automatically. +#[allow(clippy::too_many_arguments)] pub fn place_template( chunk: &mut ProtoChunk, template: &StructureTemplate, origin: Vector3, offset: (i32, i32), - rotation: BlockRotation, + rotation: Rotation, skip_air: bool, + processors: &[Box], + chunk_box: Option<&pumpkin_util::math::block_box::BlockBox>, ) { let (rotated_ox, rotated_oz) = rotation.rotate_offset(offset.0, offset.1); let world_x = origin.x + rotated_ox; @@ -76,7 +82,8 @@ pub fn place_template( } // Resolve block state with rotation applied to directional properties - let Some(state) = BlockStateResolver::resolve(palette_entry, rotation, Default::default()) + let Some(mut state) = + BlockStateResolver::resolve(palette_entry, rotation, Default::default()) else { continue; }; @@ -88,6 +95,24 @@ pub fn place_template( let wy = origin.y + local_pos.y; let wz = world_z + local_pos.z; + if let Some(bbox) = chunk_box + && (wx < bbox.min.x + || wx > bbox.max.x + || wy < bbox.min.y + || wy > bbox.max.y + || wz < bbox.min.z + || wz > bbox.max.z) + { + continue; + } + + let world_pos = Vector3::new(wx, wy, wz); + + // Apply processors + for processor in processors { + state = processor.process(chunk, world_pos, state); + } + chunk.set_block_state(wx, wy, wz, state); // Create block entities for interactive blocks (furnaces, chests, etc.) diff --git a/pumpkin-world/src/generation/structure/template/processor.rs b/pumpkin-world/src/generation/structure/template/processor.rs new file mode 100644 index 000000000..1069a0d1a --- /dev/null +++ b/pumpkin-world/src/generation/structure/template/processor.rs @@ -0,0 +1,43 @@ +use crate::ProtoChunk; +use pumpkin_data::BlockState; +use pumpkin_util::math::vector3::Vector3; + +pub trait StructureProcessor: Send + Sync { + fn process( + &self, + chunk: &mut ProtoChunk, + pos: Vector3, + state: &'static BlockState, + ) -> &'static BlockState; +} + +pub struct GravityProcessor { + pub heightmap: pumpkin_util::HeightMap, + pub offset: i32, +} + +impl StructureProcessor for GravityProcessor { + fn process( + &self, + chunk: &mut ProtoChunk, + pos: Vector3, + state: &'static BlockState, + ) -> &'static BlockState { + let top_y = chunk.get_top_y(&self.heightmap, pos.x, pos.z); + let _target_y = top_y + self.offset; + + // For now, just a simple gravity: if we are placing above the ground, shift it down? + // Actually, GravityProcessor in vanilla is used to place blocks relative to the ground. + // But our jigsaw already adjusted the piece origin. + + let block = pumpkin_data::Block::from_state_id(state.id); + if block.name == "cobblestone" || block.name == "stone_bricks" { + // Fill down to ground + for y in (top_y..pos.y).rev() { + chunk.set_block_state(pos.x, y, pos.z, state); + } + } + + state + } +} diff --git a/pumpkin-world/src/generation/structure/template/structure_template.rs b/pumpkin-world/src/generation/structure/template/structure_template.rs index 828d736aa..05eff0d6f 100644 --- a/pumpkin-world/src/generation/structure/template/structure_template.rs +++ b/pumpkin-world/src/generation/structure/template/structure_template.rs @@ -72,6 +72,27 @@ impl PaletteEntry { pub const fn with_properties(name: String, properties: Vec<(String, String)>) -> Self { Self { name, properties } } + + /// Parses a block state string (e.g. "minecraft:oak_log[axis=x]") into a palette entry. + pub fn from_string(s: &str) -> Self { + if let Some(bracket_pos) = s.find('[') { + let name = s[..bracket_pos].to_string(); + let end_bracket = s.rfind(']').unwrap_or(s.len()); + let props_str = &s[bracket_pos + 1..end_bracket]; + let properties = props_str + .split(',') + .filter_map(|p| { + let mut parts = p.split('='); + let key = parts.next()?.trim().to_string(); + let value = parts.next()?.trim().to_string(); + Some((key, value)) + }) + .collect(); + Self { name, properties } + } else { + Self::new(s.to_string()) + } + } } /// A single block placement in the template. diff --git a/pumpkin-world/src/generation/structure/template/template_piece.rs b/pumpkin-world/src/generation/structure/template/template_piece.rs index beeb1e349..b28bf65c6 100644 --- a/pumpkin-world/src/generation/structure/template/template_piece.rs +++ b/pumpkin-world/src/generation/structure/template/template_piece.rs @@ -5,6 +5,7 @@ use std::sync::Arc; +use pumpkin_data::{Mirror, Rotation}; use pumpkin_util::{ math::{block_box::BlockBox, vector3::Vector3}, random::RandomGenerator, @@ -17,9 +18,10 @@ use crate::{ piece::StructurePieceType, structures::{StructurePiece, StructurePieceBase}, }, + world::WorldPortalExt, }; -use super::{BlockMirror, BlockRotation, BlockStateResolver, StructureTemplate}; +use super::{BlockStateResolver, StructureTemplate}; /// A structure piece that places blocks from an NBT template. /// @@ -36,10 +38,10 @@ pub struct TemplatePiece { pub template: Arc, /// Rotation to apply when placing. - pub rotation: BlockRotation, + pub rotation: Rotation, /// Mirror to apply when placing. - pub mirror: BlockMirror, + pub mirror: Mirror, } impl TemplatePiece { @@ -50,8 +52,8 @@ impl TemplatePiece { #[must_use] pub fn new( template: Arc, - rotation: BlockRotation, - mirror: BlockMirror, + rotation: Rotation, + mirror: Mirror, origin: Vector3, piece_type: StructurePieceType, ) -> Self { @@ -79,8 +81,8 @@ impl TemplatePiece { #[must_use] pub fn with_chain_length( template: Arc, - rotation: BlockRotation, - mirror: BlockMirror, + rotation: Rotation, + mirror: Mirror, origin: Vector3, piece_type: StructurePieceType, chain_length: u32, @@ -118,7 +120,7 @@ impl TemplatePiece { } /// Places all blocks from the template into the chunk. - fn place_blocks(&self, chunk: &mut ProtoChunk) { + fn place_blocks(&self, chunk: &mut ProtoChunk, chunk_box: &BlockBox) { let box_limit = self.piece.bounding_box; for block in &self.template.blocks { @@ -142,8 +144,8 @@ impl TemplatePiece { // Transform position to world coordinates let world_pos = self.transform_pos(block.pos); - // Check bounds - if !box_limit.contains_pos(&world_pos) { + // Check bounds against both the piece bounding box and the current chunk box + if !box_limit.contains_pos(&world_pos) || !chunk_box.contains_pos(&world_pos) { continue; } @@ -158,14 +160,18 @@ impl TemplatePiece { } impl StructurePieceBase for TemplatePiece { + fn as_any(&self) -> &dyn std::any::Any { + self + } fn place( &mut self, chunk: &mut ProtoChunk, + _block_registry: &dyn WorldPortalExt, _random: &mut RandomGenerator, _seed: i64, - _chunk_box: &BlockBox, + chunk_box: &BlockBox, ) { - self.place_blocks(chunk); + self.place_blocks(chunk, chunk_box); // TODO: Spawn entities from template // This would involve iterating over self.template.entities diff --git a/pumpkin-world/src/lib.rs b/pumpkin-world/src/lib.rs index b5a121ee4..1307a41f7 100644 --- a/pumpkin-world/src/lib.rs +++ b/pumpkin-world/src/lib.rs @@ -96,6 +96,9 @@ pub fn bench_create_and_populate_noise( sampler, settings.aquifers_enabled, settings.ore_veins_enabled, + Vec::new(), + Vec::new(), + None, ); // Surface height estimator @@ -223,6 +226,9 @@ pub fn bench_create_and_populate_noise_with_surface( sampler, settings.aquifers_enabled, settings.ore_veins_enabled, + Vec::new(), + Vec::new(), + None, ); // Surface height estimator diff --git a/pumpkin-world/src/world.rs b/pumpkin-world/src/world.rs index 293492b3c..2c8ec23bb 100644 --- a/pumpkin-world/src/world.rs +++ b/pumpkin-world/src/world.rs @@ -2,7 +2,7 @@ use std::pin::Pin; use crate::{BlockStateId, generation::proto_chunk::GenerationCache}; use bitflags::bitflags; -use pumpkin_data::{Block, BlockState, chunk::Biome}; +use pumpkin_data::{Block, BlockState, Mirror, Rotation, chunk::Biome}; use pumpkin_util::math::position::BlockPos; use thiserror::Error; @@ -64,6 +64,10 @@ pub trait WorldPortalExt: Send + Sync { block_pos: &BlockPos, ) -> bool; + fn mirror(&self, block: &Block, state_id: u16, mirror: Mirror) -> &'static BlockState; + + fn rotate(&self, block: &Block, state_id: u16, rotation: Rotation) -> &'static BlockState; + fn spawn_mobs_for_chunk_generation( &self, cache: &mut dyn GenerationCache, diff --git a/pumpkin/src/block/blocks/jigsaw.rs b/pumpkin/src/block/blocks/jigsaw.rs new file mode 100644 index 000000000..f001910e3 --- /dev/null +++ b/pumpkin/src/block/blocks/jigsaw.rs @@ -0,0 +1,205 @@ +use std::sync::Arc; + +use crate::block::entities::jigsaw_block::JigsawBlockEntity; +use crate::block::registry::BlockActionResult; +use crate::block::{ + BlockBehaviour, BlockFuture, BlockMetadata, NormalUseArgs, OnPlaceArgs, PlacedArgs, +}; +use crate::entity::EntityBase; +use pumpkin_data::Block; +use pumpkin_data::block_properties::{ + BlockProperties, Facing, HorizontalFacing, JigsawLikeProperties, Orientation, +}; +use pumpkin_data::block_rotation::{Mirror, Rotation}; +use pumpkin_util::{BlockDirection, GameMode, PermissionLvl}; +use pumpkin_world::BlockStateId; + +pub struct JigsawBlock; + +impl JigsawBlock { + const fn from_front_top(front: BlockDirection, top: BlockDirection) -> Orientation { + match (front, top) { + (BlockDirection::Down, BlockDirection::East) => Orientation::DownEast, + (BlockDirection::Down, BlockDirection::North) => Orientation::DownNorth, + (BlockDirection::Down, BlockDirection::South) => Orientation::DownSouth, + (BlockDirection::Down, BlockDirection::West) => Orientation::DownWest, + (BlockDirection::Up, BlockDirection::East) => Orientation::UpEast, + (BlockDirection::Up, BlockDirection::North) => Orientation::UpNorth, + (BlockDirection::Up, BlockDirection::South) => Orientation::UpSouth, + (BlockDirection::Up, BlockDirection::West) => Orientation::UpWest, + (BlockDirection::West, BlockDirection::Up) => Orientation::WestUp, + (BlockDirection::East, BlockDirection::Up) => Orientation::EastUp, + (BlockDirection::South, BlockDirection::Up) => Orientation::SouthUp, + _ => Orientation::NorthUp, // Default + } + } + + const fn to_front_top(orientation: Orientation) -> (BlockDirection, BlockDirection) { + match orientation { + Orientation::DownEast => (BlockDirection::Down, BlockDirection::East), + Orientation::DownNorth => (BlockDirection::Down, BlockDirection::North), + Orientation::DownSouth => (BlockDirection::Down, BlockDirection::South), + Orientation::DownWest => (BlockDirection::Down, BlockDirection::West), + Orientation::UpEast => (BlockDirection::Up, BlockDirection::East), + Orientation::UpNorth => (BlockDirection::Up, BlockDirection::North), + Orientation::UpSouth => (BlockDirection::Up, BlockDirection::South), + Orientation::UpWest => (BlockDirection::Up, BlockDirection::West), + Orientation::WestUp => (BlockDirection::West, BlockDirection::Up), + Orientation::EastUp => (BlockDirection::East, BlockDirection::Up), + Orientation::NorthUp => (BlockDirection::North, BlockDirection::Up), + Orientation::SouthUp => (BlockDirection::South, BlockDirection::Up), + } + } +} + +impl BlockMetadata for JigsawBlock { + fn ids() -> Box<[u16]> { + [Block::JIGSAW.id].into() + } +} + +impl BlockBehaviour for JigsawBlock { + fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> { + Box::pin(async move { + let mut props = JigsawLikeProperties::default(args.block); + let facing = args.player.get_entity().get_facing(); + let front = facing_to_dir(facing).opposite(); + let top = if facing == Facing::Up || facing == Facing::Down { + horizontal_facing_to_dir(args.player.get_entity().get_horizontal_facing()) + .opposite() + } else { + BlockDirection::Up + }; + + props.r#orientation = Self::from_front_top(front, top); + props.to_state_id(args.block) + }) + } + + fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> { + Box::pin(async move { + if args.player.permission_lvl.load() < PermissionLvl::Two { + return BlockActionResult::Pass; + } + if args.player.gamemode.load() != GameMode::Creative { + return BlockActionResult::Pass; + } + let Some(block_entity) = args.world.get_block_entity(args.position) else { + return BlockActionResult::Pass; + }; + args.world.update_block_entity(&block_entity); + BlockActionResult::SuccessServer + }) + } + + fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> { + Box::pin(async move { + let entity = JigsawBlockEntity::new(*args.position); + args.world.add_block_entity(Arc::new(entity)); + }) + } + + fn mirror( + &self, + block: &pumpkin_data::Block, + state_id: u16, + mirror: Mirror, + ) -> &'static pumpkin_data::BlockState { + if mirror == Mirror::None { + return pumpkin_data::BlockState::from_id(state_id); + } + let mut props = JigsawLikeProperties::from_state_id(state_id, block); + let (front, top) = Self::to_front_top(props.r#orientation); + + let new_front = mirror_direction(front, mirror); + let new_top = mirror_direction(top, mirror); + + props.r#orientation = Self::from_front_top(new_front, new_top); + pumpkin_data::BlockState::from_id(props.to_state_id(block)) + } + + fn rotate( + &self, + block: &pumpkin_data::Block, + state_id: u16, + rotation: Rotation, + ) -> &'static pumpkin_data::BlockState { + if rotation == Rotation::None { + return pumpkin_data::BlockState::from_id(state_id); + } + let mut props = JigsawLikeProperties::from_state_id(state_id, block); + let (front, top) = Self::to_front_top(props.r#orientation); + + let new_front = rotate_direction(front, rotation); + let new_top = rotate_direction(top, rotation); + + props.r#orientation = Self::from_front_top(new_front, new_top); + pumpkin_data::BlockState::from_id(props.to_state_id(block)) + } +} + +const fn facing_to_dir(facing: Facing) -> BlockDirection { + match facing { + Facing::North => BlockDirection::North, + Facing::East => BlockDirection::East, + Facing::South => BlockDirection::South, + Facing::West => BlockDirection::West, + Facing::Up => BlockDirection::Up, + Facing::Down => BlockDirection::Down, + } +} + +const fn horizontal_facing_to_dir(facing: HorizontalFacing) -> BlockDirection { + match facing { + HorizontalFacing::North => BlockDirection::North, + HorizontalFacing::South => BlockDirection::South, + HorizontalFacing::West => BlockDirection::West, + HorizontalFacing::East => BlockDirection::East, + } +} + +fn rotate_direction(dir: BlockDirection, rotation: Rotation) -> BlockDirection { + if dir == BlockDirection::Up || dir == BlockDirection::Down { + return dir; + } + match rotation { + Rotation::None => dir, + Rotation::Clockwise90 => match dir { + BlockDirection::North => BlockDirection::East, + BlockDirection::East => BlockDirection::South, + BlockDirection::South => BlockDirection::West, + BlockDirection::West => BlockDirection::North, + _ => dir, + }, + Rotation::Rotate180 => match dir { + BlockDirection::North => BlockDirection::South, + BlockDirection::South => BlockDirection::North, + BlockDirection::East => BlockDirection::West, + BlockDirection::West => BlockDirection::East, + _ => dir, + }, + Rotation::CounterClockwise90 => match dir { + BlockDirection::North => BlockDirection::West, + BlockDirection::West => BlockDirection::South, + BlockDirection::South => BlockDirection::East, + BlockDirection::East => BlockDirection::North, + _ => dir, + }, + } +} + +const fn mirror_direction(dir: BlockDirection, mirror: Mirror) -> BlockDirection { + match mirror { + Mirror::None => dir, + Mirror::LeftRight => match dir { + BlockDirection::East => BlockDirection::West, + BlockDirection::West => BlockDirection::East, + _ => dir, + }, + Mirror::FrontBack => match dir { + BlockDirection::North => BlockDirection::South, + BlockDirection::South => BlockDirection::North, + _ => dir, + }, + } +} diff --git a/pumpkin/src/block/blocks/mod.rs b/pumpkin/src/block/blocks/mod.rs index 80c4b6390..d8b2cba39 100644 --- a/pumpkin/src/block/blocks/mod.rs +++ b/pumpkin/src/block/blocks/mod.rs @@ -23,6 +23,7 @@ pub mod stonecutter; // Redstone & mechanisms pub mod command; // command block / redstone control +pub mod jigsaw; pub mod note; pub mod piston; pub mod redstone; diff --git a/pumpkin/src/block/entities/jigsaw_block.rs b/pumpkin/src/block/entities/jigsaw_block.rs new file mode 100644 index 000000000..081449127 --- /dev/null +++ b/pumpkin/src/block/entities/jigsaw_block.rs @@ -0,0 +1,306 @@ +use rand::Rng; +use std::{ + pin::Pin, + sync::{ + Arc, + atomic::{AtomicBool, AtomicI32, Ordering}, + }, +}; + +use futures::Future; +use pumpkin_data::block_properties::{BlockProperties, JigsawLikeProperties, Orientation}; +use pumpkin_nbt::compound::NbtCompound; +use pumpkin_util::{ + BlockDirection, + math::position::BlockPos, + random::{RandomGenerator, xoroshiro128::Xoroshiro}, +}; +use pumpkin_world::generation::structure::{ + structures::{ + StructureGeneratorContext, StructurePosition, + jigsaw::{JigsawJointType, PoolElementStructurePiece}, + jigsaw_placement::{ + DimensionPadding, JigsawPlacement, LiquidSettings, MaxDistance, PoolAliasLookup, + }, + }, + template::BlockStateResolver, +}; + +use tokio::sync::Mutex; + +use crate::world::World; + +use super::BlockEntity; + +pub struct JigsawBlockEntity { + pub position: BlockPos, + pub name: Mutex, + pub target: Mutex, + pub pool: Mutex, + pub final_state: Mutex, + pub joint: Mutex, + pub selection_priority: AtomicI32, + pub placement_priority: AtomicI32, + pub dirty: AtomicBool, +} + +impl JigsawBlockEntity { + pub const ID: &'static str = "minecraft:jigsaw"; + #[must_use] + pub fn new(position: BlockPos) -> Self { + Self { + position, + name: Mutex::new("minecraft:empty".to_string()), + target: Mutex::new("minecraft:empty".to_string()), + pool: Mutex::new("minecraft:empty".to_string()), + final_state: Mutex::new("minecraft:air".to_string()), + joint: Mutex::new(JigsawJointType::Rollable), + selection_priority: AtomicI32::new(0), + placement_priority: AtomicI32::new(0), + dirty: AtomicBool::new(false), + } + } + + pub async fn generate(&self, world: &Arc, levels: i32, keep_jigsaws: bool) { + let pool = self.pool.lock().await.clone(); + let target = self.target.lock().await.clone(); + + let block_state = world.get_block_state(&self.position); + let props = + JigsawLikeProperties::from_state_id(block_state.id, &pumpkin_data::Block::JIGSAW); + let (front, _top) = Self::to_front_top(props.r#orientation); + + let position = self.position.offset(front.to_vector()); + + let structure = { + let mut context = StructureGeneratorContext { + seed: world.level_info.load().world_gen_settings.seed, + chunk_x: self.position.chunk_position().x, + chunk_z: self.position.chunk_position().y, + random: RandomGenerator::Xoroshiro(Xoroshiro::from_seed(rand::rng().next_u64())), + sea_level: 63, + min_y: -64, + height_sampler: None, + structure_key: None, + }; + + JigsawPlacement::add_pieces( + &mut context, + &pool, + Some(&target), + levels, + position, + false, + false, + MaxDistance::new(80), + DimensionPadding::ZERO, + LiquidSettings::ApplyWaterlog, + &PoolAliasLookup, + ) + }; + + if let Some(structure) = structure { + self.place_structure(world, structure, keep_jigsaws).await; + } + } + + async fn place_structure( + &self, + world: &Arc, + structure: StructurePosition, + keep_jigsaws: bool, + ) { + let mut pieces = std::mem::take(&mut structure.collector.lock().unwrap().pieces); + for piece in &mut pieces { + if let Some(pool_piece) = piece.as_any().downcast_ref::() { + let template = Arc::clone(&pool_piece.template); + let origin = pool_piece.pos; + let rotation = pool_piece.rotation; + + for block in &template.blocks { + let palette_entry = &template.palette[block.state as usize]; + if palette_entry.name == "minecraft:structure_void" { + continue; + } + + if !keep_jigsaws && palette_entry.name == "minecraft:jigsaw" { + let final_state_str = block + .nbt + .as_ref() + .and_then(|n| n.get_string("final_state")) + .unwrap_or("minecraft:air"); + + let entry = + pumpkin_world::generation::structure::template::PaletteEntry::from_string( + final_state_str, + ); + let final_state = + pumpkin_world::generation::structure::template::BlockStateResolver::resolve( + &entry, + rotation, + pumpkin_data::Mirror::default(), + ) + .unwrap_or(pumpkin_data::Block::AIR.default_state); + + let local_pos = rotation.transform_pos(block.pos, template.size); + let world_pos = origin.add(local_pos.x, local_pos.y, local_pos.z); + + world + .set_block_state( + &world_pos, + final_state.id, + pumpkin_world::world::BlockFlags::NOTIFY_ALL, + ) + .await; + continue; + } + + let Some(state) = BlockStateResolver::resolve( + palette_entry, + rotation, + pumpkin_data::Mirror::default(), + ) else { + continue; + }; + + let local_pos = rotation.transform_pos(block.pos, template.size); + let world_pos = origin.add(local_pos.x, local_pos.y, local_pos.z); + + world + .set_block_state( + &world_pos, + state.id, + pumpkin_world::world::BlockFlags::NOTIFY_ALL, + ) + .await; + + // Handle block entities + if let Some(nbt) = &block.nbt { + let mut block_entity_nbt = nbt.clone(); + block_entity_nbt.put_int("x", world_pos.0.x); + block_entity_nbt.put_int("y", world_pos.0.y); + block_entity_nbt.put_int("z", world_pos.0.z); + if let Some(block_entity) = + crate::block::entities::block_entity_from_nbt(&block_entity_nbt) + { + world.add_block_entity(block_entity); + } + } + } + } + } + } + + const fn to_front_top(orientation: Orientation) -> (BlockDirection, BlockDirection) { + match orientation { + Orientation::DownEast => (BlockDirection::Down, BlockDirection::East), + Orientation::DownNorth => (BlockDirection::Down, BlockDirection::North), + Orientation::DownSouth => (BlockDirection::Down, BlockDirection::South), + Orientation::DownWest => (BlockDirection::Down, BlockDirection::West), + Orientation::UpEast => (BlockDirection::Up, BlockDirection::East), + Orientation::UpNorth => (BlockDirection::Up, BlockDirection::North), + Orientation::UpSouth => (BlockDirection::Up, BlockDirection::South), + Orientation::UpWest => (BlockDirection::Up, BlockDirection::West), + Orientation::WestUp => (BlockDirection::West, BlockDirection::Up), + Orientation::EastUp => (BlockDirection::East, BlockDirection::Up), + Orientation::NorthUp => (BlockDirection::North, BlockDirection::Up), + Orientation::SouthUp => (BlockDirection::South, BlockDirection::Up), + } + } +} + +impl BlockEntity for JigsawBlockEntity { + fn resource_location(&self) -> &'static str { + Self::ID + } + fn get_position(&self) -> BlockPos { + self.position + } + + fn from_nbt(nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self + where + Self: Sized, + { + let name = Mutex::new( + nbt.get_string("name") + .unwrap_or("minecraft:empty") + .to_string(), + ); + let target = Mutex::new( + nbt.get_string("target") + .unwrap_or("minecraft:empty") + .to_string(), + ); + let pool = Mutex::new( + nbt.get_string("pool") + .unwrap_or("minecraft:empty") + .to_string(), + ); + let final_state = Mutex::new( + nbt.get_string("final_state") + .unwrap_or("minecraft:air") + .to_string(), + ); + let joint = Mutex::new(JigsawJointType::from_str( + nbt.get_string("joint").unwrap_or("rollable"), + )); + let selection_priority = AtomicI32::new(nbt.get_int("selection_priority").unwrap_or(0)); + let placement_priority = AtomicI32::new(nbt.get_int("placement_priority").unwrap_or(0)); + + Self { + position, + name, + target, + pool, + final_state, + joint, + selection_priority, + placement_priority, + dirty: AtomicBool::new(false), + } + } + + fn write_nbt<'a>( + &'a self, + nbt: &'a mut NbtCompound, + ) -> Pin + Send + 'a>> { + Box::pin(async { + nbt.put_string("name", self.name.lock().await.to_string()); + nbt.put_string("target", self.target.lock().await.to_string()); + nbt.put_string("pool", self.pool.lock().await.to_string()); + nbt.put_string("final_state", self.final_state.lock().await.to_string()); + let joint = *self.joint.lock().await; + nbt.put_string( + "joint", + match joint { + JigsawJointType::Rollable => "rollable".to_string(), + JigsawJointType::Aligned => "aligned".to_string(), + }, + ); + nbt.put_int( + "selection_priority", + self.selection_priority.load(Ordering::SeqCst), + ); + nbt.put_int( + "placement_priority", + self.placement_priority.load(Ordering::SeqCst), + ); + }) + } + + fn chunk_data_nbt(&self) -> Option { + let mut nbt = NbtCompound::new(); + futures::executor::block_on(async { + self.write_nbt(&mut nbt).await; + }); + Some(nbt) + } + + fn is_dirty(&self) -> bool { + self.dirty.load(Ordering::Relaxed) + } + + fn as_any(&self) -> &dyn std::any::Any { + self + } +} diff --git a/pumpkin/src/block/entities/mod.rs b/pumpkin/src/block/entities/mod.rs index f78c50282..a16c53ef0 100644 --- a/pumpkin/src/block/entities/mod.rs +++ b/pumpkin/src/block/entities/mod.rs @@ -27,6 +27,7 @@ pub mod ender_chest; pub mod furnace; pub mod furnace_like_block_entity; pub mod hopper; +pub mod jigsaw_block; pub mod jukebox; pub mod lectern; pub mod mob_spawner; @@ -198,6 +199,9 @@ pub fn block_entity_from_nbt(nbt: &NbtCompound) -> Option> command_block::CommandBlockEntity::ID => Some(Arc::new( command_block::CommandBlockEntity::from_nbt(nbt, pos), )), + jigsaw_block::JigsawBlockEntity::ID => Some(Arc::new( + jigsaw_block::JigsawBlockEntity::from_nbt(nbt, pos), + )), comparator::ComparatorBlockEntity::ID => Some(Arc::new( comparator::ComparatorBlockEntity::from_nbt(nbt, pos), )), diff --git a/pumpkin/src/block/mod.rs b/pumpkin/src/block/mod.rs index 5980eea6b..fc1ef7b45 100644 --- a/pumpkin/src/block/mod.rs +++ b/pumpkin/src/block/mod.rs @@ -21,6 +21,7 @@ use crate::block::registry::BlockActionResult; use crate::entity::EntityBase; use crate::server::Server; use pumpkin_data::BlockDirection; +use pumpkin_data::block_rotation::{Mirror, Rotation}; use pumpkin_data::item_stack::ItemStack; use pumpkin_protocol::java::server::play::SUseItemOn; use pumpkin_util::math::boundingbox::BoundingBox; @@ -210,6 +211,14 @@ pub trait BlockBehaviour: Send + Sync { ) -> BlockFuture<'a, BoundingBox> { Box::pin(async move { BoundingBox::full_block() }) } + + fn mirror(&self, block: &Block, state_id: u16, mirror: Mirror) -> &'static BlockState { + block.mirror(state_id, mirror) + } + + fn rotate(&self, block: &Block, state_id: u16, rotation: Rotation) -> &'static BlockState { + block.rotate(state_id, rotation) + } } pub struct NormalUseArgs<'a> { diff --git a/pumpkin/src/block/registry.rs b/pumpkin/src/block/registry.rs index c11316a05..c6aa8cafc 100644 --- a/pumpkin/src/block/registry.rs +++ b/pumpkin/src/block/registry.rs @@ -40,6 +40,7 @@ use crate::block::blocks::grindstone::GrindstoneBlock; use crate::block::blocks::hay::HayBlock; use crate::block::blocks::infested::InfestedBlock; use crate::block::blocks::iron_bars::IronBarsBlock; +use crate::block::blocks::jigsaw::JigsawBlock; use crate::block::blocks::logs::LogBlock; use crate::block::blocks::magma::MagmaBlock; use crate::block::blocks::mangrove_roots::MangroveRootsBlock; @@ -136,6 +137,7 @@ use crate::entity::EntityBase; use crate::entity::player::Player; use crate::server::Server; use crate::world::World; +use pumpkin_data::block_rotation::{Mirror, Rotation}; use pumpkin_data::fluid::Fluid; use pumpkin_data::item::Item; use pumpkin_data::item_stack::ItemStack; @@ -262,6 +264,7 @@ pub fn default_registry() -> Arc { manager.register(PumpkinBlock); manager.register(WetSpongeBlock); manager.register(CommandBlock); + manager.register(JigsawBlock); manager.register(ComposterBlock); manager.register(PressurePlateBlock); manager.register(WeightedPressurePlateBlock); @@ -1017,4 +1020,20 @@ impl BlockRegistry { } BoundingBox::full_block() } + + #[must_use] + pub fn mirror(&self, block: &Block, state_id: u16, mirror: Mirror) -> &'static BlockState { + self.get_pumpkin_block(block.id).map_or_else( + || block.mirror(state_id, mirror), + |pumpkin_block| pumpkin_block.mirror(block, state_id, mirror), + ) + } + + #[must_use] + pub fn rotate(&self, block: &Block, state_id: u16, rotation: Rotation) -> &'static BlockState { + self.get_pumpkin_block(block.id).map_or_else( + || block.rotate(state_id, rotation), + |pumpkin_block| pumpkin_block.rotate(block, state_id, rotation), + ) + } } diff --git a/pumpkin/src/net/java/mod.rs b/pumpkin/src/net/java/mod.rs index 75da32aee..59edad4b0 100644 --- a/pumpkin/src/net/java/mod.rs +++ b/pumpkin/src/net/java/mod.rs @@ -16,11 +16,11 @@ use pumpkin_protocol::java::server::play::{ SAttack, SChangeGameMode, SChatCommand, SChatMessage, SChunkBatch, SClickSlot, SClientCommand, SClientInformationPlay, SClientTickEnd, SCloseContainer, SCommandSuggestion, SConfirmTeleport, SContainerButtonClick, SCookieResponse as SPCookieResponse, SCustomPayload, SInteract, - SMoveVehicle, SPaddleBoat, SPickItemFromBlock, SPlaceRecipe, SPlayPingRequest, + SJigsawGenerate, SMoveVehicle, SPaddleBoat, SPickItemFromBlock, SPlaceRecipe, SPlayPingRequest, SPlayerAbilities, SPlayerAction, SPlayerCommand, SPlayerInput, SPlayerLoaded, SPlayerPosition, SPlayerPositionRotation, SPlayerRotation, SPlayerSession, SRecipeBookChangeSettings, SRecipeBookSeenRecipe, SRenameItem, SSelectTrade, SSetCommandBlock, SSetCreativeSlot, - SSetHeldItem, SSetPlayerGround, SSwingArm, SUpdateSign, SUseItem, SUseItemOn, + SSetHeldItem, SSetJigsawBlock, SSetPlayerGround, SSwingArm, SUpdateSign, SUseItem, SUseItemOn, }; use pumpkin_protocol::packet::MultiVersionJavaPacket; use pumpkin_protocol::{ @@ -967,6 +967,14 @@ impl JavaClient { self.handle_set_command_block(player, SSetCommandBlock::read(payload, &version)?) .await; } + id if id == SSetJigsawBlock::to_id(version) => { + self.handle_set_jigsaw_block(player, SSetJigsawBlock::read(payload, &version)?) + .await; + } + id if id == SJigsawGenerate::to_id(version) => { + self.handle_jigsaw_generate(player, SJigsawGenerate::read(payload, &version)?) + .await; + } id if id == SPlayerCommand::to_id(version) => { self.handle_player_command( player, diff --git a/pumpkin/src/net/java/play.rs b/pumpkin/src/net/java/play.rs index 02d77f544..29f62320e 100644 --- a/pumpkin/src/net/java/play.rs +++ b/pumpkin/src/net/java/play.rs @@ -34,6 +34,7 @@ use crate::plugin::player::player_toggle_flight_event::PlayerToggleFlightEvent; use crate::plugin::player::player_toggle_sneak_event::PlayerToggleSneakEvent; use crate::block::entities::command_block::CommandBlockEntity; +use crate::block::entities::jigsaw_block::JigsawBlockEntity; use crate::block::entities::sign::SignBlockEntity; use crate::plugin::player::player_toggle_sprint_event::PlayerToggleSprintEvent; use crate::server::{Server, seasonal_events}; @@ -66,17 +67,19 @@ use pumpkin_protocol::java::server::play::{ Action, ActionType, CommandBlockMode, FLAG_ON_GROUND, SAttack, SChangeGameMode, SChatCommand, SChatMessage, SChunkBatch, SClientCommand, SClientInformationPlay, SCloseContainer, SCommandSuggestion, SConfirmTeleport, SCookieResponse as SPCookieResponse, SInteract, - SKeepAlive, SMoveVehicle, SPaddleBoat, SPickItemFromBlock, SPlaceRecipe, SPlayPingRequest, - SPlayerAbilities, SPlayerAction, SPlayerCommand, SPlayerInput, SPlayerPosition, - SPlayerPositionRotation, SPlayerRotation, SPlayerSession, SRecipeBookChangeSettings, - SRecipeBookSeenRecipe, SSelectTrade, SSetCommandBlock, SSetCreativeSlot, SSetHeldItem, - SSetPlayerGround, SSwingArm, SUpdateSign, SUseItem, SUseItemOn, Status, + SJigsawGenerate, SKeepAlive, SMoveVehicle, SPaddleBoat, SPickItemFromBlock, SPlaceRecipe, + SPlayPingRequest, SPlayerAbilities, SPlayerAction, SPlayerCommand, SPlayerInput, + SPlayerPosition, SPlayerPositionRotation, SPlayerRotation, SPlayerSession, + SRecipeBookChangeSettings, SRecipeBookSeenRecipe, SSelectTrade, SSetCommandBlock, + SSetCreativeSlot, SSetHeldItem, SSetJigsawBlock, SSetPlayerGround, SSwingArm, SUpdateSign, + SUseItem, SUseItemOn, Status, }; use pumpkin_util::math::boundingbox::BoundingBox; use pumpkin_util::math::vector3::Vector3; use pumpkin_util::math::{polynomial_rolling_hash, position::BlockPos, wrap_degrees}; use pumpkin_util::text::color::NamedColor; use pumpkin_util::{GameMode, text::TextComponent}; +use pumpkin_world::generation::structure::structures::jigsaw::JigsawJointType; use pumpkin_world::world::BlockFlags; use tokio::sync::Mutex; @@ -838,6 +841,55 @@ impl JavaClient { } } + pub async fn handle_set_jigsaw_block(&self, player: &Arc, jigsaw: SSetJigsawBlock) { + if !player.is_creative() { + return; + } + if player.permission_lvl.load() < PermissionLvl::Two { + return; + } + let pos = jigsaw.pos; + if let Some(block_entity) = player.world().get_block_entity(&pos) { + if block_entity.resource_location() != JigsawBlockEntity::ID { + warn!("Client tried to change Jigsaw block but not Jigsaw block entity found"); + return; + } + + let jigsaw_block: &JigsawBlockEntity = block_entity.as_any().downcast_ref().unwrap(); + + *jigsaw_block.name.lock().await = jigsaw.name; + *jigsaw_block.target.lock().await = jigsaw.target; + *jigsaw_block.pool.lock().await = jigsaw.pool; + *jigsaw_block.final_state.lock().await = jigsaw.final_state; + *jigsaw_block.joint.lock().await = JigsawJointType::from_str(&jigsaw.joint); + jigsaw_block + .selection_priority + .store(jigsaw.selection_priority.0, Ordering::SeqCst); + jigsaw_block + .placement_priority + .store(jigsaw.placement_priority.0, Ordering::SeqCst); + + player.world().update_block_entity(&block_entity); + } + } + + pub async fn handle_jigsaw_generate(&self, player: &Arc, generate: SJigsawGenerate) { + if !player.is_creative() { + return; + } + if player.permission_lvl.load() < PermissionLvl::Two { + return; + } + let pos = generate.pos; + if let Some(block_entity) = player.world().get_block_entity(&pos) + && let Some(jigsaw_block) = block_entity.as_any().downcast_ref::() + { + jigsaw_block + .generate(&player.world(), generate.levels.0, generate.keep_jigsaws) + .await; + } + } + pub async fn handle_player_command( &self, player: &Arc, diff --git a/pumpkin/src/world/mod.rs b/pumpkin/src/world/mod.rs index 9c9bbff9b..4553c744f 100644 --- a/pumpkin/src/world/mod.rs +++ b/pumpkin/src/world/mod.rs @@ -52,6 +52,7 @@ use bytes::BufMut; use explosion::Explosion; use pumpkin_config::BasicConfiguration; use pumpkin_data::block_properties::is_air; +use pumpkin_data::block_rotation::{Mirror, Rotation}; use pumpkin_data::chunk_gen_settings::GenerationSettings; use pumpkin_data::data_component_impl::EquipmentSlot; use pumpkin_data::dimension::Dimension; @@ -4994,6 +4995,14 @@ impl WorldPortalExt for WorldPortal { ) } + fn mirror(&self, block: &Block, state_id: u16, mirror: Mirror) -> &'static BlockState { + self.0.block_registry.mirror(block, state_id, mirror) + } + + fn rotate(&self, block: &Block, state_id: u16, rotation: Rotation) -> &'static BlockState { + self.0.block_registry.rotate(block, state_id, rotation) + } + fn spawn_mobs_for_chunk_generation( &self, cache: &mut dyn GenerationCache,