Refactored Banner logic for better reusablilty

This commit is contained in:
Luigi
2026-04-08 12:39:58 +02:00
parent 5fa06be0a7
commit 71f18c2f47
2 changed files with 65 additions and 43 deletions

View File

@@ -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,
);
}
}
}
}
}

View File

@@ -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<Value> = 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);