diff --git a/src/element_processing/highways.rs b/src/element_processing/highways.rs index a881b65..d416374 100644 --- a/src/element_processing/highways.rs +++ b/src/element_processing/highways.rs @@ -121,14 +121,6 @@ fn generate_highways_internal( editor.set_block(BLACK_WOOL, x, 4, z, None, None); editor.set_block(BLACK_WOOL, x, 5, z, None, None); - let banner_patterns_list = fastnbt::nbt!([ - { "color": "red", "pattern": "minecraft:triangle_top" }, - { "color": "lime", "pattern": "minecraft:triangle_bottom" }, - { "color": "yellow", "pattern": "minecraft:circle" }, - { "color": "black", "pattern": "minecraft:curly_border" }, - { "color": "black", "pattern": "minecraft:border" } - ]); - // Banner placement logic let abs_y = editor.get_absolute_y(x, 5, z); let banner_offsets: [(i32, i32, &str); 4] = [ @@ -138,7 +130,7 @@ fn generate_highways_internal( (1, 0, "east"), ]; - // The 5 patterns expressed as (java_color, java_pattern_id) pairs + // patterns expressed as (java_color, java_pattern_id) pairs // so both Java and Bedrock writers can consume them. const BANNER_PATTERNS: &[(&str, &str)] = &[ ("red", "minecraft:triangle_top"), @@ -149,39 +141,13 @@ fn generate_highways_internal( ]; for (dx, dz, facing) in &banner_offsets { - let bx = x + dx; - let bz = z + dz; - - // Apply Block rotation - editor.set_block_with_properties_absolute( - crate::block_definitions::BlockWithProperties::new( - LIGHT_GRAY_WALL_BANNER, - Some(fastnbt::nbt!({ "facing": facing })), - ), - bx, abs_y, bz, None, None, + editor.place_wall_banner( + LIGHT_GRAY_WALL_BANNER, + x + dx, abs_y, z + dz, + facing, + "light_gray", + BANNER_PATTERNS, ); - - // Write banner block entity in the correct format for - // the current output format (Java vs Bedrock). - match editor.format() { - crate::world_editor::WorldFormat::JavaAnvil => { - editor.set_banner_block_entity_absolute( - bx, - abs_y, - bz, - banner_patterns_list.clone(), - ); - } - crate::world_editor::WorldFormat::BedrockMcWorld => { - editor.set_bedrock_banner_block_entity_absolute( - bx, - abs_y, - bz, - "light_gray", - BANNER_PATTERNS, - ); - } - } } } } diff --git a/src/world_editor/mod.rs b/src/world_editor/mod.rs index dee950a..197cb4e 100644 --- a/src/world_editor/mod.rs +++ b/src/world_editor/mod.rs @@ -237,6 +237,46 @@ impl<'a> WorldEditor<'a> { self.world.get_block(x, absolute_y, z).is_some() } + pub fn place_wall_banner( + &mut self, + block: Block, // e.g. LIGHT_GRAY_WALL_BANNER + x: i32, + y: i32, // ground-relative + z: i32, + facing: &str, // "north" / "south" / "east" / "west" + base_color: &str, // "light_gray" etc. + patterns: &[(&str, &str)], // [("red", "minecraft:triangle_top"), ...] + ) { + // Apply Block rotation + self.set_block_with_properties_absolute( + crate::block_definitions::BlockWithProperties::new( + block, + Some(fastnbt::nbt!({ "facing": facing })), + ), + x, y, z, None, None, + ); + match self.format() { + + crate::world_editor::WorldFormat::JavaAnvil => { + self.set_banner_block_entity_absolute( + x, + y, + z, + patterns, + ); + } + crate::world_editor::WorldFormat::BedrockMcWorld => { + self.set_bedrock_banner_block_entity_absolute( + x, + y, + z, + base_color, + patterns, + ); + } + } + } + /// Places a banner block entity at the given coordinates (absolute Y). /// This writes the pattern data into the chunk's block_entities list, /// which is required for the banner patterns to appear in-game. @@ -246,7 +286,7 @@ impl<'a> WorldEditor<'a> { x: i32, absolute_y: i32, z: i32, - patterns_list: Value, + patterns_list: &[(&str, &str)], ) { if !self.xzbbox.contains(&XZPoint::new(x, z)) { return; @@ -263,7 +303,23 @@ impl<'a> WorldEditor<'a> { be.insert("y".to_string(), Value::Int(absolute_y)); be.insert("z".to_string(), Value::Int(z)); be.insert("keepPacked".to_string(), Value::Byte(0)); - be.insert("patterns".to_string(), patterns_list); + let patterns: Vec = patterns_list + .iter() + .map(|(color, pattern)| { + let mut entry = HashMap::new(); + + entry.insert( + "color".to_string(), + Value::String(color.to_string()), + ); + entry.insert( + "pattern".to_string(), + Value::String(pattern.to_string()), + ); + Value::Compound(entry) + }) + .collect(); + be.insert("patterns".to_string(), Value::List(patterns)); be.insert("components".to_string(), Value::Compound(HashMap::new())); let region = self.world.get_or_create_region(region_x, region_z);