diff --git a/CHANGELOG.md b/CHANGELOG.md index fccf759..b702c8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ ## [Unreleased] - ReleaseDate +### Added + +- Added sign layer + + This feature is disabled by default. Use the `--sign-prefix` and `--sign-filter` options to + configure which signs to show on the map. + ### Changed - Without `--verbose`, only a single warning is printed at the end of diff --git a/Cargo.lock b/Cargo.lock index ab7a97a..e50f306 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,6 +29,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + [[package]] name = "allocator-api2" version = "0.2.16" @@ -70,7 +79,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -80,7 +89,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -125,6 +134,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + [[package]] name = "bytemuck" version = "1.14.0" @@ -179,6 +194,7 @@ dependencies = [ "anstyle", "clap_lex", "strsim", + "terminal_size", ] [[package]] @@ -287,6 +303,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "fastnbt" version = "2.4.4" @@ -481,6 +507,12 @@ dependencies = [ "libc", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" + [[package]] name = "lock_api" version = "0.4.11" @@ -531,6 +563,7 @@ dependencies = [ "num-integer", "num_cpus", "rayon", + "regex", "rustc-hash", "serde", "serde_json", @@ -698,7 +731,7 @@ version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" dependencies = [ - "bitflags", + "bitflags 1.3.2", "crc32fast", "fdeflate", "flate2", @@ -749,9 +782,38 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -764,6 +826,19 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustix" +version = "0.38.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + [[package]] name = "ryu" version = "1.0.16" @@ -863,6 +938,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "terminal_size" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +dependencies = [ + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "thread_local" version = "1.1.7" @@ -987,6 +1072,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + [[package]] name = "windows-sys" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index f1b3094..5442162 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ pre-release-replacements = [ [dependencies] anyhow = "1.0.68" bincode = "1.3.3" -clap = { version = "4.1.4", features = ["derive"] } +clap = { version = "4.1.4", features = ["derive", "wrap_help"] } fastnbt = "2.3.2" futures-util = "0.3.28" git-version = "0.3.5" @@ -52,6 +52,7 @@ minedmap-types = { version = "0.1.2", path = "crates/types" } num-integer = "0.1.45" num_cpus = "1.16.0" rayon = "1.7.0" +regex = "1.10.2" rustc-hash = "1.1.0" serde = { version = "1.0.152", features = ["rc", "derive"] } serde_json = "1.0.99" diff --git a/README.md b/README.md index be09c47..824b670 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ based on [Leaflet](https://leafletjs.com/). The map renderer is heavily inspired ## How to use Minecraft stores its save data in a directory `~/.minecraft/saves` on Linux, -and `C:\Users\\AppData\Roaming\.minecraft\saves`. To generate minedmap +and `C:\Users\\AppData\Roaming\.minecraft\saves`. To generate MinedMap tile data from a save game called "World", use the a command like the following (replacing the first argument with the path to your save data; `viewer` refers to the directory where you unpacked the MinedMap viewer): @@ -47,6 +47,34 @@ This test server is very slow and cannot handle multiple requests concurrently, a proper webserver like [nginx](https://nginx.org/) or upload the viewer together with the generated map files to public webspace to make the map available to others. +### Signs + +![Sign screenshot](https://raw.githubusercontent.com/neocturne/MinedMap/e5d9c813ba3118d04dc7e52e3dc6f48808a69120/docs/images/signs.png) + +MinedMap can display sign markers on the map, which will open a popup showing +the sign text when clicked. + +Generation of the sign layer is disabled by default. It can be enabled by passing +the `--sign-prefix` or `--sign-filter` options to MinedMap. The options allow +to configure which signs should be displayed, and they can be passed multiple +times to show every sign that matches at least one prefix or filter. + +`--sign-prefix` will make all signs visible the text of which starts with the +given prefix, so something like `--sign-prefix '[Map]'` would allow to put up +signs that start with "\[Map\]" in Minecraft to add markers to the map. An +empty prefix (`--sign-prefix ''`) can be used to make *all* signs visible on +the map. + +`--sign-filter` can be used for more advanced filters based on regular expressions. +`--sign-filter '\[Map\]'` would show all signs that contain "\[Map\]" +anywhere in their text, and `--sign-filter '.'` makes all non-empty signs (signs +containing at least one character) visible. See the documentation of the +[regex crate](https://docs.rs/regex) for more information on the supported syntax. + +All prefixes and filters are applied to the front and back text separately, but +both the front and the back text will be shown in the popup when one of them +matches. + ## Installation Binary builds of the map generator for Linux and Windows, as well as an archive diff --git a/crates/resource/src/block_color.rs b/crates/resource/src/block_color.rs index cffebeb..e95e0ed 100644 --- a/crates/resource/src/block_color.rs +++ b/crates/resource/src/block_color.rs @@ -1,6 +1,6 @@ //! Functions for computations of block colors -use super::{Biome, BlockType, Color, Colorf}; +use super::{Biome, BlockColor, Color, Colorf}; /// Converts an u8 RGB color to a float vector fn color_vec_unscaled(color: Color) -> Colorf { @@ -91,18 +91,18 @@ const BIRCH_COLOR: Colorf = Colorf::new(0.502, 0.655, 0.333); // == color_vec(Co /// Color multiplier for spruce leaves const EVERGREEN_COLOR: Colorf = Colorf::new(0.380, 0.600, 0.380); // == color_vec(Color([97, 153, 97])) -/// Determined if calling [block_color] for a given [BlockType] needs biome information -pub fn needs_biome(block: BlockType) -> bool { +/// Determined if calling [block_color] for a given [BlockColor] needs biome information +pub fn needs_biome(block: BlockColor) -> bool { use super::BlockFlag::*; block.is(Grass) || block.is(Foliage) || block.is(Water) } -/// Determined the block color to display for a given [BlockType] +/// Determined the block color to display for a given [BlockColor] /// /// [needs_biome] must be used to determine whether passing a [Biome] is necessary. /// Will panic if a [Biome] is necessary, but none is passed. -pub fn block_color(block: BlockType, biome: Option<&Biome>, depth: f32) -> Colorf { +pub fn block_color(block: BlockColor, biome: Option<&Biome>, depth: f32) -> Colorf { use super::BlockFlag::*; let get_biome = || biome.expect("needs biome to determine block color"); diff --git a/crates/resource/src/block_types.rs b/crates/resource/src/block_types.rs index a70106c..6229016 100644 --- a/crates/resource/src/block_types.rs +++ b/crates/resource/src/block_types.rs @@ -2,7068 +2,10095 @@ use enumflags2::make_bitflags; use super::*; -pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ +pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ ( "acacia_button", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "acacia_door", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([167, 95, 60]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([167, 95, 60]), + }, + sign_material: None, }, ), ( "acacia_fence", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([168, 90, 50]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([168, 90, 50]), + }, + sign_material: None, }, ), ( "acacia_fence_gate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([168, 90, 50]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([168, 90, 50]), + }, + sign_material: None, }, ), ( "acacia_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("acacia"), }, ), ( "acacia_leaves", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), - color: Color([149, 148, 148]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), + color: Color([149, 148, 148]), + }, + sign_material: None, }, ), ( "acacia_log", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([150, 88, 55]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([150, 88, 55]), + }, + sign_material: None, }, ), ( "acacia_planks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([168, 90, 50]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([168, 90, 50]), + }, + sign_material: None, }, ), ( "acacia_pressure_plate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([168, 90, 50]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([168, 90, 50]), + }, + sign_material: None, }, ), ( "acacia_sapling", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([118, 117, 23]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([118, 117, 23]), + }, + sign_material: None, }, ), ( "acacia_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([168, 90, 50]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("acacia"), }, ), ( "acacia_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([168, 90, 50]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([168, 90, 50]), + }, + sign_material: None, }, ), ( "acacia_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([168, 90, 50]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([168, 90, 50]), + }, + sign_material: None, }, ), ( "acacia_trapdoor", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([156, 87, 51]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([156, 87, 51]), + }, + sign_material: None, }, ), ( "acacia_wall_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("acacia"), }, ), ( "acacia_wall_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("acacia"), }, ), ( "acacia_wood", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([103, 96, 86]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([103, 96, 86]), + }, + sign_material: None, }, ), ( "activator_rail", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([115, 87, 74]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([115, 87, 74]), + }, + sign_material: None, }, ), ( "air", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "allium", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "amethyst_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([133, 97, 191]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([133, 97, 191]), + }, + sign_material: None, }, ), ( "amethyst_cluster", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([163, 126, 207]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([163, 126, 207]), + }, + sign_material: None, }, ), ( "ancient_debris", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([94, 66, 58]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([94, 66, 58]), + }, + sign_material: None, }, ), ( "andesite", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([136, 136, 136]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([136, 136, 136]), + }, + sign_material: None, }, ), ( "andesite_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([136, 136, 136]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([136, 136, 136]), + }, + sign_material: None, }, ), ( "andesite_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([136, 136, 136]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([136, 136, 136]), + }, + sign_material: None, }, ), ( "andesite_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([136, 136, 136]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([136, 136, 136]), + }, + sign_material: None, }, ), ( "anvil", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([72, 72, 72]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([72, 72, 72]), + }, + sign_material: None, }, ), ( "attached_melon_stem", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: Color([141, 142, 141]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([141, 142, 141]), + }, + sign_material: None, }, ), ( "attached_pumpkin_stem", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: Color([139, 139, 139]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([139, 139, 139]), + }, + sign_material: None, }, ), ( "azalea", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([101, 124, 47]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([101, 124, 47]), + }, + sign_material: None, }, ), ( "azalea_leaves", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([90, 114, 44]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([90, 114, 44]), + }, + sign_material: None, }, ), ( "azure_bluet", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "bamboo", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([93, 144, 19]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([93, 144, 19]), + }, + sign_material: None, }, ), ( "bamboo_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([139, 141, 62]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([139, 141, 62]), + }, + sign_material: None, }, ), ( "bamboo_button", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "bamboo_door", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([191, 171, 81]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([191, 171, 81]), + }, + sign_material: None, }, ), ( "bamboo_fence", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([193, 173, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 173, 80]), + }, + sign_material: None, }, ), ( "bamboo_fence_gate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([193, 173, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 173, 80]), + }, + sign_material: None, }, ), ( "bamboo_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("bamboo"), }, ), ( "bamboo_mosaic", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([190, 170, 78]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([190, 170, 78]), + }, + sign_material: None, }, ), ( "bamboo_mosaic_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([190, 170, 78]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([190, 170, 78]), + }, + sign_material: None, }, ), ( "bamboo_mosaic_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([190, 170, 78]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([190, 170, 78]), + }, + sign_material: None, }, ), ( "bamboo_planks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([193, 173, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 173, 80]), + }, + sign_material: None, }, ), ( "bamboo_pressure_plate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([193, 173, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 173, 80]), + }, + sign_material: None, }, ), ( "bamboo_sapling", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "bamboo_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([193, 173, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("bamboo"), }, ), ( "bamboo_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([193, 173, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 173, 80]), + }, + sign_material: None, }, ), ( "bamboo_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([193, 173, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 173, 80]), + }, + sign_material: None, }, ), ( "bamboo_trapdoor", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([198, 179, 85]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([198, 179, 85]), + }, + sign_material: None, }, ), ( "bamboo_wall_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("bamboo"), }, ), ( "bamboo_wall_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("bamboo"), }, ), ( "barrel", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([134, 100, 58]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([134, 100, 58]), + }, + sign_material: None, }, ), ( "barrier", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "basalt", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([80, 81, 86]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([80, 81, 86]), + }, + sign_material: None, }, ), ( "beacon", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 220, 215]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([117, 220, 215]), + }, + sign_material: None, }, ), ( "bedrock", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([85, 85, 85]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([85, 85, 85]), + }, + sign_material: None, }, ), ( "bee_nest", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([202, 160, 74]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([202, 160, 74]), + }, + sign_material: None, }, ), ( "beehive", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([180, 146, 90]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([180, 146, 90]), + }, + sign_material: None, }, ), ( "beetroots", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([93, 91, 30]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([93, 91, 30]), + }, + sign_material: None, }, ), ( "bell", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([253, 235, 110]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([253, 235, 110]), + }, + sign_material: None, }, ), ( "big_dripleaf", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([111, 141, 51]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([111, 141, 51]), + }, + sign_material: None, }, ), ( "big_dripleaf_stem", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "birch_button", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "birch_door", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([220, 209, 176]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([220, 209, 176]), + }, + sign_material: None, }, ), ( "birch_fence", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 175, 121]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 175, 121]), + }, + sign_material: None, }, ), ( "birch_fence_gate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 175, 121]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 175, 121]), + }, + sign_material: None, }, ), ( "birch_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("birch"), }, ), ( "birch_leaves", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Birch}), - color: Color([130, 129, 130]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Birch}), + color: Color([130, 129, 130]), + }, + sign_material: None, }, ), ( "birch_log", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([193, 179, 135]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 179, 135]), + }, + sign_material: None, }, ), ( "birch_planks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 175, 121]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 175, 121]), + }, + sign_material: None, }, ), ( "birch_pressure_plate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 175, 121]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 175, 121]), + }, + sign_material: None, }, ), ( "birch_sapling", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([127, 160, 79]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([127, 160, 79]), + }, + sign_material: None, }, ), ( "birch_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 175, 121]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("birch"), }, ), ( "birch_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 175, 121]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 175, 121]), + }, + sign_material: None, }, ), ( "birch_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 175, 121]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 175, 121]), + }, + sign_material: None, }, ), ( "birch_trapdoor", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([207, 194, 157]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([207, 194, 157]), + }, + sign_material: None, }, ), ( "birch_wall_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("birch"), }, ), ( "birch_wall_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("birch"), }, ), ( "birch_wood", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([216, 215, 210]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([216, 215, 210]), + }, + sign_material: None, }, ), ( "black_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "black_bed", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "black_candle", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "black_candle_cake", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, + sign_material: None, }, ), ( "black_carpet", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([20, 21, 25]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([20, 21, 25]), + }, + sign_material: None, }, ), ( "black_concrete", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([8, 10, 15]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([8, 10, 15]), + }, + sign_material: None, }, ), ( "black_concrete_powder", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([25, 26, 31]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([25, 26, 31]), + }, + sign_material: None, }, ), ( "black_glazed_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([67, 30, 32]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([67, 30, 32]), + }, + sign_material: None, }, ), ( "black_shulker_box", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([25, 25, 29]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([25, 25, 29]), + }, + sign_material: None, }, ), ( "black_stained_glass", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([25, 25, 25]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([25, 25, 25]), + }, + sign_material: None, }, ), ( "black_stained_glass_pane", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([24, 24, 24]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([24, 24, 24]), + }, + sign_material: None, }, ), ( "black_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([37, 22, 16]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([37, 22, 16]), + }, + sign_material: None, }, ), ( "black_wall_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "black_wool", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([20, 21, 25]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([20, 21, 25]), + }, + sign_material: None, }, ), ( "blackstone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([42, 36, 41]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([42, 36, 41]), + }, + sign_material: None, }, ), ( "blackstone_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([42, 36, 41]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([42, 36, 41]), + }, + sign_material: None, }, ), ( "blackstone_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([42, 36, 41]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([42, 36, 41]), + }, + sign_material: None, }, ), ( "blackstone_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([42, 36, 41]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([42, 36, 41]), + }, + sign_material: None, }, ), ( "blast_furnace", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([80, 80, 81]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([80, 80, 81]), + }, + sign_material: None, }, ), ( "blue_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "blue_bed", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "blue_candle", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "blue_candle_cake", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, + sign_material: None, }, ), ( "blue_carpet", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([53, 57, 157]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([53, 57, 157]), + }, + sign_material: None, }, ), ( "blue_concrete", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 46, 143]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 46, 143]), + }, + sign_material: None, }, ), ( "blue_concrete_powder", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([70, 73, 166]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([70, 73, 166]), + }, + sign_material: None, }, ), ( "blue_glazed_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([47, 64, 139]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([47, 64, 139]), + }, + sign_material: None, }, ), ( "blue_ice", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([116, 167, 253]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([116, 167, 253]), + }, + sign_material: None, }, ), ( "blue_orchid", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "blue_shulker_box", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([43, 45, 140]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([43, 45, 140]), + }, + sign_material: None, }, ), ( "blue_stained_glass", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([51, 76, 178]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([51, 76, 178]), + }, + sign_material: None, }, ), ( "blue_stained_glass_pane", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([48, 73, 171]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([48, 73, 171]), + }, + sign_material: None, }, ), ( "blue_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([74, 59, 91]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([74, 59, 91]), + }, + sign_material: None, }, ), ( "blue_wall_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "blue_wool", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([53, 57, 157]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([53, 57, 157]), + }, + sign_material: None, }, ), ( "bone_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([209, 206, 179]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([209, 206, 179]), + }, + sign_material: None, }, ), ( "bookshelf", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, + sign_material: None, }, ), ( "brain_coral", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "brain_coral_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([207, 91, 159]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([207, 91, 159]), + }, + sign_material: None, }, ), ( "brain_coral_fan", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "brain_coral_wall_fan", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "brewing_stand", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([122, 100, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([122, 100, 80]), + }, + sign_material: None, }, ), ( "brick_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([150, 97, 83]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([150, 97, 83]), + }, + sign_material: None, }, ), ( "brick_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([150, 97, 83]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([150, 97, 83]), + }, + sign_material: None, }, ), ( "brick_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([150, 97, 83]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([150, 97, 83]), + }, + sign_material: None, }, ), ( "bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([150, 97, 83]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([150, 97, 83]), + }, + sign_material: None, }, ), ( "brown_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "brown_bed", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "brown_candle", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "brown_candle_cake", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, + sign_material: None, }, ), ( "brown_carpet", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 71, 40]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 71, 40]), + }, + sign_material: None, }, ), ( "brown_concrete", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([96, 59, 31]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([96, 59, 31]), + }, + sign_material: None, }, ), ( "brown_concrete_powder", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([125, 84, 53]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([125, 84, 53]), + }, + sign_material: None, }, ), ( "brown_glazed_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([119, 106, 85]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([119, 106, 85]), + }, + sign_material: None, }, ), ( "brown_mushroom", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "brown_mushroom_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([149, 111, 81]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([149, 111, 81]), + }, + sign_material: None, }, ), ( "brown_shulker_box", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([106, 66, 35]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([106, 66, 35]), + }, + sign_material: None, }, ), ( "brown_stained_glass", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([102, 76, 51]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([102, 76, 51]), + }, + sign_material: None, }, ), ( "brown_stained_glass_pane", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([97, 73, 48]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([97, 73, 48]), + }, + sign_material: None, }, ), ( "brown_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([77, 51, 35]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([77, 51, 35]), + }, + sign_material: None, }, ), ( "brown_wall_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "brown_wool", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 71, 40]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 71, 40]), + }, + sign_material: None, }, ), ( "bubble_column", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Water}), - color: Color([177, 177, 177]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Water}), + color: Color([177, 177, 177]), + }, + sign_material: None, }, ), ( "bubble_coral", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "bubble_coral_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([165, 26, 162]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([165, 26, 162]), + }, + sign_material: None, }, ), ( "bubble_coral_fan", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "bubble_coral_wall_fan", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "budding_amethyst", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([132, 96, 186]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([132, 96, 186]), + }, + sign_material: None, }, ), ( "cactus", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([85, 127, 43]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([85, 127, 43]), + }, + sign_material: None, }, ), ( "cake", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, + sign_material: None, }, ), ( "calcite", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 224, 220]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 224, 220]), + }, + sign_material: None, }, ), ( "calibrated_sculk_sensor", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([27, 79, 100]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([27, 79, 100]), + }, + sign_material: None, }, ), ( "campfire", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([110, 88, 54]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 88, 54]), + }, + sign_material: None, }, ), ( "candle", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "candle_cake", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, + sign_material: None, }, ), ( "carrots", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([81, 124, 37]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([81, 124, 37]), + }, + sign_material: None, }, ), ( "cartography_table", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([103, 87, 67]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([103, 87, 67]), + }, + sign_material: None, }, ), ( "carved_pumpkin", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([198, 118, 24]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([198, 118, 24]), + }, + sign_material: None, }, ), ( "cauldron", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([73, 72, 74]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([73, 72, 74]), + }, + sign_material: None, }, ), ( "cave_air", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "cave_vines", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([90, 109, 40]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([90, 109, 40]), + }, + sign_material: None, }, ), ( "cave_vines_plant", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([88, 101, 38]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([88, 101, 38]), + }, + sign_material: None, }, ), ( "chain", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "chain_command_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([131, 161, 147]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([131, 161, 147]), + }, + sign_material: None, }, ), ( "cherry_button", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "cherry_door", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 170, 164]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 170, 164]), + }, + sign_material: None, }, ), ( "cherry_fence", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([226, 178, 172]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, + sign_material: None, }, ), ( "cherry_fence_gate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([226, 178, 172]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, + sign_material: None, }, ), ( "cherry_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("cherry"), }, ), ( "cherry_leaves", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([229, 172, 194]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([229, 172, 194]), + }, + sign_material: None, }, ), ( "cherry_log", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([185, 141, 137]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([185, 141, 137]), + }, + sign_material: None, }, ), ( "cherry_planks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([226, 178, 172]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, + sign_material: None, }, ), ( "cherry_pressure_plate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([226, 178, 172]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, + sign_material: None, }, ), ( "cherry_sapling", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "cherry_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([226, 178, 172]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("cherry"), }, ), ( "cherry_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([226, 178, 172]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, + sign_material: None, }, ), ( "cherry_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([226, 178, 172]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, + sign_material: None, }, ), ( "cherry_trapdoor", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([226, 178, 172]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, + sign_material: None, }, ), ( "cherry_wall_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("cherry"), }, ), ( "cherry_wall_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("cherry"), }, ), ( "cherry_wood", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([54, 33, 44]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([54, 33, 44]), + }, + sign_material: None, }, ), ( "chest", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, + sign_material: None, }, ), ( "chipped_anvil", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([72, 72, 72]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([72, 72, 72]), + }, + sign_material: None, }, ), ( "chiseled_bookshelf", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([178, 144, 88]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([178, 144, 88]), + }, + sign_material: None, }, ), ( "chiseled_deepslate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([54, 54, 54]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([54, 54, 54]), + }, + sign_material: None, }, ), ( "chiseled_nether_bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([47, 23, 28]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([47, 23, 28]), + }, + sign_material: None, }, ), ( "chiseled_polished_blackstone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([53, 48, 56]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([53, 48, 56]), + }, + sign_material: None, }, ), ( "chiseled_quartz_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([231, 226, 218]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([231, 226, 218]), + }, + sign_material: None, }, ), ( "chiseled_red_sandstone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 97, 31]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 97, 31]), + }, + sign_material: None, }, ), ( "chiseled_sandstone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 214, 170]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 214, 170]), + }, + sign_material: None, }, ), ( "chiseled_stone_bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([119, 118, 119]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([119, 118, 119]), + }, + sign_material: None, }, ), ( "chorus_flower", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([151, 120, 151]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([151, 120, 151]), + }, + sign_material: None, }, ), ( "chorus_plant", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([93, 57, 93]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([93, 57, 93]), + }, + sign_material: None, }, ), ( "clay", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 166, 179]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 166, 179]), + }, + sign_material: None, }, ), ( "coal_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([16, 15, 15]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([16, 15, 15]), + }, + sign_material: None, }, ), ( "coal_ore", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([105, 105, 105]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([105, 105, 105]), + }, + sign_material: None, }, ), ( "coarse_dirt", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([119, 85, 59]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([119, 85, 59]), + }, + sign_material: None, }, ), ( "cobbled_deepslate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([77, 77, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([77, 77, 80]), + }, + sign_material: None, }, ), ( "cobbled_deepslate_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([77, 77, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([77, 77, 80]), + }, + sign_material: None, }, ), ( "cobbled_deepslate_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([77, 77, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([77, 77, 80]), + }, + sign_material: None, }, ), ( "cobbled_deepslate_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([77, 77, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([77, 77, 80]), + }, + sign_material: None, }, ), ( "cobblestone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([127, 127, 127]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([127, 127, 127]), + }, + sign_material: None, }, ), ( "cobblestone_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([127, 127, 127]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([127, 127, 127]), + }, + sign_material: None, }, ), ( "cobblestone_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([127, 127, 127]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([127, 127, 127]), + }, + sign_material: None, }, ), ( "cobblestone_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([127, 127, 127]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([127, 127, 127]), + }, + sign_material: None, }, ), ( "cobweb", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([228, 233, 234]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([228, 233, 234]), + }, + sign_material: None, }, ), ( "cocoa", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 91, 40]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 91, 40]), + }, + sign_material: None, }, ), ( "command_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 136, 108]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 136, 108]), + }, + sign_material: None, }, ), ( "comparator", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([166, 161, 159]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([166, 161, 159]), + }, + sign_material: None, }, ), ( "composter", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([88, 61, 23]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([88, 61, 23]), + }, + sign_material: None, }, ), ( "conduit", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([159, 139, 113]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([159, 139, 113]), + }, + sign_material: None, }, ), ( "copper_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 107, 79]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 107, 79]), + }, + sign_material: None, }, ), ( "copper_ore", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([124, 125, 120]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([124, 125, 120]), + }, + sign_material: None, }, ), ( "cornflower", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "cracked_deepslate_bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([64, 64, 65]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([64, 64, 65]), + }, + sign_material: None, }, ), ( "cracked_deepslate_tiles", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([52, 52, 52]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([52, 52, 52]), + }, + sign_material: None, }, ), ( "cracked_nether_bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([40, 20, 23]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([40, 20, 23]), + }, + sign_material: None, }, ), ( "cracked_polished_blackstone_bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 37, 43]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 37, 43]), + }, + sign_material: None, }, ), ( "cracked_stone_bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([118, 117, 118]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([118, 117, 118]), + }, + sign_material: None, }, ), ( "crafting_table", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([119, 73, 42]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([119, 73, 42]), + }, + sign_material: None, }, ), ( "creeper_head", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "creeper_wall_head", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "crimson_button", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "crimson_door", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 54, 79]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 54, 79]), + }, + sign_material: None, }, ), ( "crimson_fence", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([101, 48, 70]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([101, 48, 70]), + }, + sign_material: None, }, ), ( "crimson_fence_gate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([101, 48, 70]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([101, 48, 70]), + }, + sign_material: None, }, ), ( "crimson_fungus", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "crimson_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("crimson"), }, ), ( "crimson_hyphae", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([92, 25, 29]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([92, 25, 29]), + }, + sign_material: None, }, ), ( "crimson_nylium", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([130, 31, 31]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([130, 31, 31]), + }, + sign_material: None, }, ), ( "crimson_planks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([101, 48, 70]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([101, 48, 70]), + }, + sign_material: None, }, ), ( "crimson_pressure_plate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([101, 48, 70]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([101, 48, 70]), + }, + sign_material: None, }, ), ( "crimson_roots", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([126, 8, 41]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([126, 8, 41]), + }, + sign_material: None, }, ), ( "crimson_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([101, 48, 70]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("crimson"), }, ), ( "crimson_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([101, 48, 70]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([101, 48, 70]), + }, + sign_material: None, }, ), ( "crimson_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([101, 48, 70]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([101, 48, 70]), + }, + sign_material: None, }, ), ( "crimson_stem", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([112, 49, 70]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([112, 49, 70]), + }, + sign_material: None, }, ), ( "crimson_trapdoor", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([103, 50, 72]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([103, 50, 72]), + }, + sign_material: None, }, ), ( "crimson_wall_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("crimson"), }, ), ( "crimson_wall_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("crimson"), }, ), ( "crying_obsidian", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([32, 10, 60]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([32, 10, 60]), + }, + sign_material: None, }, ), ( "cut_copper", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([191, 106, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([191, 106, 80]), + }, + sign_material: None, }, ), ( "cut_copper_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([191, 106, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([191, 106, 80]), + }, + sign_material: None, }, ), ( "cut_copper_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([191, 106, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([191, 106, 80]), + }, + sign_material: None, }, ), ( "cut_red_sandstone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 97, 31]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 97, 31]), + }, + sign_material: None, }, ), ( "cut_red_sandstone_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 97, 31]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 97, 31]), + }, + sign_material: None, }, ), ( "cut_sandstone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 214, 170]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 214, 170]), + }, + sign_material: None, }, ), ( "cut_sandstone_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 214, 170]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 214, 170]), + }, + sign_material: None, }, ), ( "cyan_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "cyan_bed", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "cyan_candle", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "cyan_candle_cake", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, + sign_material: None, }, ), ( "cyan_carpet", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([21, 137, 145]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([21, 137, 145]), + }, + sign_material: None, }, ), ( "cyan_concrete", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([21, 119, 136]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([21, 119, 136]), + }, + sign_material: None, }, ), ( "cyan_concrete_powder", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([36, 147, 157]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([36, 147, 157]), + }, + sign_material: None, }, ), ( "cyan_glazed_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([52, 118, 125]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([52, 118, 125]), + }, + sign_material: None, }, ), ( "cyan_shulker_box", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([20, 121, 135]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([20, 121, 135]), + }, + sign_material: None, }, ), ( "cyan_stained_glass", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([76, 127, 153]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([76, 127, 153]), + }, + sign_material: None, }, ), ( "cyan_stained_glass_pane", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([73, 122, 147]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([73, 122, 147]), + }, + sign_material: None, }, ), ( "cyan_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([86, 91, 91]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([86, 91, 91]), + }, + sign_material: None, }, ), ( "cyan_wall_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "cyan_wool", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([21, 137, 145]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([21, 137, 145]), + }, + sign_material: None, }, ), ( "damaged_anvil", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([72, 72, 72]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([72, 72, 72]), + }, + sign_material: None, }, ), ( "dandelion", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "dark_oak_button", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "dark_oak_door", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([76, 51, 25]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([76, 51, 25]), + }, + sign_material: None, }, ), ( "dark_oak_fence", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([66, 43, 20]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([66, 43, 20]), + }, + sign_material: None, }, ), ( "dark_oak_fence_gate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([66, 43, 20]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([66, 43, 20]), + }, + sign_material: None, }, ), ( "dark_oak_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("dark_oak"), }, ), ( "dark_oak_leaves", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), - color: Color([150, 150, 150]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), + color: Color([150, 150, 150]), + }, + sign_material: None, }, ), ( "dark_oak_log", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([67, 45, 22]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([67, 45, 22]), + }, + sign_material: None, }, ), ( "dark_oak_planks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([66, 43, 20]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([66, 43, 20]), + }, + sign_material: None, }, ), ( "dark_oak_pressure_plate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([66, 43, 20]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([66, 43, 20]), + }, + sign_material: None, }, ), ( "dark_oak_sapling", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([61, 90, 30]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([61, 90, 30]), + }, + sign_material: None, }, ), ( "dark_oak_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([66, 43, 20]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("dark_oak"), }, ), ( "dark_oak_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([66, 43, 20]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([66, 43, 20]), + }, + sign_material: None, }, ), ( "dark_oak_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([66, 43, 20]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([66, 43, 20]), + }, + sign_material: None, }, ), ( "dark_oak_trapdoor", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([75, 49, 23]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([75, 49, 23]), + }, + sign_material: None, }, ), ( "dark_oak_wall_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("dark_oak"), }, ), ( "dark_oak_wall_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("dark_oak"), }, ), ( "dark_oak_wood", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([60, 46, 26]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([60, 46, 26]), + }, + sign_material: None, }, ), ( "dark_prismarine", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([51, 91, 75]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([51, 91, 75]), + }, + sign_material: None, }, ), ( "dark_prismarine_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([51, 91, 75]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([51, 91, 75]), + }, + sign_material: None, }, ), ( "dark_prismarine_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([51, 91, 75]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([51, 91, 75]), + }, + sign_material: None, }, ), ( "daylight_detector", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([130, 116, 94]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([130, 116, 94]), + }, + sign_material: None, }, ), ( "dead_brain_coral", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "dead_brain_coral_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([124, 117, 114]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([124, 117, 114]), + }, + sign_material: None, }, ), ( "dead_brain_coral_fan", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "dead_brain_coral_wall_fan", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "dead_bubble_coral", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "dead_bubble_coral_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([131, 123, 119]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([131, 123, 119]), + }, + sign_material: None, }, ), ( "dead_bubble_coral_fan", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "dead_bubble_coral_wall_fan", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "dead_bush", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([107, 78, 40]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([107, 78, 40]), + }, + sign_material: None, }, ), ( "dead_fire_coral", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "dead_fire_coral_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([131, 123, 119]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([131, 123, 119]), + }, + sign_material: None, }, ), ( "dead_fire_coral_fan", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "dead_fire_coral_wall_fan", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "dead_horn_coral", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "dead_horn_coral_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([133, 126, 122]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([133, 126, 122]), + }, + sign_material: None, }, ), ( "dead_horn_coral_fan", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "dead_horn_coral_wall_fan", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "dead_tube_coral", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "dead_tube_coral_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([130, 123, 119]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([130, 123, 119]), + }, + sign_material: None, }, ), ( "dead_tube_coral_fan", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "dead_tube_coral_wall_fan", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "decorated_pot", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([124, 68, 53]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([124, 68, 53]), + }, + sign_material: None, }, ), ( "deepslate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([80, 80, 82]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([80, 80, 82]), + }, + sign_material: None, }, ), ( "deepslate_brick_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([70, 70, 71]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([70, 70, 71]), + }, + sign_material: None, }, ), ( "deepslate_brick_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([70, 70, 71]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([70, 70, 71]), + }, + sign_material: None, }, ), ( "deepslate_brick_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([70, 70, 71]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([70, 70, 71]), + }, + sign_material: None, }, ), ( "deepslate_bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([70, 70, 71]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([70, 70, 71]), + }, + sign_material: None, }, ), ( "deepslate_coal_ore", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([74, 74, 76]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([74, 74, 76]), + }, + sign_material: None, }, ), ( "deepslate_copper_ore", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([92, 93, 89]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([92, 93, 89]), + }, + sign_material: None, }, ), ( "deepslate_diamond_ore", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([83, 106, 106]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([83, 106, 106]), + }, + sign_material: None, }, ), ( "deepslate_emerald_ore", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([78, 104, 87]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([78, 104, 87]), + }, + sign_material: None, }, ), ( "deepslate_gold_ore", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([115, 102, 78]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([115, 102, 78]), + }, + sign_material: None, }, ), ( "deepslate_iron_ore", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([106, 99, 94]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([106, 99, 94]), + }, + sign_material: None, }, ), ( "deepslate_lapis_ore", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([79, 90, 115]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([79, 90, 115]), + }, + sign_material: None, }, ), ( "deepslate_redstone_ore", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([104, 73, 74]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([104, 73, 74]), + }, + sign_material: None, }, ), ( "deepslate_tile_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([54, 54, 55]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([54, 54, 55]), + }, + sign_material: None, }, ), ( "deepslate_tile_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([54, 54, 55]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([54, 54, 55]), + }, + sign_material: None, }, ), ( "deepslate_tile_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([54, 54, 55]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([54, 54, 55]), + }, + sign_material: None, }, ), ( "deepslate_tiles", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([54, 54, 55]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([54, 54, 55]), + }, + sign_material: None, }, ), ( "detector_rail", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([123, 104, 90]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([123, 104, 90]), + }, + sign_material: None, }, ), ( "diamond_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([98, 237, 228]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([98, 237, 228]), + }, + sign_material: None, }, ), ( "diamond_ore", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([121, 141, 140]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([121, 141, 140]), + }, + sign_material: None, }, ), ( "diorite", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([188, 188, 188]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([188, 188, 188]), + }, + sign_material: None, }, ), ( "diorite_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([188, 188, 188]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([188, 188, 188]), + }, + sign_material: None, }, ), ( "diorite_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([188, 188, 188]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([188, 188, 188]), + }, + sign_material: None, }, ), ( "diorite_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([188, 188, 188]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([188, 188, 188]), + }, + sign_material: None, }, ), ( "dirt", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([134, 96, 67]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([134, 96, 67]), + }, + sign_material: None, }, ), ( "dirt_path", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([148, 121, 65]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([148, 121, 65]), + }, + sign_material: None, }, ), ( "dispenser", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([110, 109, 109]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 109, 109]), + }, + sign_material: None, }, ), ( "dragon_egg", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([12, 9, 15]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([12, 9, 15]), + }, + sign_material: None, }, ), ( "dragon_head", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "dragon_wall_head", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "dried_kelp_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([50, 58, 38]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([50, 58, 38]), + }, + sign_material: None, }, ), ( "dripstone_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([134, 107, 92]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([134, 107, 92]), + }, + sign_material: None, }, ), ( "dropper", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([110, 109, 109]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 109, 109]), + }, + sign_material: None, }, ), ( "emerald_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([42, 203, 87]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([42, 203, 87]), + }, + sign_material: None, }, ), ( "emerald_ore", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([108, 136, 115]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([108, 136, 115]), + }, + sign_material: None, }, ), ( "enchanting_table", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([128, 75, 85]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([128, 75, 85]), + }, + sign_material: None, }, ), ( "end_gateway", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([15, 10, 24]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([15, 10, 24]), + }, + sign_material: None, }, ), ( "end_portal", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([15, 10, 24]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([15, 10, 24]), + }, + sign_material: None, }, ), ( "end_portal_frame", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([91, 120, 97]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([91, 120, 97]), + }, + sign_material: None, }, ), ( "end_rod", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "end_stone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([219, 222, 158]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([219, 222, 158]), + }, + sign_material: None, }, ), ( "end_stone_brick_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([218, 224, 162]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([218, 224, 162]), + }, + sign_material: None, }, ), ( "end_stone_brick_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([218, 224, 162]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([218, 224, 162]), + }, + sign_material: None, }, ), ( "end_stone_brick_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([218, 224, 162]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([218, 224, 162]), + }, + sign_material: None, }, ), ( "end_stone_bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([218, 224, 162]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([218, 224, 162]), + }, + sign_material: None, }, ), ( "ender_chest", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([15, 10, 24]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([15, 10, 24]), + }, + sign_material: None, }, ), ( "exposed_copper", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([161, 125, 103]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([161, 125, 103]), + }, + sign_material: None, }, ), ( "exposed_cut_copper", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 121, 101]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 121, 101]), + }, + sign_material: None, }, ), ( "exposed_cut_copper_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 121, 101]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 121, 101]), + }, + sign_material: None, }, ), ( "exposed_cut_copper_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 121, 101]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 121, 101]), + }, + sign_material: None, }, ), ( "farmland", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([81, 44, 15]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([81, 44, 15]), + }, + sign_material: None, }, ), ( "fern", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "fire", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([211, 140, 53]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([211, 140, 53]), + }, + sign_material: None, }, ), ( "fire_coral", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "fire_coral_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([163, 35, 46]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([163, 35, 46]), + }, + sign_material: None, }, ), ( "fire_coral_fan", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "fire_coral_wall_fan", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "fletching_table", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([197, 180, 133]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([197, 180, 133]), + }, + sign_material: None, }, ), ( "flower_pot", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([124, 68, 53]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([124, 68, 53]), + }, + sign_material: None, }, ), ( "flowering_azalea", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([112, 121, 64]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([112, 121, 64]), + }, + sign_material: None, }, ), ( "flowering_azalea_leaves", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 111, 60]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 111, 60]), + }, + sign_material: None, }, ), ( "frogspawn", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([105, 90, 82]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([105, 90, 82]), + }, + sign_material: None, }, ), ( "frosted_ice", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([140, 181, 252]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([140, 181, 252]), + }, + sign_material: None, }, ), ( "furnace", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([110, 109, 109]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 109, 109]), + }, + sign_material: None, }, ), ( "gilded_blackstone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([55, 42, 38]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([55, 42, 38]), + }, + sign_material: None, }, ), ( "glass", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([175, 213, 219]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([175, 213, 219]), + }, + sign_material: None, }, ), ( "glass_pane", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([170, 210, 217]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([170, 210, 217]), + }, + sign_material: None, }, ), ( "glow_item_frame", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "glow_lichen", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "glowstone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([171, 131, 84]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([171, 131, 84]), + }, + sign_material: None, }, ), ( "gold_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([246, 208, 61]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([246, 208, 61]), + }, + sign_material: None, }, ), ( "gold_ore", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([145, 133, 106]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([145, 133, 106]), + }, + sign_material: None, }, ), ( "granite", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([149, 103, 85]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([149, 103, 85]), + }, + sign_material: None, }, ), ( "granite_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([149, 103, 85]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([149, 103, 85]), + }, + sign_material: None, }, ), ( "granite_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([149, 103, 85]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([149, 103, 85]), + }, + sign_material: None, }, ), ( "granite_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([149, 103, 85]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([149, 103, 85]), + }, + sign_material: None, }, ), ( "grass", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "grass_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: Color([147, 147, 147]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([147, 147, 147]), + }, + sign_material: None, }, ), ( "grass_path", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([148, 121, 65]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([148, 121, 65]), + }, + sign_material: None, }, ), ( "gravel", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([131, 127, 126]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([131, 127, 126]), + }, + sign_material: None, }, ), ( "gray_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "gray_bed", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "gray_candle", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "gray_candle_cake", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, + sign_material: None, }, ), ( "gray_carpet", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([62, 68, 71]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([62, 68, 71]), + }, + sign_material: None, }, ), ( "gray_concrete", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([54, 57, 61]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([54, 57, 61]), + }, + sign_material: None, }, ), ( "gray_concrete_powder", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([76, 81, 84]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([76, 81, 84]), + }, + sign_material: None, }, ), ( "gray_glazed_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([83, 90, 93]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([83, 90, 93]), + }, + sign_material: None, }, ), ( "gray_shulker_box", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([55, 58, 62]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([55, 58, 62]), + }, + sign_material: None, }, ), ( "gray_stained_glass", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([76, 76, 76]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([76, 76, 76]), + }, + sign_material: None, }, ), ( "gray_stained_glass_pane", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([73, 73, 73]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([73, 73, 73]), + }, + sign_material: None, }, ), ( "gray_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([57, 42, 35]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([57, 42, 35]), + }, + sign_material: None, }, ), ( "gray_wall_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "gray_wool", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([62, 68, 71]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([62, 68, 71]), + }, + sign_material: None, }, ), ( "green_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "green_bed", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "green_candle", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "green_candle_cake", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, + sign_material: None, }, ), ( "green_carpet", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([84, 109, 27]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([84, 109, 27]), + }, + sign_material: None, }, ), ( "green_concrete", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([73, 91, 36]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([73, 91, 36]), + }, + sign_material: None, }, ), ( "green_concrete_powder", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([97, 119, 44]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([97, 119, 44]), + }, + sign_material: None, }, ), ( "green_glazed_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 142, 67]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([117, 142, 67]), + }, + sign_material: None, }, ), ( "green_shulker_box", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([79, 100, 31]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([79, 100, 31]), + }, + sign_material: None, }, ), ( "green_stained_glass", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([102, 127, 51]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([102, 127, 51]), + }, + sign_material: None, }, ), ( "green_stained_glass_pane", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([97, 122, 48]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([97, 122, 48]), + }, + sign_material: None, }, ), ( "green_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([76, 83, 42]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([76, 83, 42]), + }, + sign_material: None, }, ), ( "green_wall_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "green_wool", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([84, 109, 27]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([84, 109, 27]), + }, + sign_material: None, }, ), ( "grindstone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([142, 142, 142]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([142, 142, 142]), + }, + sign_material: None, }, ), ( "hanging_roots", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([161, 115, 91]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([161, 115, 91]), + }, + sign_material: None, }, ), ( "hay_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([165, 139, 12]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([165, 139, 12]), + }, + sign_material: None, }, ), ( "heavy_weighted_pressure_plate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([220, 220, 220]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([220, 220, 220]), + }, + sign_material: None, }, ), ( "honey_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([251, 185, 52]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([251, 185, 52]), + }, + sign_material: None, }, ), ( "honeycomb_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([229, 148, 29]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([229, 148, 29]), + }, + sign_material: None, }, ), ( "hopper", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([75, 74, 75]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([75, 74, 75]), + }, + sign_material: None, }, ), ( "horn_coral", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "horn_coral_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([216, 199, 66]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([216, 199, 66]), + }, + sign_material: None, }, ), ( "horn_coral_fan", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "horn_coral_wall_fan", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "ice", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([145, 183, 253]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([145, 183, 253]), + }, + sign_material: None, }, ), ( "infested_chiseled_stone_bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([119, 118, 119]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([119, 118, 119]), + }, + sign_material: None, }, ), ( "infested_cobblestone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([127, 127, 127]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([127, 127, 127]), + }, + sign_material: None, }, ), ( "infested_cracked_stone_bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([118, 117, 118]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([118, 117, 118]), + }, + sign_material: None, }, ), ( "infested_deepslate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([80, 80, 82]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([80, 80, 82]), + }, + sign_material: None, }, ), ( "infested_mossy_stone_bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([115, 121, 105]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([115, 121, 105]), + }, + sign_material: None, }, ), ( "infested_stone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([125, 125, 125]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([125, 125, 125]), + }, + sign_material: None, }, ), ( "infested_stone_bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([122, 121, 122]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([122, 121, 122]), + }, + sign_material: None, }, ), ( "iron_bars", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([136, 139, 135]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([136, 139, 135]), + }, + sign_material: None, }, ), ( "iron_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([220, 220, 220]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([220, 220, 220]), + }, + sign_material: None, }, ), ( "iron_door", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([194, 193, 193]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([194, 193, 193]), + }, + sign_material: None, }, ), ( "iron_ore", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([136, 129, 122]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([136, 129, 122]), + }, + sign_material: None, }, ), ( "iron_trapdoor", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([202, 202, 202]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([202, 202, 202]), + }, + sign_material: None, }, ), ( "item_frame", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "jack_o_lantern", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([214, 152, 52]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([214, 152, 52]), + }, + sign_material: None, }, ), ( "jigsaw", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([80, 69, 81]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([80, 69, 81]), + }, + sign_material: None, }, ), ( "jukebox", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([93, 64, 47]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([93, 64, 47]), + }, + sign_material: None, }, ), ( "jungle_button", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "jungle_door", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([163, 119, 84]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([163, 119, 84]), + }, + sign_material: None, }, ), ( "jungle_fence", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 115, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 115, 80]), + }, + sign_material: None, }, ), ( "jungle_fence_gate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 115, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 115, 80]), + }, + sign_material: None, }, ), ( "jungle_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("jungle"), }, ), ( "jungle_leaves", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), - color: Color([156, 154, 143]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), + color: Color([156, 154, 143]), + }, + sign_material: None, }, ), ( "jungle_log", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([149, 109, 70]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([149, 109, 70]), + }, + sign_material: None, }, ), ( "jungle_planks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 115, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 115, 80]), + }, + sign_material: None, }, ), ( "jungle_pressure_plate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 115, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 115, 80]), + }, + sign_material: None, }, ), ( "jungle_sapling", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([47, 81, 16]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([47, 81, 16]), + }, + sign_material: None, }, ), ( "jungle_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 115, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("jungle"), }, ), ( "jungle_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 115, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 115, 80]), + }, + sign_material: None, }, ), ( "jungle_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 115, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 115, 80]), + }, + sign_material: None, }, ), ( "jungle_trapdoor", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([152, 110, 77]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([152, 110, 77]), + }, + sign_material: None, }, ), ( "jungle_wall_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("jungle"), }, ), ( "jungle_wall_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("jungle"), }, ), ( "jungle_wood", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([85, 67, 25]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([85, 67, 25]), + }, + sign_material: None, }, ), ( "kelp", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "kelp_plant", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([86, 130, 42]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([86, 130, 42]), + }, + sign_material: None, }, ), ( "ladder", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "lantern", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([106, 91, 83]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([106, 91, 83]), + }, + sign_material: None, }, ), ( "lapis_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([30, 67, 140]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([30, 67, 140]), + }, + sign_material: None, }, ), ( "lapis_ore", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([107, 117, 141]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([107, 117, 141]), + }, + sign_material: None, }, ), ( "large_amethyst_bud", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "large_fern", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: Color([125, 125, 125]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([125, 125, 125]), + }, + sign_material: None, }, ), ( "lava", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([212, 90, 18]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([212, 90, 18]), + }, + sign_material: None, }, ), ( "lava_cauldron", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([73, 72, 74]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([73, 72, 74]), + }, + sign_material: None, }, ), ( "lectern", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([173, 137, 83]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([173, 137, 83]), + }, + sign_material: None, }, ), ( "lever", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "light", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "light_blue_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "light_blue_bed", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "light_blue_candle", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "light_blue_candle_cake", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, + sign_material: None, }, ), ( "light_blue_carpet", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([58, 175, 217]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([58, 175, 217]), + }, + sign_material: None, }, ), ( "light_blue_concrete", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([35, 137, 198]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([35, 137, 198]), + }, + sign_material: None, }, ), ( "light_blue_concrete_powder", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([74, 180, 213]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([74, 180, 213]), + }, + sign_material: None, }, ), ( "light_blue_glazed_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([94, 164, 208]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([94, 164, 208]), + }, + sign_material: None, }, ), ( "light_blue_shulker_box", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([49, 163, 212]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([49, 163, 212]), + }, + sign_material: None, }, ), ( "light_blue_stained_glass", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([102, 153, 216]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([102, 153, 216]), + }, + sign_material: None, }, ), ( "light_blue_stained_glass_pane", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([97, 147, 208]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([97, 147, 208]), + }, + sign_material: None, }, ), ( "light_blue_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([113, 108, 137]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([113, 108, 137]), + }, + sign_material: None, }, ), ( "light_blue_wall_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "light_blue_wool", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([58, 175, 217]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([58, 175, 217]), + }, + sign_material: None, }, ), ( "light_gray_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "light_gray_bed", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "light_gray_candle", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "light_gray_candle_cake", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, + sign_material: None, }, ), ( "light_gray_carpet", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([142, 142, 134]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([142, 142, 134]), + }, + sign_material: None, }, ), ( "light_gray_concrete", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([125, 125, 115]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([125, 125, 115]), + }, + sign_material: None, }, ), ( "light_gray_concrete_powder", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 154, 148]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 154, 148]), + }, + sign_material: None, }, ), ( "light_gray_glazed_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([144, 166, 167]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([144, 166, 167]), + }, + sign_material: None, }, ), ( "light_gray_shulker_box", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([124, 124, 115]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([124, 124, 115]), + }, + sign_material: None, }, ), ( "light_gray_stained_glass", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([153, 153, 153]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([153, 153, 153]), + }, + sign_material: None, }, ), ( "light_gray_stained_glass_pane", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([147, 147, 147]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([147, 147, 147]), + }, + sign_material: None, }, ), ( "light_gray_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([135, 106, 97]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([135, 106, 97]), + }, + sign_material: None, }, ), ( "light_gray_wall_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "light_gray_wool", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([142, 142, 134]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([142, 142, 134]), + }, + sign_material: None, }, ), ( "light_weighted_pressure_plate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([246, 208, 61]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([246, 208, 61]), + }, + sign_material: None, }, ), ( "lightning_rod", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "lilac", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 125, 147]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 125, 147]), + }, + sign_material: None, }, ), ( "lily_of_the_valley", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "lily_pad", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: Color([133, 133, 133]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([133, 133, 133]), + }, + sign_material: None, }, ), ( "lime_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "lime_bed", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "lime_candle", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "lime_candle_cake", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, + sign_material: None, }, ), ( "lime_carpet", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([112, 185, 25]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([112, 185, 25]), + }, + sign_material: None, }, ), ( "lime_concrete", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([94, 168, 24]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([94, 168, 24]), + }, + sign_material: None, }, ), ( "lime_concrete_powder", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([125, 189, 41]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([125, 189, 41]), + }, + sign_material: None, }, ), ( "lime_glazed_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 197, 55]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 197, 55]), + }, + sign_material: None, }, ), ( "lime_shulker_box", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 172, 23]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 172, 23]), + }, + sign_material: None, }, ), ( "lime_stained_glass", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([127, 204, 25]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([127, 204, 25]), + }, + sign_material: None, }, ), ( "lime_stained_glass_pane", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([122, 196, 24]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([122, 196, 24]), + }, + sign_material: None, }, ), ( "lime_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([103, 117, 52]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([103, 117, 52]), + }, + sign_material: None, }, ), ( "lime_wall_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "lime_wool", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([112, 185, 25]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([112, 185, 25]), + }, + sign_material: None, }, ), ( "lodestone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([147, 149, 152]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([147, 149, 152]), + }, + sign_material: None, }, ), ( "loom", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([142, 119, 91]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([142, 119, 91]), + }, + sign_material: None, }, ), ( "magenta_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "magenta_bed", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "magenta_candle", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "magenta_candle_cake", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, + sign_material: None, }, ), ( "magenta_carpet", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([189, 68, 179]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([189, 68, 179]), + }, + sign_material: None, }, ), ( "magenta_concrete", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([169, 48, 159]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([169, 48, 159]), + }, + sign_material: None, }, ), ( "magenta_concrete_powder", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 83, 184]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 83, 184]), + }, + sign_material: None, }, ), ( "magenta_glazed_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([208, 100, 191]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([208, 100, 191]), + }, + sign_material: None, }, ), ( "magenta_shulker_box", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([173, 54, 163]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([173, 54, 163]), + }, + sign_material: None, }, ), ( "magenta_stained_glass", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([178, 76, 216]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([178, 76, 216]), + }, + sign_material: None, }, ), ( "magenta_stained_glass_pane", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([171, 73, 208]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([171, 73, 208]), + }, + sign_material: None, }, ), ( "magenta_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([149, 88, 108]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([149, 88, 108]), + }, + sign_material: None, }, ), ( "magenta_wall_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "magenta_wool", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([189, 68, 179]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([189, 68, 179]), + }, + sign_material: None, }, ), ( "magma_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([142, 63, 31]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([142, 63, 31]), + }, + sign_material: None, }, ), ( "mangrove_button", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "mangrove_door", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([112, 48, 46]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([112, 48, 46]), + }, + sign_material: None, }, ), ( "mangrove_fence", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 54, 48]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([117, 54, 48]), + }, + sign_material: None, }, ), ( "mangrove_fence_gate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 54, 48]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([117, 54, 48]), + }, + sign_material: None, }, ), ( "mangrove_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("mangrove"), }, ), ( "mangrove_leaves", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), - color: Color([129, 128, 128]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), + color: Color([129, 128, 128]), + }, + sign_material: None, }, ), ( "mangrove_log", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([102, 48, 42]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([102, 48, 42]), + }, + sign_material: None, }, ), ( "mangrove_planks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 54, 48]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([117, 54, 48]), + }, + sign_material: None, }, ), ( "mangrove_pressure_plate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 54, 48]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([117, 54, 48]), + }, + sign_material: None, }, ), ( "mangrove_propagule", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([96, 174, 83]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([96, 174, 83]), + }, + sign_material: None, }, ), ( "mangrove_roots", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([74, 59, 38]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([74, 59, 38]), + }, + sign_material: None, }, ), ( "mangrove_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 54, 48]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("mangrove"), }, ), ( "mangrove_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 54, 48]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([117, 54, 48]), + }, + sign_material: None, }, ), ( "mangrove_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 54, 48]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([117, 54, 48]), + }, + sign_material: None, }, ), ( "mangrove_trapdoor", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([110, 46, 42]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 46, 42]), + }, + sign_material: None, }, ), ( "mangrove_wall_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("mangrove"), }, ), ( "mangrove_wall_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("mangrove"), }, ), ( "mangrove_wood", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([83, 66, 41]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([83, 66, 41]), + }, + sign_material: None, }, ), ( "medium_amethyst_bud", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "melon", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([111, 144, 30]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([111, 144, 30]), + }, + sign_material: None, }, ), ( "melon_stem", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: Color([153, 153, 153]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([153, 153, 153]), + }, + sign_material: None, }, ), ( "moss_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([89, 109, 45]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([89, 109, 45]), + }, + sign_material: None, }, ), ( "moss_carpet", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([89, 109, 45]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([89, 109, 45]), + }, + sign_material: None, }, ), ( "mossy_cobblestone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([110, 118, 94]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 118, 94]), + }, + sign_material: None, }, ), ( "mossy_cobblestone_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([110, 118, 94]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 118, 94]), + }, + sign_material: None, }, ), ( "mossy_cobblestone_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([110, 118, 94]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 118, 94]), + }, + sign_material: None, }, ), ( "mossy_cobblestone_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([110, 118, 94]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 118, 94]), + }, + sign_material: None, }, ), ( "mossy_stone_brick_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([115, 121, 105]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([115, 121, 105]), + }, + sign_material: None, }, ), ( "mossy_stone_brick_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([115, 121, 105]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([115, 121, 105]), + }, + sign_material: None, }, ), ( "mossy_stone_brick_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([115, 121, 105]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([115, 121, 105]), + }, + sign_material: None, }, ), ( "mossy_stone_bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([115, 121, 105]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([115, 121, 105]), + }, + sign_material: None, }, ), ( "moving_piston", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "mud", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([60, 57, 60]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([60, 57, 60]), + }, + sign_material: None, }, ), ( "mud_brick_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([137, 103, 79]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([137, 103, 79]), + }, + sign_material: None, }, ), ( "mud_brick_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([137, 103, 79]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([137, 103, 79]), + }, + sign_material: None, }, ), ( "mud_brick_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([137, 103, 79]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([137, 103, 79]), + }, + sign_material: None, }, ), ( "mud_bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([137, 103, 79]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([137, 103, 79]), + }, + sign_material: None, }, ), ( "muddy_mangrove_roots", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([70, 58, 45]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([70, 58, 45]), + }, + sign_material: None, }, ), ( "mushroom_stem", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([203, 196, 185]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([203, 196, 185]), + }, + sign_material: None, }, ), ( "mycelium", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([111, 98, 101]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([111, 98, 101]), + }, + sign_material: None, }, ), ( "nether_brick_fence", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 21, 26]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 21, 26]), + }, + sign_material: None, }, ), ( "nether_brick_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 21, 26]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 21, 26]), + }, + sign_material: None, }, ), ( "nether_brick_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 21, 26]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 21, 26]), + }, + sign_material: None, }, ), ( "nether_brick_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 21, 26]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 21, 26]), + }, + sign_material: None, }, ), ( "nether_bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 21, 26]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 21, 26]), + }, + sign_material: None, }, ), ( "nether_gold_ore", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([115, 54, 42]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([115, 54, 42]), + }, + sign_material: None, }, ), ( "nether_portal", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([89, 11, 192]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([89, 11, 192]), + }, + sign_material: None, }, ), ( "nether_quartz_ore", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 65, 62]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([117, 65, 62]), + }, + sign_material: None, }, ), ( "nether_sprouts", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([19, 151, 133]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([19, 151, 133]), + }, + sign_material: None, }, ), ( "nether_wart", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([111, 18, 19]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([111, 18, 19]), + }, + sign_material: None, }, ), ( "nether_wart_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 2, 2]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 2, 2]), + }, + sign_material: None, }, ), ( "netherite_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([66, 61, 63]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([66, 61, 63]), + }, + sign_material: None, }, ), ( "netherrack", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([97, 38, 38]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([97, 38, 38]), + }, + sign_material: None, }, ), ( "note_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([88, 58, 40]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([88, 58, 40]), + }, + sign_material: None, }, ), ( "oak_button", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "oak_door", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([140, 110, 66]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([140, 110, 66]), + }, + sign_material: None, }, ), ( "oak_fence", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, + sign_material: None, }, ), ( "oak_fence_gate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, + sign_material: None, }, ), ( "oak_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("oak"), }, ), ( "oak_leaves", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), - color: Color([144, 144, 144]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), + color: Color([144, 144, 144]), + }, + sign_material: None, }, ), ( "oak_log", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([151, 121, 73]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([151, 121, 73]), + }, + sign_material: None, }, ), ( "oak_planks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, + sign_material: None, }, ), ( "oak_pressure_plate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, + sign_material: None, }, ), ( "oak_sapling", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([77, 106, 40]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([77, 106, 40]), + }, + sign_material: None, }, ), ( "oak_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("oak"), }, ), ( "oak_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, + sign_material: None, }, ), ( "oak_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, + sign_material: None, }, ), ( "oak_trapdoor", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([124, 99, 56]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([124, 99, 56]), + }, + sign_material: None, }, ), ( "oak_wall_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("oak"), }, ), ( "oak_wall_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("oak"), }, ), ( "oak_wood", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 85, 50]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 85, 50]), + }, + sign_material: None, }, ), ( "observer", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([98, 98, 98]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([98, 98, 98]), + }, + sign_material: None, }, ), ( "obsidian", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([15, 10, 24]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([15, 10, 24]), + }, + sign_material: None, }, ), ( "ochre_froglight", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([250, 245, 206]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([250, 245, 206]), + }, + sign_material: None, }, ), ( "orange_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "orange_bed", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "orange_candle", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "orange_candle_cake", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, + sign_material: None, }, ), ( "orange_carpet", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([240, 118, 19]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([240, 118, 19]), + }, + sign_material: None, }, ), ( "orange_concrete", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([224, 97, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([224, 97, 0]), + }, + sign_material: None, }, ), ( "orange_concrete_powder", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([227, 131, 31]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([227, 131, 31]), + }, + sign_material: None, }, ), ( "orange_glazed_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 147, 91]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 147, 91]), + }, + sign_material: None, }, ), ( "orange_shulker_box", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([234, 106, 8]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([234, 106, 8]), + }, + sign_material: None, }, ), ( "orange_stained_glass", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([216, 127, 51]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([216, 127, 51]), + }, + sign_material: None, }, ), ( "orange_stained_glass_pane", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([208, 122, 48]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([208, 122, 48]), + }, + sign_material: None, }, ), ( "orange_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([161, 83, 37]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([161, 83, 37]), + }, + sign_material: None, }, ), ( "orange_tulip", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "orange_wall_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "orange_wool", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([240, 118, 19]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([240, 118, 19]), + }, + sign_material: None, }, ), ( "oxeye_daisy", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "oxidized_copper", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([82, 162, 132]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([82, 162, 132]), + }, + sign_material: None, }, ), ( "oxidized_cut_copper", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([79, 153, 126]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([79, 153, 126]), + }, + sign_material: None, }, ), ( "oxidized_cut_copper_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([79, 153, 126]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([79, 153, 126]), + }, + sign_material: None, }, ), ( "oxidized_cut_copper_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([79, 153, 126]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([79, 153, 126]), + }, + sign_material: None, }, ), ( "packed_ice", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([141, 180, 250]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([141, 180, 250]), + }, + sign_material: None, }, ), ( "packed_mud", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([142, 106, 79]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([142, 106, 79]), + }, + sign_material: None, }, ), ( "pearlescent_froglight", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([245, 240, 239]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([245, 240, 239]), + }, + sign_material: None, }, ), ( "peony", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([129, 126, 139]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([129, 126, 139]), + }, + sign_material: None, }, ), ( "petrified_oak_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, + sign_material: None, }, ), ( "piglin_head", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "piglin_wall_head", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "pink_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "pink_bed", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "pink_candle", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "pink_candle_cake", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, + sign_material: None, }, ), ( "pink_carpet", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([237, 141, 172]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([237, 141, 172]), + }, + sign_material: None, }, ), ( "pink_concrete", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([213, 101, 142]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([213, 101, 142]), + }, + sign_material: None, }, ), ( "pink_concrete_powder", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([228, 153, 181]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([228, 153, 181]), + }, + sign_material: None, }, ), ( "pink_glazed_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([235, 154, 181]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([235, 154, 181]), + }, + sign_material: None, }, ), ( "pink_petals", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "pink_shulker_box", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([230, 121, 157]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([230, 121, 157]), + }, + sign_material: None, }, ), ( "pink_stained_glass", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([242, 127, 165]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([242, 127, 165]), + }, + sign_material: None, }, ), ( "pink_stained_glass_pane", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([233, 122, 159]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([233, 122, 159]), + }, + sign_material: None, }, ), ( "pink_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([161, 78, 78]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([161, 78, 78]), + }, + sign_material: None, }, ), ( "pink_tulip", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "pink_wall_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "pink_wool", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([237, 141, 172]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([237, 141, 172]), + }, + sign_material: None, }, ), ( "piston", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 104, 96]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 104, 96]), + }, + sign_material: None, }, ), ( "piston_head", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([153, 127, 85]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([153, 127, 85]), + }, + sign_material: None, }, ), ( "pitcher_crop", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([193, 165, 103]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 165, 103]), + }, + sign_material: None, }, ), ( "pitcher_plant", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([122, 144, 189]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([122, 144, 189]), + }, + sign_material: None, }, ), ( "player_head", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "player_wall_head", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "podzol", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([91, 63, 24]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([91, 63, 24]), + }, + sign_material: None, }, ), ( "pointed_dripstone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([129, 102, 89]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([129, 102, 89]), + }, + sign_material: None, }, ), ( "polished_andesite", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([132, 134, 133]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([132, 134, 133]), + }, + sign_material: None, }, ), ( "polished_andesite_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([132, 134, 133]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([132, 134, 133]), + }, + sign_material: None, }, ), ( "polished_andesite_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([132, 134, 133]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([132, 134, 133]), + }, + sign_material: None, }, ), ( "polished_basalt", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 98, 100]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 98, 100]), + }, + sign_material: None, }, ), ( "polished_blackstone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([53, 48, 56]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([53, 48, 56]), + }, + sign_material: None, }, ), ( "polished_blackstone_brick_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([48, 42, 49]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([48, 42, 49]), + }, + sign_material: None, }, ), ( "polished_blackstone_brick_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([48, 42, 49]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([48, 42, 49]), + }, + sign_material: None, }, ), ( "polished_blackstone_brick_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([48, 42, 49]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([48, 42, 49]), + }, + sign_material: None, }, ), ( "polished_blackstone_bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([48, 42, 49]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([48, 42, 49]), + }, + sign_material: None, }, ), ( "polished_blackstone_button", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "polished_blackstone_pressure_plate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([53, 48, 56]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([53, 48, 56]), + }, + sign_material: None, }, ), ( "polished_blackstone_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([53, 48, 56]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([53, 48, 56]), + }, + sign_material: None, }, ), ( "polished_blackstone_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([53, 48, 56]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([53, 48, 56]), + }, + sign_material: None, }, ), ( "polished_blackstone_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([53, 48, 56]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([53, 48, 56]), + }, + sign_material: None, }, ), ( "polished_deepslate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([72, 72, 73]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([72, 72, 73]), + }, + sign_material: None, }, ), ( "polished_deepslate_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([72, 72, 73]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([72, 72, 73]), + }, + sign_material: None, }, ), ( "polished_deepslate_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([72, 72, 73]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([72, 72, 73]), + }, + sign_material: None, }, ), ( "polished_deepslate_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([72, 72, 73]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([72, 72, 73]), + }, + sign_material: None, }, ), ( "polished_diorite", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 193, 194]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 193, 194]), + }, + sign_material: None, }, ), ( "polished_diorite_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 193, 194]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 193, 194]), + }, + sign_material: None, }, ), ( "polished_diorite_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 193, 194]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 193, 194]), + }, + sign_material: None, }, ), ( "polished_granite", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 106, 89]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 106, 89]), + }, + sign_material: None, }, ), ( "polished_granite_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 106, 89]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 106, 89]), + }, + sign_material: None, }, ), ( "polished_granite_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 106, 89]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 106, 89]), + }, + sign_material: None, }, ), ( "poppy", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "potatoes", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([84, 135, 47]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([84, 135, 47]), + }, + sign_material: None, }, ), ( "potted_acacia_sapling", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([118, 117, 23]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([118, 117, 23]), + }, + sign_material: None, }, ), ( "potted_allium", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([158, 137, 183]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([158, 137, 183]), + }, + sign_material: None, }, ), ( "potted_azalea_bush", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([101, 124, 47]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([101, 124, 47]), + }, + sign_material: None, }, ), ( "potted_azure_bluet", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([169, 204, 127]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([169, 204, 127]), + }, + sign_material: None, }, ), ( "potted_bamboo", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([93, 144, 19]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([93, 144, 19]), + }, + sign_material: None, }, ), ( "potted_birch_sapling", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([127, 160, 79]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([127, 160, 79]), + }, + sign_material: None, }, ), ( "potted_blue_orchid", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([47, 162, 168]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([47, 162, 168]), + }, + sign_material: None, }, ), ( "potted_brown_mushroom", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([153, 116, 92]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([153, 116, 92]), + }, + sign_material: None, }, ), ( "potted_cactus", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([85, 127, 43]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([85, 127, 43]), + }, + sign_material: None, }, ), ( "potted_cherry_sapling", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([164, 117, 143]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([164, 117, 143]), + }, + sign_material: None, }, ), ( "potted_cornflower", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([79, 121, 146]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([79, 121, 146]), + }, + sign_material: None, }, ), ( "potted_crimson_fungus", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([141, 44, 29]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([141, 44, 29]), + }, + sign_material: None, }, ), ( "potted_crimson_roots", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([127, 8, 41]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([127, 8, 41]), + }, + sign_material: None, }, ), ( "potted_dandelion", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([147, 172, 43]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([147, 172, 43]), + }, + sign_material: None, }, ), ( "potted_dark_oak_sapling", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([61, 90, 30]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([61, 90, 30]), + }, + sign_material: None, }, ), ( "potted_dead_bush", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([107, 78, 40]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([107, 78, 40]), + }, + sign_material: None, }, ), ( "potted_fern", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: Color([124, 124, 124]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([124, 124, 124]), + }, + sign_material: None, }, ), ( "potted_flowering_azalea_bush", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([112, 121, 64]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([112, 121, 64]), + }, + sign_material: None, }, ), ( "potted_jungle_sapling", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([47, 81, 16]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([47, 81, 16]), + }, + sign_material: None, }, ), ( "potted_lily_of_the_valley", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([123, 174, 95]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([123, 174, 95]), + }, + sign_material: None, }, ), ( "potted_mangrove_propagule", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([96, 174, 83]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([96, 174, 83]), + }, + sign_material: None, }, ), ( "potted_oak_sapling", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([77, 106, 40]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([77, 106, 40]), + }, + sign_material: None, }, ), ( "potted_orange_tulip", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([93, 142, 30]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([93, 142, 30]), + }, + sign_material: None, }, ), ( "potted_oxeye_daisy", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([179, 202, 143]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([179, 202, 143]), + }, + sign_material: None, }, ), ( "potted_pink_tulip", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 157, 78]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 157, 78]), + }, + sign_material: None, }, ), ( "potted_poppy", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([128, 64, 37]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([128, 64, 37]), + }, + sign_material: None, }, ), ( "potted_red_mushroom", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([216, 75, 67]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([216, 75, 67]), + }, + sign_material: None, }, ), ( "potted_red_tulip", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([89, 128, 32]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([89, 128, 32]), + }, + sign_material: None, }, ), ( "potted_spruce_sapling", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 60, 36]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 60, 36]), + }, + sign_material: None, }, ), ( "potted_torchflower", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([100, 101, 77]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([100, 101, 77]), + }, + sign_material: None, }, ), ( "potted_warped_fungus", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([74, 109, 87]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([74, 109, 87]), + }, + sign_material: None, }, ), ( "potted_warped_roots", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([20, 136, 123]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([20, 136, 123]), + }, + sign_material: None, }, ), ( "potted_white_tulip", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([93, 164, 71]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([93, 164, 71]), + }, + sign_material: None, }, ), ( "potted_wither_rose", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([41, 44, 23]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([41, 44, 23]), + }, + sign_material: None, }, ), ( "powder_snow", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 253, 253]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 253, 253]), + }, + sign_material: None, }, ), ( "powder_snow_cauldron", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([73, 72, 74]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([73, 72, 74]), + }, + sign_material: None, }, ), ( "powered_rail", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([137, 109, 74]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([137, 109, 74]), + }, + sign_material: None, }, ), ( "prismarine", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 156, 151]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 156, 151]), + }, + sign_material: None, }, ), ( "prismarine_brick_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 171, 158]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 171, 158]), + }, + sign_material: None, }, ), ( "prismarine_brick_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 171, 158]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 171, 158]), + }, + sign_material: None, }, ), ( "prismarine_bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 171, 158]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 171, 158]), + }, + sign_material: None, }, ), ( "prismarine_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 156, 151]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 156, 151]), + }, + sign_material: None, }, ), ( "prismarine_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 156, 151]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 156, 151]), + }, + sign_material: None, }, ), ( "prismarine_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 156, 151]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 156, 151]), + }, + sign_material: None, }, ), ( "pumpkin", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([198, 118, 24]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([198, 118, 24]), + }, + sign_material: None, }, ), ( "pumpkin_stem", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: Color([154, 154, 154]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([154, 154, 154]), + }, + sign_material: None, }, ), ( "purple_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "purple_bed", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "purple_candle", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "purple_candle_cake", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, + sign_material: None, }, ), ( "purple_carpet", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([121, 42, 172]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([121, 42, 172]), + }, + sign_material: None, }, ), ( "purple_concrete", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([100, 31, 156]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([100, 31, 156]), + }, + sign_material: None, }, ), ( "purple_concrete_powder", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([131, 55, 177]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([131, 55, 177]), + }, + sign_material: None, }, ), ( "purple_glazed_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 47, 152]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 47, 152]), + }, + sign_material: None, }, ), ( "purple_shulker_box", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([103, 32, 156]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([103, 32, 156]), + }, + sign_material: None, }, ), ( "purple_stained_glass", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([127, 63, 178]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([127, 63, 178]), + }, + sign_material: None, }, ), ( "purple_stained_glass_pane", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([122, 61, 171]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([122, 61, 171]), + }, + sign_material: None, }, ), ( "purple_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([118, 70, 86]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([118, 70, 86]), + }, + sign_material: None, }, ), ( "purple_wall_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "purple_wool", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([121, 42, 172]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([121, 42, 172]), + }, + sign_material: None, }, ), ( "purpur_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([169, 125, 169]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([169, 125, 169]), + }, + sign_material: None, }, ), ( "purpur_pillar", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([171, 129, 171]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([171, 129, 171]), + }, + sign_material: None, }, ), ( "purpur_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([169, 125, 169]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([169, 125, 169]), + }, + sign_material: None, }, ), ( "purpur_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([169, 125, 169]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([169, 125, 169]), + }, + sign_material: None, }, ), ( "quartz_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([235, 229, 222]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([235, 229, 222]), + }, + sign_material: None, }, ), ( "quartz_bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([234, 229, 221]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([234, 229, 221]), + }, + sign_material: None, }, ), ( "quartz_pillar", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([235, 230, 224]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([235, 230, 224]), + }, + sign_material: None, }, ), ( "quartz_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([235, 229, 222]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([235, 229, 222]), + }, + sign_material: None, }, ), ( "quartz_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([235, 229, 222]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([235, 229, 222]), + }, + sign_material: None, }, ), ( "rail", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([125, 111, 88]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([125, 111, 88]), + }, + sign_material: None, }, ), ( "raw_copper_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 105, 79]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 105, 79]), + }, + sign_material: None, }, ), ( "raw_gold_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([221, 169, 46]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([221, 169, 46]), + }, + sign_material: None, }, ), ( "raw_iron_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([166, 135, 107]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([166, 135, 107]), + }, + sign_material: None, }, ), ( "red_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "red_bed", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "red_candle", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "red_candle_cake", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, + sign_material: None, }, ), ( "red_carpet", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 39, 34]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 39, 34]), + }, + sign_material: None, }, ), ( "red_concrete", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([142, 32, 32]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([142, 32, 32]), + }, + sign_material: None, }, ), ( "red_concrete_powder", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([168, 54, 50]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([168, 54, 50]), + }, + sign_material: None, }, ), ( "red_glazed_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 59, 53]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 59, 53]), + }, + sign_material: None, }, ), ( "red_mushroom", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "red_mushroom_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([200, 46, 45]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([200, 46, 45]), + }, + sign_material: None, }, ), ( "red_nether_brick_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([69, 7, 9]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([69, 7, 9]), + }, + sign_material: None, }, ), ( "red_nether_brick_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([69, 7, 9]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([69, 7, 9]), + }, + sign_material: None, }, ), ( "red_nether_brick_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([69, 7, 9]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([69, 7, 9]), + }, + sign_material: None, }, ), ( "red_nether_bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([69, 7, 9]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([69, 7, 9]), + }, + sign_material: None, }, ), ( "red_sand", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([190, 102, 33]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([190, 102, 33]), + }, + sign_material: None, }, ), ( "red_sandstone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 97, 31]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 97, 31]), + }, + sign_material: None, }, ), ( "red_sandstone_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 97, 31]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 97, 31]), + }, + sign_material: None, }, ), ( "red_sandstone_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 97, 31]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 97, 31]), + }, + sign_material: None, }, ), ( "red_sandstone_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 97, 31]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 97, 31]), + }, + sign_material: None, }, ), ( "red_shulker_box", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([140, 31, 30]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([140, 31, 30]), + }, + sign_material: None, }, ), ( "red_stained_glass", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([153, 51, 51]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([153, 51, 51]), + }, + sign_material: None, }, ), ( "red_stained_glass_pane", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([147, 48, 48]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([147, 48, 48]), + }, + sign_material: None, }, ), ( "red_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([143, 61, 46]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([143, 61, 46]), + }, + sign_material: None, }, ), ( "red_tulip", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "red_wall_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "red_wool", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 39, 34]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 39, 34]), + }, + sign_material: None, }, ), ( "redstone_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([175, 24, 5]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([175, 24, 5]), + }, + sign_material: None, }, ), ( "redstone_lamp", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([95, 54, 30]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([95, 54, 30]), + }, + sign_material: None, }, ), ( "redstone_ore", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([140, 109, 109]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([140, 109, 109]), + }, + sign_material: None, }, ), ( "redstone_torch", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "redstone_wall_torch", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "redstone_wire", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([175, 24, 5]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([175, 24, 5]), + }, + sign_material: None, }, ), ( "reinforced_deepslate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([80, 82, 78]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([80, 82, 78]), + }, + sign_material: None, }, ), ( "repeater", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 157, 156]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 157, 156]), + }, + sign_material: None, }, ), ( "repeating_command_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([129, 111, 176]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([129, 111, 176]), + }, + sign_material: None, }, ), ( "respawn_anchor", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([75, 26, 144]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([75, 26, 144]), + }, + sign_material: None, }, ), ( "rooted_dirt", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([144, 103, 76]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([144, 103, 76]), + }, + sign_material: None, }, ), ( "rose_bush", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([131, 66, 37]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([131, 66, 37]), + }, + sign_material: None, }, ), ( "sand", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([219, 207, 163]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([219, 207, 163]), + }, + sign_material: None, }, ), ( "sandstone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 214, 170]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 214, 170]), + }, + sign_material: None, }, ), ( "sandstone_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 214, 170]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 214, 170]), + }, + sign_material: None, }, ), ( "sandstone_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 214, 170]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 214, 170]), + }, + sign_material: None, }, ), ( "sandstone_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 214, 170]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 214, 170]), + }, + sign_material: None, }, ), ( "scaffolding", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([170, 131, 73]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([170, 131, 73]), + }, + sign_material: None, }, ), ( "sculk", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([12, 29, 36]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([12, 29, 36]), + }, + sign_material: None, }, ), ( "sculk_catalyst", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([15, 31, 38]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([15, 31, 38]), + }, + sign_material: None, }, ), ( "sculk_sensor", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([7, 70, 84]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([7, 70, 84]), + }, + sign_material: None, }, ), ( "sculk_shrieker", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([198, 205, 169]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([198, 205, 169]), + }, + sign_material: None, }, ), ( "sculk_vein", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([7, 48, 57]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([7, 48, 57]), + }, + sign_material: None, }, ), ( "sea_lantern", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([172, 199, 190]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([172, 199, 190]), + }, + sign_material: None, }, ), ( "sea_pickle", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([90, 97, 39]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([90, 97, 39]), + }, + sign_material: None, }, ), ( "seagrass", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "short_grass", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "shroomlight", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([240, 146, 70]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([240, 146, 70]), + }, + sign_material: None, }, ), ( "shulker_box", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([139, 96, 139]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([139, 96, 139]), + }, + sign_material: None, }, ), ( "sign", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("oak"), }, ), ( "skeleton_skull", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "skeleton_wall_skull", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "slime_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([111, 192, 91]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([111, 192, 91]), + }, + sign_material: None, }, ), ( "small_amethyst_bud", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "small_dripleaf", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "smithing_table", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([57, 58, 70]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([57, 58, 70]), + }, + sign_material: None, }, ), ( "smoker", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([85, 83, 81]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([85, 83, 81]), + }, + sign_material: None, }, ), ( "smooth_basalt", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([72, 72, 78]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([72, 72, 78]), + }, + sign_material: None, }, ), ( "smooth_quartz", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([235, 229, 222]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([235, 229, 222]), + }, + sign_material: None, }, ), ( "smooth_quartz_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([235, 229, 222]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([235, 229, 222]), + }, + sign_material: None, }, ), ( "smooth_quartz_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([235, 229, 222]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([235, 229, 222]), + }, + sign_material: None, }, ), ( "smooth_red_sandstone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 97, 31]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 97, 31]), + }, + sign_material: None, }, ), ( "smooth_red_sandstone_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 97, 31]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 97, 31]), + }, + sign_material: None, }, ), ( "smooth_red_sandstone_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 97, 31]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 97, 31]), + }, + sign_material: None, }, ), ( "smooth_sandstone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 214, 170]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 214, 170]), + }, + sign_material: None, }, ), ( "smooth_sandstone_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 214, 170]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 214, 170]), + }, + sign_material: None, }, ), ( "smooth_sandstone_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 214, 170]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 214, 170]), + }, + sign_material: None, }, ), ( "smooth_stone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([158, 158, 158]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([158, 158, 158]), + }, + sign_material: None, }, ), ( "smooth_stone_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([158, 158, 158]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([158, 158, 158]), + }, + sign_material: None, }, ), ( "sniffer_egg", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([135, 105, 67]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([135, 105, 67]), + }, + sign_material: None, }, ), ( "snow", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([249, 254, 254]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([249, 254, 254]), + }, + sign_material: None, }, ), ( "snow_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([249, 254, 254]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([249, 254, 254]), + }, + sign_material: None, }, ), ( "soul_campfire", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([80, 204, 208]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([80, 204, 208]), + }, + sign_material: None, }, ), ( "soul_fire", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([51, 192, 197]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([51, 192, 197]), + }, + sign_material: None, }, ), ( "soul_lantern", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([71, 99, 114]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([71, 99, 114]), + }, + sign_material: None, }, ), ( "soul_sand", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([81, 62, 50]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([81, 62, 50]), + }, + sign_material: None, }, ), ( "soul_soil", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([75, 57, 46]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([75, 57, 46]), + }, + sign_material: None, }, ), ( "soul_torch", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "soul_wall_torch", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "spawner", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([36, 46, 62]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([36, 46, 62]), + }, + sign_material: None, }, ), ( "sponge", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([195, 192, 74]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([195, 192, 74]), + }, + sign_material: None, }, ), ( "spore_blossom", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([206, 96, 158]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([206, 96, 158]), + }, + sign_material: None, }, ), ( "spruce_button", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "spruce_door", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([106, 80, 48]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([106, 80, 48]), + }, + sign_material: None, }, ), ( "spruce_fence", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 84, 48]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 84, 48]), + }, + sign_material: None, }, ), ( "spruce_fence_gate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 84, 48]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 84, 48]), + }, + sign_material: None, }, ), ( "spruce_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("spruce"), }, ), ( "spruce_leaves", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Spruce}), - color: Color([126, 126, 126]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Spruce}), + color: Color([126, 126, 126]), + }, + sign_material: None, }, ), ( "spruce_log", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([108, 80, 46]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([108, 80, 46]), + }, + sign_material: None, }, ), ( "spruce_planks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 84, 48]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 84, 48]), + }, + sign_material: None, }, ), ( "spruce_pressure_plate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 84, 48]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 84, 48]), + }, + sign_material: None, }, ), ( "spruce_sapling", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 60, 36]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 60, 36]), + }, + sign_material: None, }, ), ( "spruce_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 84, 48]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("spruce"), }, ), ( "spruce_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 84, 48]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 84, 48]), + }, + sign_material: None, }, ), ( "spruce_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 84, 48]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 84, 48]), + }, + sign_material: None, }, ), ( "spruce_trapdoor", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([103, 79, 47]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([103, 79, 47]), + }, + sign_material: None, }, ), ( "spruce_wall_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("spruce"), }, ), ( "spruce_wall_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("spruce"), }, ), ( "spruce_wood", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([58, 37, 16]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([58, 37, 16]), + }, + sign_material: None, }, ), ( "sticky_piston", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 104, 96]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 104, 96]), + }, + sign_material: None, }, ), ( "stone", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([125, 125, 125]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([125, 125, 125]), + }, + sign_material: None, }, ), ( "stone_brick_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([122, 121, 122]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([122, 121, 122]), + }, + sign_material: None, }, ), ( "stone_brick_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([122, 121, 122]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([122, 121, 122]), + }, + sign_material: None, }, ), ( "stone_brick_wall", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([122, 121, 122]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([122, 121, 122]), + }, + sign_material: None, }, ), ( "stone_bricks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([122, 121, 122]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([122, 121, 122]), + }, + sign_material: None, }, ), ( "stone_button", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "stone_pressure_plate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([125, 125, 125]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([125, 125, 125]), + }, + sign_material: None, }, ), ( "stone_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([125, 125, 125]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([125, 125, 125]), + }, + sign_material: None, }, ), ( "stone_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([125, 125, 125]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([125, 125, 125]), + }, + sign_material: None, }, ), ( "stonecutter", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([123, 118, 111]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([123, 118, 111]), + }, + sign_material: None, }, ), ( "stripped_acacia_log", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([166, 91, 51]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([166, 91, 51]), + }, + sign_material: None, }, ), ( "stripped_acacia_wood", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([174, 92, 59]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([174, 92, 59]), + }, + sign_material: None, }, ), ( "stripped_bamboo_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([178, 158, 72]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([178, 158, 72]), + }, + sign_material: None, }, ), ( "stripped_birch_log", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([191, 171, 116]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([191, 171, 116]), + }, + sign_material: None, }, ), ( "stripped_birch_wood", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([196, 176, 118]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([196, 176, 118]), + }, + sign_material: None, }, ), ( "stripped_cherry_log", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([221, 164, 157]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([221, 164, 157]), + }, + sign_material: None, }, ), ( "stripped_cherry_wood", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([215, 145, 148]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([215, 145, 148]), + }, + sign_material: None, }, ), ( "stripped_crimson_hyphae", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([137, 57, 90]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([137, 57, 90]), + }, + sign_material: None, }, ), ( "stripped_crimson_stem", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([121, 56, 82]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([121, 56, 82]), + }, + sign_material: None, }, ), ( "stripped_dark_oak_log", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([65, 44, 22]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([65, 44, 22]), + }, + sign_material: None, }, ), ( "stripped_dark_oak_wood", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([72, 56, 36]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([72, 56, 36]), + }, + sign_material: None, }, ), ( "stripped_jungle_log", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([165, 122, 81]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([165, 122, 81]), + }, + sign_material: None, }, ), ( "stripped_jungle_wood", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([171, 132, 84]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([171, 132, 84]), + }, + sign_material: None, }, ), ( "stripped_mangrove_log", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 43, 43]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 43, 43]), + }, + sign_material: None, }, ), ( "stripped_mangrove_wood", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([119, 54, 47]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([119, 54, 47]), + }, + sign_material: None, }, ), ( "stripped_oak_log", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 129, 77]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 129, 77]), + }, + sign_material: None, }, ), ( "stripped_oak_wood", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([177, 144, 86]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([177, 144, 86]), + }, + sign_material: None, }, ), ( "stripped_spruce_log", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([105, 80, 46]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([105, 80, 46]), + }, + sign_material: None, }, ), ( "stripped_spruce_wood", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([115, 89, 52]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([115, 89, 52]), + }, + sign_material: None, }, ), ( "stripped_warped_hyphae", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([57, 150, 147]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([57, 150, 147]), + }, + sign_material: None, }, ), ( "stripped_warped_stem", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([52, 128, 124]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([52, 128, 124]), + }, + sign_material: None, }, ), ( "structure_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([88, 74, 90]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([88, 74, 90]), + }, + sign_material: None, }, ), ( "structure_void", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "sugar_cane", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([148, 192, 101]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([148, 192, 101]), + }, + sign_material: None, }, ), ( "sunflower", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([246, 196, 54]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([246, 196, 54]), + }, + sign_material: None, }, ), ( "suspicious_gravel", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([129, 125, 124]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([129, 125, 124]), + }, + sign_material: None, }, ), ( "suspicious_sand", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([217, 204, 159]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([217, 204, 159]), + }, + sign_material: None, }, ), ( "sweet_berry_bush", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([68, 77, 50]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([68, 77, 50]), + }, + sign_material: None, }, ), ( "tall_grass", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: Color([151, 149, 151]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([151, 149, 151]), + }, + sign_material: None, }, ), ( "tall_seagrass", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([59, 139, 14]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([59, 139, 14]), + }, + sign_material: None, }, ), ( "target", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([226, 170, 157]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 170, 157]), + }, + sign_material: None, }, ), ( "terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([152, 94, 67]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([152, 94, 67]), + }, + sign_material: None, }, ), ( "tinted_glass", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 38, 46]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 38, 46]), + }, + sign_material: None, }, ), ( "tnt", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([142, 62, 53]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([142, 62, 53]), + }, + sign_material: None, }, ), ( "torch", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "torchflower", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "torchflower_crop", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "trapped_chest", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, + sign_material: None, }, ), ( "tripwire", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "tripwire_hook", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "tube_coral", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "tube_coral_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([49, 87, 206]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([49, 87, 206]), + }, + sign_material: None, }, ), ( "tube_coral_fan", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "tube_coral_wall_fan", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "tuff", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([108, 109, 102]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([108, 109, 102]), + }, + sign_material: None, }, ), ( "turtle_egg", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([228, 226, 191]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([228, 226, 191]), + }, + sign_material: None, }, ), ( "twisting_vines", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([20, 143, 124]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([20, 143, 124]), + }, + sign_material: None, }, ), ( "twisting_vines_plant", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([20, 135, 122]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([20, 135, 122]), + }, + sign_material: None, }, ), ( "verdant_froglight", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([229, 244, 228]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([229, 244, 228]), + }, + sign_material: None, }, ), ( "vine", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: Color([116, 116, 116]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([116, 116, 116]), + }, + sign_material: None, }, ), ( "void_air", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "wall_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("oak"), }, ), ( "wall_torch", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "warped_button", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "warped_door", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 126, 120]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 126, 120]), + }, + sign_material: None, }, ), ( "warped_fence", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([43, 104, 99]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([43, 104, 99]), + }, + sign_material: None, }, ), ( "warped_fence_gate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([43, 104, 99]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([43, 104, 99]), + }, + sign_material: None, }, ), ( "warped_fungus", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "warped_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("warped"), }, ), ( "warped_hyphae", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([58, 58, 77]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([58, 58, 77]), + }, + sign_material: None, }, ), ( "warped_nylium", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([43, 114, 101]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([43, 114, 101]), + }, + sign_material: None, }, ), ( "warped_planks", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([43, 104, 99]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([43, 104, 99]), + }, + sign_material: None, }, ), ( "warped_pressure_plate", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([43, 104, 99]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([43, 104, 99]), + }, + sign_material: None, }, ), ( "warped_roots", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([20, 138, 124]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([20, 138, 124]), + }, + sign_material: None, }, ), ( "warped_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([43, 104, 99]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("warped"), }, ), ( "warped_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([43, 104, 99]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([43, 104, 99]), + }, + sign_material: None, }, ), ( "warped_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([43, 104, 99]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([43, 104, 99]), + }, + sign_material: None, }, ), ( "warped_stem", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([53, 109, 110]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([53, 109, 110]), + }, + sign_material: None, }, ), ( "warped_trapdoor", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([47, 119, 111]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([47, 119, 111]), + }, + sign_material: None, }, ), ( "warped_wall_hanging_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("warped"), }, ), ( "warped_wall_sign", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("warped"), }, ), ( "warped_wart_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([22, 119, 121]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([22, 119, 121]), + }, + sign_material: None, }, ), ( "water", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Water}), - color: Color([177, 177, 177]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Water}), + color: Color([177, 177, 177]), + }, + sign_material: None, }, ), ( "water_cauldron", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([73, 72, 74]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([73, 72, 74]), + }, + sign_material: None, }, ), ( "waxed_copper_block", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 107, 79]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 107, 79]), + }, + sign_material: None, }, ), ( "waxed_cut_copper", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([191, 106, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([191, 106, 80]), + }, + sign_material: None, }, ), ( "waxed_cut_copper_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([191, 106, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([191, 106, 80]), + }, + sign_material: None, }, ), ( "waxed_cut_copper_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([191, 106, 80]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([191, 106, 80]), + }, + sign_material: None, }, ), ( "waxed_exposed_copper", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([161, 125, 103]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([161, 125, 103]), + }, + sign_material: None, }, ), ( "waxed_exposed_cut_copper", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 121, 101]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 121, 101]), + }, + sign_material: None, }, ), ( "waxed_exposed_cut_copper_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 121, 101]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 121, 101]), + }, + sign_material: None, }, ), ( "waxed_exposed_cut_copper_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 121, 101]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 121, 101]), + }, + sign_material: None, }, ), ( "waxed_oxidized_copper", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([82, 162, 132]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([82, 162, 132]), + }, + sign_material: None, }, ), ( "waxed_oxidized_cut_copper", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([79, 153, 126]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([79, 153, 126]), + }, + sign_material: None, }, ), ( "waxed_oxidized_cut_copper_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([79, 153, 126]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([79, 153, 126]), + }, + sign_material: None, }, ), ( "waxed_oxidized_cut_copper_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([79, 153, 126]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([79, 153, 126]), + }, + sign_material: None, }, ), ( "waxed_weathered_copper", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([108, 153, 110]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([108, 153, 110]), + }, + sign_material: None, }, ), ( "waxed_weathered_cut_copper", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 145, 107]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 145, 107]), + }, + sign_material: None, }, ), ( "waxed_weathered_cut_copper_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 145, 107]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 145, 107]), + }, + sign_material: None, }, ), ( "waxed_weathered_cut_copper_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 145, 107]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 145, 107]), + }, + sign_material: None, }, ), ( "weathered_copper", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([108, 153, 110]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([108, 153, 110]), + }, + sign_material: None, }, ), ( "weathered_cut_copper", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 145, 107]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 145, 107]), + }, + sign_material: None, }, ), ( "weathered_cut_copper_slab", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 145, 107]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 145, 107]), + }, + sign_material: None, }, ), ( "weathered_cut_copper_stairs", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 145, 107]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 145, 107]), + }, + sign_material: None, }, ), ( "weeping_vines", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([104, 1, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([104, 1, 0]), + }, + sign_material: None, }, ), ( "weeping_vines_plant", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([132, 16, 12]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([132, 16, 12]), + }, + sign_material: None, }, ), ( "wet_sponge", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([171, 181, 70]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([171, 181, 70]), + }, + sign_material: None, }, ), ( "wheat", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([166, 151, 73]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([166, 151, 73]), + }, + sign_material: None, }, ), ( "white_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "white_bed", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "white_candle", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "white_candle_cake", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, + sign_material: None, }, ), ( "white_carpet", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([233, 236, 236]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([233, 236, 236]), + }, + sign_material: None, }, ), ( "white_concrete", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([207, 213, 214]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([207, 213, 214]), + }, + sign_material: None, }, ), ( "white_concrete_powder", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([225, 227, 227]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([225, 227, 227]), + }, + sign_material: None, }, ), ( "white_glazed_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([188, 212, 202]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([188, 212, 202]), + }, + sign_material: None, }, ), ( "white_shulker_box", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([215, 220, 221]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([215, 220, 221]), + }, + sign_material: None, }, ), ( "white_stained_glass", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([255, 255, 255]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([255, 255, 255]), + }, + sign_material: None, }, ), ( "white_stained_glass_pane", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([246, 246, 246]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([246, 246, 246]), + }, + sign_material: None, }, ), ( "white_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([209, 178, 161]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([209, 178, 161]), + }, + sign_material: None, }, ), ( "white_tulip", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "white_wall_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "white_wool", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([233, 236, 236]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([233, 236, 236]), + }, + sign_material: None, }, ), ( "wither_rose", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "wither_skeleton_skull", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "wither_skeleton_wall_skull", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "yellow_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "yellow_bed", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "yellow_candle", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "yellow_candle_cake", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, + sign_material: None, }, ), ( "yellow_carpet", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 197, 39]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 197, 39]), + }, + sign_material: None, }, ), ( "yellow_concrete", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([240, 175, 21]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([240, 175, 21]), + }, + sign_material: None, }, ), ( "yellow_concrete_powder", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([232, 199, 54]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([232, 199, 54]), + }, + sign_material: None, }, ), ( "yellow_glazed_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([234, 192, 88]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([234, 192, 88]), + }, + sign_material: None, }, ), ( "yellow_shulker_box", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 188, 29]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 188, 29]), + }, + sign_material: None, }, ), ( "yellow_stained_glass", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([229, 229, 51]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([229, 229, 51]), + }, + sign_material: None, }, ), ( "yellow_stained_glass_pane", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([221, 221, 48]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([221, 221, 48]), + }, + sign_material: None, }, ), ( "yellow_terracotta", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([186, 133, 35]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([186, 133, 35]), + }, + sign_material: None, }, ), ( "yellow_wall_banner", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "yellow_wool", - BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 197, 39]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 197, 39]), + }, + sign_material: None, }, ), ( "zombie_head", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "zombie_wall_head", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ]; diff --git a/crates/resource/src/lib.rs b/crates/resource/src/lib.rs index a832a58..1baffda 100644 --- a/crates/resource/src/lib.rs +++ b/crates/resource/src/lib.rs @@ -27,10 +27,15 @@ pub enum BlockFlag { Foliage, /// The block type is birch foliage Birch, - /// The block type is spurce foliage + /// The block type is spruce foliage Spruce, /// The block type is colored using biome water colors Water, + /// The block type is a wall sign + /// + /// The WallSign flag is used to distinguish wall signs from + /// freestanding or -hanging signs. + WallSign, } /// An RGB color with u8 components @@ -42,21 +47,48 @@ pub type Colorf = glam::Vec3; /// A block type specification #[derive(Debug, Clone, Copy, Serialize, Deserialize)] -pub struct BlockType { +pub struct BlockColor { /// Bit set of [BlockFlag]s describing special properties of the block type pub flags: BitFlags, /// Base color of the block type pub color: Color, } -impl BlockType { - /// Checks whether a block type has a given [BlockFlag] set +impl BlockColor { + /// Checks whether a block color has a given [BlockFlag] set #[inline] pub fn is(&self, flag: BlockFlag) -> bool { self.flags.contains(flag) } } +/// A block type specification (for use in constants) +#[derive(Debug, Clone)] +struct ConstBlockType { + /// Determines the rendered color of the block type + pub block_color: BlockColor, + /// Material of a sign block + pub sign_material: Option<&'static str>, +} + +/// A block type specification +#[derive(Debug, Clone)] +pub struct BlockType { + /// Determines the rendered color of the block type + pub block_color: BlockColor, + /// Material of a sign block + pub sign_material: Option, +} + +impl From<&ConstBlockType> for BlockType { + fn from(value: &ConstBlockType) -> Self { + BlockType { + block_color: value.block_color, + sign_material: value.sign_material.map(String::from), + } + } +} + /// Used to look up standard Minecraft block types #[derive(Debug)] pub struct BlockTypes { @@ -70,10 +102,15 @@ impl Default for BlockTypes { fn default() -> Self { let block_type_map: HashMap<_, _> = block_types::BLOCK_TYPES .iter() - .map(|(k, v)| (String::from(*k), *v)) + .map(|(k, v)| (String::from(*k), BlockType::from(v))) .collect(); let legacy_block_types = Box::new(legacy_block_types::LEGACY_BLOCK_TYPES.map(|inner| { - inner.map(|id| *block_type_map.get(id).expect("Unknown legacy block type")) + inner.map(|id| { + block_type_map + .get(id) + .expect("Unknown legacy block type") + .clone() + }) })); BlockTypes { @@ -86,15 +123,15 @@ impl Default for BlockTypes { impl BlockTypes { /// Resolves a Minecraft 1.13+ string block type ID #[inline] - pub fn get(&self, id: &str) -> Option { + pub fn get(&self, id: &str) -> Option<&BlockType> { let suffix = id.strip_prefix("minecraft:")?; - self.block_type_map.get(suffix).copied() + self.block_type_map.get(suffix) } /// Resolves a Minecraft pre-1.13 numeric block type ID #[inline] - pub fn get_legacy(&self, id: u8, data: u8) -> Option { - Some(self.legacy_block_types[id as usize][data as usize]) + pub fn get_legacy(&self, id: u8, data: u8) -> Option<&BlockType> { + Some(&self.legacy_block_types[id as usize][data as usize]) } } diff --git a/resource/README.md b/resource/README.md index 08857ad..ab9d5ea 100644 --- a/resource/README.md +++ b/resource/README.md @@ -11,6 +11,7 @@ work. - `extract.py`: Takes the block type information from `blocks.json` and texture data from an unpacked Minecraft JAR, storing the result in `colors.json` - `generate.py`: Generates `block_types.rs` from `colors.json` +- `sign_textures.py`: Generates all needed sign graphics from Minecraft assets In addition to these scripts, the JSON processor *jq* is a useful tool to work with MinedMap's resource metadata. @@ -42,12 +43,13 @@ with MinedMap's resource metadata. 5. Edit `blocks.json` until the following command passes without errors: ```sh - ./extract.py blocks.json data/new/assets/minecraft/textures/block colors.json + ./extract.py blocks.json data/new colors.json ``` If possible, the top texture of blocks should be used where different sides exist. Block types that should not be visible on the map are just set to - `null` in the JSON. + `null` in the JSON (or have a `null` `texture` field when other flags need + to be set, like for sign blocks). The `water`, `grass` and `foliage` flags control biome-dependent texture color modifiers. diff --git a/resource/blocks.json b/resource/blocks.json index 6f4f5e7..f8b0165 100644 --- a/resource/blocks.json +++ b/resource/blocks.json @@ -9,7 +9,10 @@ "acacia_fence_gate": { "texture": "acacia_planks" }, - "acacia_hanging_sign": null, + "acacia_hanging_sign": { + "sign_material": "acacia", + "texture": null + }, "acacia_leaves": { "foliage": true }, @@ -22,7 +25,8 @@ }, "acacia_sapling": {}, "acacia_sign": { - "texture": "acacia_planks" + "sign_material": "acacia", + "texture": null }, "acacia_slab": { "texture": "acacia_planks" @@ -31,8 +35,16 @@ "texture": "acacia_planks" }, "acacia_trapdoor": {}, - "acacia_wall_hanging_sign": null, - "acacia_wall_sign": null, + "acacia_wall_hanging_sign": { + "sign_material": "acacia", + "texture": null, + "wall_sign": true + }, + "acacia_wall_sign": { + "sign_material": "acacia", + "texture": null, + "wall_sign": true + }, "acacia_wood": { "texture": "acacia_log" }, @@ -84,7 +96,10 @@ "bamboo_fence_gate": { "texture": "bamboo_planks" }, - "bamboo_hanging_sign": null, + "bamboo_hanging_sign": { + "sign_material": "bamboo", + "texture": null + }, "bamboo_mosaic": {}, "bamboo_mosaic_slab": { "texture": "bamboo_mosaic" @@ -98,7 +113,8 @@ }, "bamboo_sapling": null, "bamboo_sign": { - "texture": "bamboo_planks" + "sign_material": "bamboo", + "texture": null }, "bamboo_slab": { "texture": "bamboo_planks" @@ -107,8 +123,16 @@ "texture": "bamboo_planks" }, "bamboo_trapdoor": {}, - "bamboo_wall_hanging_sign": null, - "bamboo_wall_sign": null, + "bamboo_wall_hanging_sign": { + "sign_material": "bamboo", + "texture": null, + "wall_sign": true + }, + "bamboo_wall_sign": { + "sign_material": "bamboo", + "texture": null, + "wall_sign": true + }, "barrel": { "texture": "barrel_top" }, @@ -144,7 +168,10 @@ "birch_fence_gate": { "texture": "birch_planks" }, - "birch_hanging_sign": null, + "birch_hanging_sign": { + "sign_material": "birch", + "texture": null + }, "birch_leaves": { "birch": true }, @@ -157,7 +184,8 @@ }, "birch_sapling": {}, "birch_sign": { - "texture": "birch_planks" + "sign_material": "birch", + "texture": null }, "birch_slab": { "texture": "birch_planks" @@ -166,8 +194,16 @@ "texture": "birch_planks" }, "birch_trapdoor": {}, - "birch_wall_hanging_sign": null, - "birch_wall_sign": null, + "birch_wall_hanging_sign": { + "sign_material": "birch", + "texture": null, + "wall_sign": true + }, + "birch_wall_sign": { + "sign_material": "birch", + "texture": null, + "wall_sign": true + }, "birch_wood": { "texture": "birch_log" }, @@ -326,7 +362,10 @@ "cherry_fence_gate": { "texture": "cherry_planks" }, - "cherry_hanging_sign": null, + "cherry_hanging_sign": { + "sign_material": "cherry", + "texture": null + }, "cherry_leaves": {}, "cherry_log": { "texture": "cherry_log_top" @@ -337,7 +376,8 @@ }, "cherry_sapling": null, "cherry_sign": { - "texture": "cherry_planks" + "sign_material": "cherry", + "texture": null }, "cherry_slab": { "texture": "cherry_planks" @@ -346,8 +386,16 @@ "texture": "cherry_planks" }, "cherry_trapdoor": {}, - "cherry_wall_hanging_sign": null, - "cherry_wall_sign": null, + "cherry_wall_hanging_sign": { + "sign_material": "cherry", + "texture": null, + "wall_sign": true + }, + "cherry_wall_sign": { + "sign_material": "cherry", + "texture": null, + "wall_sign": true + }, "cherry_wood": { "texture": "cherry_log" }, @@ -433,7 +481,10 @@ "texture": "crimson_planks" }, "crimson_fungus": null, - "crimson_hanging_sign": null, + "crimson_hanging_sign": { + "sign_material": "crimson", + "texture": null + }, "crimson_hyphae": { "texture": "crimson_stem" }, @@ -444,7 +495,8 @@ }, "crimson_roots": {}, "crimson_sign": { - "texture": "crimson_planks" + "sign_material": "crimson", + "texture": null }, "crimson_slab": { "texture": "crimson_planks" @@ -456,8 +508,16 @@ "texture": "crimson_stem_top" }, "crimson_trapdoor": {}, - "crimson_wall_hanging_sign": null, - "crimson_wall_sign": null, + "crimson_wall_hanging_sign": { + "sign_material": "crimson", + "texture": null, + "wall_sign": true + }, + "crimson_wall_sign": { + "sign_material": "crimson", + "texture": null, + "wall_sign": true + }, "crying_obsidian": {}, "cut_copper": {}, "cut_copper_slab": { @@ -512,7 +572,10 @@ "dark_oak_fence_gate": { "texture": "dark_oak_planks" }, - "dark_oak_hanging_sign": null, + "dark_oak_hanging_sign": { + "sign_material": "dark_oak", + "texture": null + }, "dark_oak_leaves": { "foliage": true }, @@ -525,7 +588,8 @@ }, "dark_oak_sapling": {}, "dark_oak_sign": { - "texture": "dark_oak_planks" + "sign_material": "dark_oak", + "texture": null }, "dark_oak_slab": { "texture": "dark_oak_planks" @@ -534,8 +598,16 @@ "texture": "dark_oak_planks" }, "dark_oak_trapdoor": {}, - "dark_oak_wall_hanging_sign": null, - "dark_oak_wall_sign": null, + "dark_oak_wall_hanging_sign": { + "sign_material": "dark_oak", + "texture": null, + "wall_sign": true + }, + "dark_oak_wall_sign": { + "sign_material": "dark_oak", + "texture": null, + "wall_sign": true + }, "dark_oak_wood": { "texture": "dark_oak_log" }, @@ -832,7 +904,10 @@ "jungle_fence_gate": { "texture": "jungle_planks" }, - "jungle_hanging_sign": null, + "jungle_hanging_sign": { + "sign_material": "jungle", + "texture": null + }, "jungle_leaves": { "foliage": true }, @@ -845,7 +920,8 @@ }, "jungle_sapling": {}, "jungle_sign": { - "texture": "jungle_planks" + "sign_material": "jungle", + "texture": null }, "jungle_slab": { "texture": "jungle_planks" @@ -854,8 +930,16 @@ "texture": "jungle_planks" }, "jungle_trapdoor": {}, - "jungle_wall_hanging_sign": null, - "jungle_wall_sign": null, + "jungle_wall_hanging_sign": { + "sign_material": "jungle", + "texture": null, + "wall_sign": true + }, + "jungle_wall_sign": { + "sign_material": "jungle", + "texture": null, + "wall_sign": true + }, "jungle_wood": { "texture": "jungle_log" }, @@ -991,7 +1075,10 @@ "mangrove_fence_gate": { "texture": "mangrove_planks" }, - "mangrove_hanging_sign": null, + "mangrove_hanging_sign": { + "sign_material": "mangrove", + "texture": null + }, "mangrove_leaves": { "foliage": true }, @@ -1007,7 +1094,8 @@ "texture": "mangrove_roots_top" }, "mangrove_sign": { - "texture": "mangrove_planks" + "sign_material": "mangrove", + "texture": null }, "mangrove_slab": { "texture": "mangrove_planks" @@ -1016,8 +1104,16 @@ "texture": "mangrove_planks" }, "mangrove_trapdoor": {}, - "mangrove_wall_hanging_sign": null, - "mangrove_wall_sign": null, + "mangrove_wall_hanging_sign": { + "sign_material": "mangrove", + "texture": null, + "wall_sign": true + }, + "mangrove_wall_sign": { + "sign_material": "mangrove", + "texture": null, + "wall_sign": true + }, "mangrove_wood": { "texture": "mangrove_log" }, @@ -1105,7 +1201,10 @@ "oak_fence_gate": { "texture": "oak_planks" }, - "oak_hanging_sign": null, + "oak_hanging_sign": { + "sign_material": "oak", + "texture": null + }, "oak_leaves": { "foliage": true }, @@ -1118,7 +1217,8 @@ }, "oak_sapling": {}, "oak_sign": { - "texture": "oak_planks" + "sign_material": "oak", + "texture": null }, "oak_slab": { "texture": "oak_planks" @@ -1127,8 +1227,16 @@ "texture": "oak_planks" }, "oak_trapdoor": {}, - "oak_wall_hanging_sign": null, - "oak_wall_sign": null, + "oak_wall_hanging_sign": { + "sign_material": "oak", + "texture": null, + "wall_sign": true + }, + "oak_wall_sign": { + "sign_material": "oak", + "texture": null, + "wall_sign": true + }, "oak_wood": { "texture": "oak_log" }, @@ -1562,7 +1670,8 @@ "shroomlight": {}, "shulker_box": {}, "sign": { - "texture": "oak_planks" + "sign_material": "oak", + "texture": null }, "skeleton_skull": null, "skeleton_wall_skull": null, @@ -1638,7 +1747,10 @@ "spruce_fence_gate": { "texture": "spruce_planks" }, - "spruce_hanging_sign": null, + "spruce_hanging_sign": { + "sign_material": "spruce", + "texture": null + }, "spruce_leaves": { "spruce": true }, @@ -1651,7 +1763,8 @@ }, "spruce_sapling": {}, "spruce_sign": { - "texture": "spruce_planks" + "sign_material": "spruce", + "texture": null }, "spruce_slab": { "texture": "spruce_planks" @@ -1660,8 +1773,16 @@ "texture": "spruce_planks" }, "spruce_trapdoor": {}, - "spruce_wall_hanging_sign": null, - "spruce_wall_sign": null, + "spruce_wall_hanging_sign": { + "sign_material": "spruce", + "texture": null, + "wall_sign": true + }, + "spruce_wall_sign": { + "sign_material": "spruce", + "texture": null, + "wall_sign": true + }, "spruce_wood": { "texture": "spruce_log" }, @@ -1808,7 +1929,11 @@ "grass": true }, "void_air": null, - "wall_sign": null, + "wall_sign": { + "sign_material": "oak", + "texture": null, + "wall_sign": true + }, "wall_torch": null, "warped_button": null, "warped_door": { @@ -1821,7 +1946,10 @@ "texture": "warped_planks" }, "warped_fungus": null, - "warped_hanging_sign": null, + "warped_hanging_sign": { + "sign_material": "warped", + "texture": null + }, "warped_hyphae": { "texture": "warped_stem" }, @@ -1832,7 +1960,8 @@ }, "warped_roots": {}, "warped_sign": { - "texture": "warped_planks" + "sign_material": "warped", + "texture": null }, "warped_slab": { "texture": "warped_planks" @@ -1844,8 +1973,16 @@ "texture": "warped_stem_top" }, "warped_trapdoor": {}, - "warped_wall_hanging_sign": null, - "warped_wall_sign": null, + "warped_wall_hanging_sign": { + "sign_material": "warped", + "texture": null, + "wall_sign": true + }, + "warped_wall_sign": { + "sign_material": "warped", + "texture": null, + "wall_sign": true + }, "warped_wart_block": {}, "water": { "texture": "water_still", diff --git a/resource/extract.py b/resource/extract.py index 281f3a7..31c1e97 100755 --- a/resource/extract.py +++ b/resource/extract.py @@ -11,7 +11,7 @@ if len(sys.argv) != 4: sys.exit('Usage: extract.py ') def mean_color(texture): - path = os.path.join(sys.argv[2], texture + '.png') + path = os.path.join(sys.argv[2], 'assets/minecraft/textures/block', texture + '.png') im = Image.open(path) data = im.convert('RGBA').getdata() @@ -45,20 +45,30 @@ for name, info in blocks.items(): 'birch': False, 'spruce': False, 'water': False, + 'wall_sign': False, + 'sign_material': None, } if info is None: continue - color = mean_color(info.get('texture', name)) + texture = info.get('texture', name) + + color = None + if texture: + color = mean_color(texture) if color: output[id]['color'] = color output[id]['opaque'] = True - output[id]['grass'] = info.get('grass', False) - output[id]['foliage'] = info.get('foliage', False) - output[id]['birch'] = info.get('birch', False) - output[id]['spruce'] = info.get('spruce', False) - output[id]['water'] = info.get('water', False) + + output[id]['grass'] = info.get('grass', False) + output[id]['foliage'] = info.get('foliage', False) + output[id]['birch'] = info.get('birch', False) + output[id]['spruce'] = info.get('spruce', False) + output[id]['water'] = info.get('water', False) + output[id]['wall_sign'] = info.get('wall_sign', False) + + output[id]['sign_material'] = info.get('sign_material') with open(sys.argv[3], 'w') as f: json.dump(output, f) diff --git a/resource/generate.py b/resource/generate.py index 73bb91d..8064482 100755 --- a/resource/generate.py +++ b/resource/generate.py @@ -18,7 +18,7 @@ with open(sys.argv[2], 'w') as f: print('', file=f) print('use super::*;', file=f) print('', file=f) - print('pub const BLOCK_TYPES: &[(&str, BlockType)] = &[', file=f) + print('pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[', file=f) for name, info in colors.items(): flags = [] @@ -34,13 +34,22 @@ with open(sys.argv[2], 'w') as f: flags.append('Spruce') if info['water']: flags.append('Water') + if info['wall_sign']: + flags.append('WallSign') flags = 'make_bitflags!(BlockFlag::{' + '|'.join(flags) + '})' - print('\t("%s", BlockType { flags: %s, color: Color([%u, %u, %u]) }),' % ( - name, + sign_material = 'None' + if info['sign_material']: + sign_material = 'Some("%s")' % info['sign_material'] + + print('\t("%s", ConstBlockType { ' % name, file=f) + print('\t\tblock_color: BlockColor { flags: %s, color: Color([%u, %u, %u]) },' % ( flags, info['color']['r'], info['color']['g'], info['color']['b'], ), file=f) + print('\t\tsign_material: %s,' % sign_material, file=f) + print('}),', file=f) + print('];', file=f) diff --git a/resource/sign_textures.py b/resource/sign_textures.py new file mode 100755 index 0000000..e0b548d --- /dev/null +++ b/resource/sign_textures.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 + +import shutil +import sys + +from PIL import Image + +MATERIALS = [ + 'acacia', + 'bamboo', + 'birch', + 'cherry', + 'crimson', + 'dark_oak', + 'jungle', + 'mangrove', + 'oak', + 'spruce', + 'warped', +] + +in_dir = sys.argv[1] +out_dir = sys.argv[2] + +def sign_bg_image(material): + in_path = f'{in_dir}/assets/minecraft/textures/entity/signs/{material}.png' + out_path = f'{out_dir}/bg/{material}_sign.png' + out_path_wall = f'{out_dir}/bg/{material}_wall_sign.png' + + in_image = Image.open(in_path) + + out_image = Image.new('RGBA', (24, 26)) + out_image.paste(in_image.crop((2, 2, 26, 14)), (0, 0)) + out_image.paste(in_image.crop((2, 16, 4, 30)), (11, 12)) + out_image.save(out_path) + + out_image = Image.new('RGBA', (24, 12)) + out_image.paste(in_image.crop((2, 2, 26, 14)), (0, 0)) + out_image.save(out_path_wall) + +def hanging_sign_bg_image(material): + in_path = f'{in_dir}/assets/minecraft/textures/gui/hanging_signs/{material}.png' + out_path = f'{out_dir}/bg/{material}_hanging_sign.png' + out_path_wall = f'{out_dir}/bg/{material}_hanging_wall_sign.png' + + in_image = Image.open(in_path) + + out_image = Image.new('RGBA', (16, 14)) + out_image.paste(in_image.crop((0, 2, 16, 16)), (0, 0)) + out_image.save(out_path) + + shutil.copyfile(in_path, out_path_wall) + + +def sign_icon_image(material): + in_path = f'{in_dir}/assets/minecraft/textures/item/{material}_sign.png' + out_path = f'{out_dir}/icon/{material}_sign.png' + out_path_wall = f'{out_dir}/icon/{material}_wall_sign.png' + + in_image = Image.open(in_path) + + out_image = Image.new('RGBA', (13, 14)) + out_image.paste(in_image.crop((2, 2, 15, 16)), (0, 0)) + out_image.save(out_path) + + out_image = Image.new('RGBA', (13, 9)) + out_image.paste(in_image.crop((2, 2, 15, 11)), (0, 0)) + out_image.save(out_path_wall) + + +def hanging_sign_icon_image(material): + in_path = f'{in_dir}/assets/minecraft/textures/item/{material}_hanging_sign.png' + out_path = f'{out_dir}/icon/{material}_hanging_sign.png' + out_path_wall = f'{out_dir}/icon/{material}_hanging_wall_sign.png' + + in_image = Image.open(in_path) + + out_image = Image.new('RGBA', (14, 12)) + out_image.paste(in_image.crop((1, 3, 15, 15)), (0, 0)) + out_image.save(out_path) + + out_image = Image.new('RGBA', (14, 14)) + out_image.paste(in_image.crop((1, 1, 15, 15)), (0, 0)) + out_image.save(out_path_wall) + +for material in MATERIALS: + sign_bg_image(material) + hanging_sign_bg_image(material) + sign_icon_image(material) + hanging_sign_icon_image(material) diff --git a/src/core/common.rs b/src/core/common.rs index 39c8e54..92d0019 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -6,21 +6,47 @@ use std::{ path::{Path, PathBuf}, }; +use anyhow::{Context, Result}; use indexmap::IndexSet; +use regex::RegexSet; use serde::{Deserialize, Serialize}; -use crate::{io::fs::FileMetaVersion, resource::Biome, types::*, world::layer}; +use crate::{ + io::fs::FileMetaVersion, + resource::Biome, + types::*, + world::{block_entity::BlockEntity, layer}, +}; /// Increase to force regeneration of all output files /// MinedMap processed region data version number -pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); +/// +/// Increase when the generation of processed regions from region data changes +/// (usually because of updated resource data) +pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(1); /// MinedMap map tile data version number +/// +/// Increase when the generation of map tiles from processed regions changes +/// (because of code changes in tile generation) pub const MAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); /// MinedMap lightmap data version number -pub const LIGHTMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); +/// +/// Increase when the generation of lightmap tiles from region data changes +/// (usually because of updated resource data) +pub const LIGHTMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(1); + +/// MinedMap mipmap data version number +/// +/// Increase when the mipmap generation changes (this should not happen) +pub const MIPMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); + +/// MinedMap processed entity data version number +/// +/// Increase when entity collection changes bacause of code changes. +pub const ENTITIES_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); /// Coordinate pair of a generated tile /// @@ -80,6 +106,13 @@ pub struct ProcessedRegion { pub chunks: ChunkArray>>, } +/// Data structure for storing entity data between processing and collection steps +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct ProcessedEntities { + /// List of block entities + pub block_entities: Vec, +} + /// Derives a filename from region coordinates and a file extension /// /// Can be used for input regions, processed data or rendered tiles @@ -108,13 +141,21 @@ pub struct Config { pub output_dir: PathBuf, /// Path for storage of intermediate processed data files pub processed_dir: PathBuf, + /// Path for storage of processed entity data files + pub entities_dir: PathBuf, + /// Path for storage of the final merged processed entity data file + pub entities_path_final: PathBuf, /// Path of viewer metadata file - pub metadata_path: PathBuf, + pub viewer_info_path: PathBuf, + /// Path of viewer entities file + pub viewer_entities_path: PathBuf, + /// Sign text filter patterns + pub sign_patterns: RegexSet, } impl Config { /// Crates a new [Config] from [command line arguments](super::Args) - pub fn new(args: &super::Args) -> Self { + pub fn new(args: &super::Args) -> Result { let num_threads = match args.jobs { Some(0) => num_cpus::get(), Some(threads) => threads, @@ -123,17 +164,40 @@ impl Config { let region_dir = [&args.input_dir, Path::new("region")].iter().collect(); let level_dat_path = [&args.input_dir, Path::new("level.dat")].iter().collect(); - let processed_dir = [&args.output_dir, Path::new("processed")].iter().collect(); - let metadata_path = [&args.output_dir, Path::new("info.json")].iter().collect(); + let processed_dir: PathBuf = [&args.output_dir, Path::new("processed")].iter().collect(); + let entities_dir: PathBuf = [&processed_dir, Path::new("entities")].iter().collect(); + let entities_path_final = [&entities_dir, Path::new("entities.bin")].iter().collect(); + let viewer_info_path = [&args.output_dir, Path::new("info.json")].iter().collect(); + let viewer_entities_path = [&args.output_dir, Path::new("entities.json")] + .iter() + .collect(); - Config { + let sign_patterns = Self::sign_patterns(args).context("Failed to parse sign patterns")?; + + Ok(Config { num_threads, region_dir, level_dat_path, output_dir: args.output_dir.clone(), processed_dir, - metadata_path, - } + entities_dir, + entities_path_final, + viewer_info_path, + viewer_entities_path, + sign_patterns, + }) + } + + /// Parses the sign prefixes and sign filters into a [RegexSet] + fn sign_patterns(args: &super::Args) -> Result { + let prefix_patterns: Vec<_> = args + .sign_prefix + .iter() + .map(|prefix| format!("^{}", regex::escape(prefix))) + .collect(); + Ok(RegexSet::new( + prefix_patterns.iter().chain(args.sign_filter.iter()), + )?) } /// Constructs the path to an input region file @@ -148,6 +212,20 @@ impl Config { [&self.processed_dir, Path::new(&filename)].iter().collect() } + /// Constructs the base output path for processed entity data + pub fn entities_dir(&self, level: usize) -> PathBuf { + [&self.entities_dir, Path::new(&level.to_string())] + .iter() + .collect() + } + + /// Constructs the path of a processed entity data file + pub fn entities_path(&self, level: usize, coords: TileCoords) -> PathBuf { + let filename = coord_filename(coords, "bin"); + let dir = self.entities_dir(level); + [Path::new(&dir), Path::new(&filename)].iter().collect() + } + /// Constructs the base output path for a [TileKind] and mipmap level pub fn tile_dir(&self, kind: TileKind, level: usize) -> PathBuf { let prefix = match kind { diff --git a/src/core/entity_collector.rs b/src/core/entity_collector.rs new file mode 100644 index 0000000..3d9b6ab --- /dev/null +++ b/src/core/entity_collector.rs @@ -0,0 +1,123 @@ +//! The [EntityCollector] + +use std::path::Path; + +use anyhow::{Context, Result}; +use tracing::{info, warn}; + +use super::{common::*, tile_collector::TileCollector, tile_merger::TileMerger}; +use crate::io::{fs, storage}; + +/// Generates mipmap tiles from full-resolution tile images +pub struct EntityCollector<'a> { + /// Common MinedMap configuration from command line + config: &'a Config, + /// List of populated tiles for base mipmap level (level 0) + regions: &'a [TileCoords], +} + +impl<'a> TileMerger for EntityCollector<'a> { + fn file_meta_version(&self) -> fs::FileMetaVersion { + ENTITIES_FILE_META_VERSION + } + + fn tile_path(&self, level: usize, coords: TileCoords) -> std::path::PathBuf { + self.config.entities_path(level, coords) + } + + fn write_tile( + &self, + file: &mut std::io::BufWriter, + sources: &[super::tile_merger::Source], + ) -> Result<()> { + Self::merge_entity_lists(file, sources.iter().map(|source| &source.1)) + } +} + +impl<'a> TileCollector for EntityCollector<'a> { + type CollectOutput = (); + + fn tiles(&self) -> &[TileCoords] { + self.regions + } + + fn prepare(&self, level: usize) -> Result<()> { + fs::create_dir_all(&self.config.entities_dir(level)) + } + + fn finish( + &self, + _level: usize, + _outputs: impl Iterator, + ) -> Result<()> { + Ok(()) + } + + fn collect_one( + &self, + level: usize, + coords: TileCoords, + prev: &TileCoordMap, + ) -> Result { + self.merge_tiles(level, coords, prev)?; + Ok(()) + } +} + +impl<'a> EntityCollector<'a> { + /// Constructs a new EntityCollector + pub fn new(config: &'a Config, regions: &'a [TileCoords]) -> Self { + EntityCollector { config, regions } + } + + /// Merges multiple entity lists into one + fn merge_entity_lists>( + file: &mut std::io::BufWriter, + sources: impl Iterator, + ) -> Result<()> { + let mut output = ProcessedEntities::default(); + + for source_path in sources { + let mut source: ProcessedEntities = + match storage::read_file(source_path.as_ref(), storage::Format::Json) { + Ok(source) => source, + Err(err) => { + warn!( + "Failed to read entity data file {}: {:?}", + source_path.as_ref().display(), + err, + ); + continue; + } + }; + + output.block_entities.append(&mut source.block_entities); + } + + storage::write(file, &output, storage::Format::Json).context("Failed to write entity data") + } + + /// Runs the mipmap generation + pub fn run(self) -> Result<()> { + info!("Collecting entity data..."); + + let tile_stack = self.collect_tiles()?; + + // Final merge + let level = tile_stack.len() - 1; + let tile_map = &tile_stack[level]; + let sources: Vec<_> = [(-1, -1), (-1, 0), (0, -1), (0, 0)] + .into_iter() + .map(|(x, z)| TileCoords { x, z }) + .filter(|&coords| tile_map.contains(coords)) + .map(|coords| self.tile_path(level, coords)) + .collect(); + + fs::create_with_tmpfile(&self.config.entities_path_final, |file| { + Self::merge_entity_lists(file, sources.iter()) + })?; + + info!("Collected entity data."); + Ok(()) + } +} diff --git a/src/core/metadata_writer.rs b/src/core/metadata_writer.rs index 5783356..b051b69 100644 --- a/src/core/metadata_writer.rs +++ b/src/core/metadata_writer.rs @@ -3,7 +3,14 @@ use anyhow::{Context, Result}; use serde::Serialize; -use crate::{core::common::*, io::fs, world::de}; +use crate::{ + core::common::*, + io::{fs, storage}, + world::{ + block_entity::{self, BlockEntity, BlockEntityData}, + de, + }, +}; /// Minimum and maximum X and Z tile coordinates for a mipmap level #[derive(Debug, Serialize)] @@ -37,6 +44,13 @@ struct Spawn { z: i32, } +/// Keeps track of enabled MinedMap features +#[derive(Debug, Serialize)] +struct Features { + /// Sign layer + signs: bool, +} + /// Viewer metadata JSON data structure #[derive(Debug, Serialize)] struct Metadata<'t> { @@ -44,6 +58,15 @@ struct Metadata<'t> { mipmaps: Vec>, /// Initial spawn point for new players spawn: Spawn, + /// Enabled MinedMap features + features: Features, +} + +/// Viewer entity JSON data structure +#[derive(Debug, Serialize, Default)] +struct Entities { + /// List of signs + signs: Vec, } /// The MetadataWriter is used to generate the viewer metadata file @@ -109,21 +132,65 @@ impl<'a> MetadataWriter<'a> { } } + /// Filter signs according to the sign pattern configuration + fn sign_filter(&self, sign: &block_entity::Sign) -> bool { + let front_text = sign.front_text.to_string(); + if self.config.sign_patterns.is_match(front_text.trim()) { + return true; + } + let back_text = sign.back_text.to_string(); + if self.config.sign_patterns.is_match(back_text.trim()) { + return true; + } + false + } + + /// Generates [Entities] data from collected entity lists + fn entities(&self) -> Result { + let data: ProcessedEntities = + storage::read_file(&self.config.entities_path_final, storage::Format::Json) + .context("Failed to read entity data file")?; + + let ret = Entities { + signs: data + .block_entities + .into_iter() + .filter(|entity| match &entity.data { + BlockEntityData::Sign(sign) => self.sign_filter(sign), + }) + .collect(), + }; + + Ok(ret) + } + /// Runs the viewer metadata file generation pub fn run(self) -> Result<()> { let level_dat = self.read_level_dat()?; + let features = Features { + signs: !self.config.sign_patterns.is_empty(), + }; + let mut metadata = Metadata { mipmaps: Vec::new(), spawn: Self::spawn(&level_dat), + features, }; for tile_map in self.tiles.iter() { metadata.mipmaps.push(Self::mipmap_entry(tile_map)); } - fs::create_with_tmpfile(&self.config.metadata_path, |file| { - serde_json::to_writer(file, &metadata).context("Failed to write metadata") - }) + fs::create_with_tmpfile(&self.config.viewer_info_path, |file| { + serde_json::to_writer(file, &metadata).context("Failed to write info.json") + })?; + + let entities = self.entities()?; + fs::create_with_tmpfile(&self.config.viewer_entities_path, |file| { + serde_json::to_writer(file, &entities).context("Failed to write entities.json") + })?; + + Ok(()) } } diff --git a/src/core/mod.rs b/src/core/mod.rs index 0e77768..274bae8 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -1,9 +1,12 @@ //! Core functions of the MinedMap CLI mod common; +mod entity_collector; mod metadata_writer; mod region_group; mod region_processor; +mod tile_collector; +mod tile_merger; mod tile_mipmapper; mod tile_renderer; @@ -19,6 +22,8 @@ use region_processor::RegionProcessor; use tile_mipmapper::TileMipmapper; use tile_renderer::TileRenderer; +use self::entity_collector::EntityCollector; + /// MinedMap version number const VERSION: &str = git_version!( args = ["--abbrev=7", "--match=v*", "--dirty=-modified"], @@ -27,7 +32,11 @@ const VERSION: &str = git_version!( /// Command line arguments for minedmap CLI #[derive(Debug, Parser)] -#[command(about, version = VERSION.strip_prefix("v").unwrap())] +#[command( + about, + version = VERSION.strip_prefix("v").unwrap(), + max_term_width = 100, +)] pub struct Args { /// Number of parallel threads to use for processing /// @@ -38,6 +47,18 @@ pub struct Args { /// Enable verbose messages #[arg(short, long)] pub verbose: bool, + /// Prefix for text of signs to show on the map + #[arg(long)] + pub sign_prefix: Vec, + /// Regular expression for text of signs to show on the map + /// + /// --sign-prefix and --sign-filter allow to filter for signs to display; + /// by default, none are visible. The options may be passed multiple times, + /// and a sign will be visible if it matches any pattern. + /// + /// To make all signs visible, pass an empty string to either option. + #[arg(long)] + pub sign_filter: Vec, /// Minecraft save directory pub input_dir: PathBuf, /// MinedMap data directory @@ -55,7 +76,7 @@ fn setup_threads(num_threads: usize) -> Result<()> { /// MinedMap CLI main function pub fn cli() -> Result<()> { let args = Args::parse(); - let config = Config::new(&args); + let config = Config::new(&args)?; tracing_subscriber::fmt() .with_max_level(if args.verbose { @@ -75,6 +96,7 @@ pub fn cli() -> Result<()> { let regions = RegionProcessor::new(&config).run()?; TileRenderer::new(&config, &rt, ®ions).run()?; let tiles = TileMipmapper::new(&config, ®ions).run()?; + EntityCollector::new(&config, ®ions).run()?; MetadataWriter::new(&config, &tiles).run()?; Ok(()) diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index 0a8ad0e..63d5c09 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -64,20 +64,28 @@ struct SingleRegionProcessor<'a> { output_path: PathBuf, /// Lightmap output filename lightmap_path: PathBuf, + /// Processed entity output filename + entities_path: PathBuf, /// Timestamp of last modification of input file input_timestamp: SystemTime, /// Timestamp of last modification of processed region output file (if valid) output_timestamp: Option, /// Timestamp of last modification of lightmap output file (if valid) lightmap_timestamp: Option, + /// Timestamp of last modification of entity list output file (if valid) + entities_timestamp: Option, /// True if processed region output file needs to be updated output_needed: bool, /// True if lightmap output file needs to be updated lightmap_needed: bool, + /// True if entity output file needs to be updated + entities_needed: bool, /// Processed region intermediate data processed_region: ProcessedRegion, /// Lightmap intermediate data lightmap: image::GrayAlphaImage, + /// Processed entity intermediate data + entities: ProcessedEntities, /// True if any unknown block or biome types were encountered during processing has_unknown: bool, } @@ -93,14 +101,20 @@ impl<'a> SingleRegionProcessor<'a> { let output_path = processor.config.processed_path(coords); let output_timestamp = fs::read_timestamp(&output_path, REGION_FILE_META_VERSION); + let lightmap_path = processor.config.tile_path(TileKind::Lightmap, 0, coords); let lightmap_timestamp = fs::read_timestamp(&lightmap_path, LIGHTMAP_FILE_META_VERSION); + let entities_path = processor.config.entities_path(0, coords); + let entities_timestamp = fs::read_timestamp(&entities_path, ENTITIES_FILE_META_VERSION); + let output_needed = Some(input_timestamp) > output_timestamp; let lightmap_needed = Some(input_timestamp) > lightmap_timestamp; + let entities_needed = Some(input_timestamp) > entities_timestamp; let processed_region = ProcessedRegion::default(); let lightmap = image::GrayAlphaImage::new(N, N); + let entities = ProcessedEntities::default(); Ok(SingleRegionProcessor { block_types: &processor.block_types, @@ -109,13 +123,17 @@ impl<'a> SingleRegionProcessor<'a> { input_path, output_path, lightmap_path, + entities_path, input_timestamp, output_timestamp, lightmap_timestamp, + entities_timestamp, output_needed, lightmap_needed, + entities_needed, processed_region, lightmap, + entities, has_unknown: false, }) } @@ -145,9 +163,10 @@ impl<'a> SingleRegionProcessor<'a> { return Ok(()); } - storage::write( + storage::write_file( &self.output_path, &self.processed_region, + storage::Format::Bincode, REGION_FILE_META_VERSION, self.input_timestamp, ) @@ -173,34 +192,64 @@ impl<'a> SingleRegionProcessor<'a> { ) } + /// Saves processed entity data + /// + /// The timestamp is the time of the last modification of the input region data. + fn save_entities(&mut self) -> Result<()> { + if !self.entities_needed { + return Ok(()); + } + + self.entities.block_entities.sort_unstable(); + + storage::write_file( + &self.entities_path, + &self.entities, + storage::Format::Json, + ENTITIES_FILE_META_VERSION, + self.input_timestamp, + ) + } + /// Processes a single chunk fn process_chunk(&mut self, chunk_coords: ChunkCoords, data: world::de::Chunk) -> Result<()> { let (chunk, has_unknown) = world::chunk::Chunk::new(&data, self.block_types, self.biome_types) .with_context(|| format!("Failed to decode chunk {:?}", chunk_coords))?; self.has_unknown |= has_unknown; - let Some(layer::LayerData { - blocks, - biomes, - block_light, - depths, - }) = world::layer::top_layer(&mut self.processed_region.biome_list, &chunk) - .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))? - else { - return Ok(()); - }; - if self.output_needed { - self.processed_region.chunks[chunk_coords] = Some(Box::new(ProcessedChunk { + if self.output_needed || self.lightmap_needed { + if let Some(layer::LayerData { blocks, biomes, + block_light, depths, - })); + }) = world::layer::top_layer(&mut self.processed_region.biome_list, &chunk) + .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))? + { + if self.output_needed { + self.processed_region.chunks[chunk_coords] = Some(Box::new(ProcessedChunk { + blocks, + biomes, + depths, + })); + } + + if self.lightmap_needed { + let chunk_lightmap = Self::render_chunk_lightmap(block_light); + overlay_chunk(&mut self.lightmap, &chunk_lightmap, chunk_coords); + } + } } - if self.lightmap_needed { - let chunk_lightmap = Self::render_chunk_lightmap(block_light); - overlay_chunk(&mut self.lightmap, &chunk_lightmap, chunk_coords); + if self.entities_needed { + let mut block_entities = chunk.block_entities().with_context(|| { + format!( + "Failed to process block entities for chunk {:?}", + chunk_coords, + ) + })?; + self.entities.block_entities.append(&mut block_entities); } Ok(()) @@ -214,7 +263,7 @@ impl<'a> SingleRegionProcessor<'a> { /// Processes the region fn run(mut self) -> Result { - if !self.output_needed && !self.lightmap_needed { + if !self.output_needed && !self.lightmap_needed && !self.entities_needed { debug!( "Skipping unchanged region r.{}.{}.mca", self.coords.x, self.coords.z @@ -228,7 +277,10 @@ impl<'a> SingleRegionProcessor<'a> { ); if let Err(err) = self.process_chunks() { - if self.output_timestamp.is_some() && self.lightmap_timestamp.is_some() { + if self.output_timestamp.is_some() + && self.lightmap_timestamp.is_some() + && self.entities_timestamp.is_some() + { warn!( "Failed to process region {:?}, using old data: {:?}", self.coords, err @@ -245,6 +297,7 @@ impl<'a> SingleRegionProcessor<'a> { self.save_region()?; self.save_lightmap()?; + self.save_entities()?; Ok(if self.has_unknown { RegionProcessorStatus::OkWithUnknown @@ -312,6 +365,7 @@ impl<'a> RegionProcessor<'a> { pub fn run(self) -> Result> { fs::create_dir_all(&self.config.processed_dir)?; fs::create_dir_all(&self.config.tile_dir(TileKind::Lightmap, 0))?; + fs::create_dir_all(&self.config.entities_dir(0))?; info!("Processing region files..."); diff --git a/src/core/tile_collector.rs b/src/core/tile_collector.rs new file mode 100644 index 0000000..dfc6085 --- /dev/null +++ b/src/core/tile_collector.rs @@ -0,0 +1,107 @@ +//! A trait for recursively processing tiles +//! +//! Used for mipmap generation and collecting entity data + +use std::sync::mpsc; + +use anyhow::Result; +use rayon::prelude::*; + +use super::common::*; + +/// Helper to determine if no further mipmap levels are needed +/// +/// If all tile coordinates are -1 or 0, further mipmap levels will not +/// decrease the number of tiles and mipmap generated is considered finished. +fn done(tiles: &TileCoordMap) -> bool { + tiles + .0 + .iter() + .all(|(z, xs)| (-1..=0).contains(z) && xs.iter().all(|x| (-1..=0).contains(x))) +} + +/// Derives the map of populated tile coordinates for the next mipmap level +fn map_coords(tiles: &TileCoordMap) -> TileCoordMap { + let mut ret = TileCoordMap::default(); + + for (&z, xs) in &tiles.0 { + for &x in xs { + let xt = x >> 1; + let zt = z >> 1; + + ret.0.entry(zt).or_default().insert(xt); + } + } + + ret +} + +/// Trait to implement for collecting tiles recursively +pub trait TileCollector: Sync { + /// Return value of [TileCollector::collect_one] + type CollectOutput: Send; + + /// List of level 0 tiles + fn tiles(&self) -> &[TileCoords]; + + /// Called at the beginning of each level of processing + fn prepare(&self, level: usize) -> Result<()>; + + /// Called at the end of each level of processing + fn finish( + &self, + level: usize, + outputs: impl Iterator, + ) -> Result<()>; + + /// Called for each tile coordinate of the level that is currently being generated + fn collect_one( + &self, + level: usize, + coords: TileCoords, + prev: &TileCoordMap, + ) -> Result; + + /// Collects tiles recursively + fn collect_tiles(&self) -> Result> { + let mut tile_stack = { + let mut tile_map = TileCoordMap::default(); + + for &TileCoords { x, z } in self.tiles() { + tile_map.0.entry(z).or_default().insert(x); + } + + vec![tile_map] + }; + + loop { + let level = tile_stack.len(); + let prev = &tile_stack[level - 1]; + if done(prev) { + break; + } + + self.prepare(level)?; + + let next = map_coords(prev); + + let (send, recv) = mpsc::channel(); + + next.0 + .par_iter() + .flat_map(|(&z, xs)| xs.par_iter().map(move |&x| TileCoords { x, z })) + .try_for_each(|coords| { + let output = self.collect_one(level, coords, prev)?; + send.send(output).unwrap(); + anyhow::Ok(()) + })?; + + drop(send); + self.finish(level, recv.into_iter())?; + + tile_stack.push(next); + } + + Ok(tile_stack) + } +} diff --git a/src/core/tile_merger.rs b/src/core/tile_merger.rs new file mode 100644 index 0000000..6f3cc22 --- /dev/null +++ b/src/core/tile_merger.rs @@ -0,0 +1,97 @@ +//! Mipmap-style merging of tiles + +use std::{ + fs::File, + io::BufWriter, + path::{Path, PathBuf}, + time::SystemTime, +}; + +use anyhow::Result; +use tracing::warn; + +use super::common::*; +use crate::io::fs; + +/// [TileMerger::merge_tiles] return +#[derive(Debug, Clone, Copy)] +pub enum Stat { + /// None of the input files were found + NotFound, + /// The output file is up-to-date + Skipped, + /// The output file is regenerated + Regenerate, +} + +/// A source file for the [TileMerger] +/// +/// The tuple elements are X and Z coordinate offsets in the range [0, 1], +/// the file path and the time of last change of the input. +pub type Source = ((i32, i32), PathBuf, SystemTime); + +/// Reusable trait for mipmap-style tile merging with change tracking +pub trait TileMerger { + /// [fs::FileMetaVersion] of input and output files + /// + /// The version in the file metadata on disk must match the returned + /// version for the a to be considered up-to-date. + fn file_meta_version(&self) -> fs::FileMetaVersion; + + /// Returns the paths of input and output files + fn tile_path(&self, level: usize, coords: TileCoords) -> PathBuf; + + /// Can be used to log the processing status + fn log(&self, _output_path: &Path, _stat: Stat) {} + + /// Handles the actual merging of source files + fn write_tile(&self, file: &mut BufWriter, sources: &[Source]) -> Result<()>; + + /// Generates a tile at given coordinates and mipmap level + fn merge_tiles(&self, level: usize, coords: TileCoords, prev: &TileCoordMap) -> Result { + let version = self.file_meta_version(); + let output_path = self.tile_path(level, coords); + let output_timestamp = fs::read_timestamp(&output_path, version); + + let sources: Vec<_> = [(0, 0), (0, 1), (1, 0), (1, 1)] + .into_iter() + .filter_map(|(dx, dz)| { + let source_coords = TileCoords { + x: 2 * coords.x + dx, + z: 2 * coords.z + dz, + }; + if !prev.contains(source_coords) { + return None; + } + + let source_path = self.tile_path(level - 1, source_coords); + let timestamp = match fs::modified_timestamp(&source_path) { + Ok(timestamp) => timestamp, + Err(err) => { + warn!("{:?}", err); + return None; + } + }; + Some(((dx, dz), source_path, timestamp)) + }) + .collect(); + + let Some(input_timestamp) = sources.iter().map(|(_, _, ts)| *ts).max() else { + self.log(&output_path, Stat::NotFound); + return Ok(Stat::NotFound); + }; + + if Some(input_timestamp) <= output_timestamp { + self.log(&output_path, Stat::Skipped); + return Ok(Stat::Skipped); + } + + self.log(&output_path, Stat::Regenerate); + + fs::create_with_timestamp(&output_path, version, input_timestamp, |file| { + self.write_tile(file, &sources) + })?; + + Ok(Stat::Regenerate) + } +} diff --git a/src/core/tile_mipmapper.rs b/src/core/tile_mipmapper.rs index 355bd23..cd90e20 100644 --- a/src/core/tile_mipmapper.rs +++ b/src/core/tile_mipmapper.rs @@ -1,14 +1,154 @@ //! The [TileMipmapper] -use std::sync::mpsc; +use std::{marker::PhantomData, ops::Add}; use anyhow::{Context, Result}; -use rayon::prelude::*; use tracing::{debug, info, warn}; -use super::common::*; +use super::{ + common::*, + tile_collector::TileCollector, + tile_merger::{self, TileMerger}, +}; use crate::{io::fs, types::*}; +/// Counters for the number of processed and total tiles +/// +/// Used as return of [TileMipmapper::collect_one] +#[derive(Debug, Clone, Copy)] +pub struct MipmapStat { + /// Total number of tiles + total: usize, + /// Processed number of tiles + processed: usize, +} + +impl From for MipmapStat { + fn from(value: tile_merger::Stat) -> Self { + match value { + tile_merger::Stat::NotFound => MipmapStat { + total: 0, + processed: 0, + }, + tile_merger::Stat::Skipped => MipmapStat { + total: 1, + processed: 0, + }, + tile_merger::Stat::Regenerate => MipmapStat { + total: 1, + processed: 1, + }, + } + } +} + +impl Add for MipmapStat { + type Output = MipmapStat; + + fn add(self, rhs: Self) -> Self::Output { + MipmapStat { + total: self.total + rhs.total, + processed: self.processed + rhs.processed, + } + } +} + +/// [TileMerger] for map tile images +struct MapMerger<'a, P> { + /// Common MinedMap configuration from command line + config: &'a Config, + /// Tile kind (map or lightmap) + kind: TileKind, + /// Pixel format type + _pixel: PhantomData

, +} + +impl<'a, P> MapMerger<'a, P> { + /// Creates a new [MapMerger] + fn new(config: &'a Config, kind: TileKind) -> Self { + MapMerger { + config, + kind, + _pixel: PhantomData, + } + } +} + +impl<'a, P: image::PixelWithColorType> TileMerger for MapMerger<'a, P> +where + [P::Subpixel]: image::EncodableLayout, + image::ImageBuffer>: Into, +{ + fn file_meta_version(&self) -> fs::FileMetaVersion { + MIPMAP_FILE_META_VERSION + } + + fn tile_path(&self, level: usize, coords: TileCoords) -> std::path::PathBuf { + self.config.tile_path(self.kind, level, coords) + } + + fn log(&self, output_path: &std::path::Path, stat: super::tile_merger::Stat) { + match stat { + super::tile_merger::Stat::NotFound => {} + super::tile_merger::Stat::Skipped => { + debug!( + "Skipping unchanged mipmap tile {}", + output_path + .strip_prefix(&self.config.output_dir) + .expect("tile path must be in output directory") + .display(), + ); + } + super::tile_merger::Stat::Regenerate => { + debug!( + "Rendering mipmap tile {}", + output_path + .strip_prefix(&self.config.output_dir) + .expect("tile path must be in output directory") + .display(), + ); + } + }; + } + + fn write_tile( + &self, + file: &mut std::io::BufWriter, + sources: &[super::tile_merger::Source], + ) -> Result<()> { + /// Tile width/height + const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; + + let mut image: image::DynamicImage = + image::ImageBuffer::>::new(N, N).into(); + + for ((dx, dz), source_path, _) in sources { + let source = match image::open(source_path) { + Ok(source) => source, + Err(err) => { + warn!( + "Failed to read source image {}: {:?}", + source_path.display(), + err, + ); + continue; + } + }; + let resized = source.resize(N / 2, N / 2, image::imageops::FilterType::Triangle); + image::imageops::overlay( + &mut image, + &resized, + *dx as i64 * (N / 2) as i64, + *dz as i64 * (N / 2) as i64, + ); + } + + image + .write_to(file, image::ImageFormat::Png) + .context("Failed to save image") + } +} + /// Generates mipmap tiles from full-resolution tile images pub struct TileMipmapper<'a> { /// Common MinedMap configuration from command line @@ -17,39 +157,63 @@ pub struct TileMipmapper<'a> { regions: &'a [TileCoords], } +impl<'a> TileCollector for TileMipmapper<'a> { + type CollectOutput = MipmapStat; + + fn tiles(&self) -> &[TileCoords] { + self.regions + } + + fn prepare(&self, level: usize) -> Result<()> { + info!("Generating level {} mipmaps...", level); + + fs::create_dir_all(&self.config.tile_dir(TileKind::Map, level))?; + fs::create_dir_all(&self.config.tile_dir(TileKind::Lightmap, level))?; + + Ok(()) + } + + fn finish( + &self, + level: usize, + outputs: impl Iterator, + ) -> Result<()> { + let stat = outputs.fold( + MipmapStat { + total: 0, + processed: 0, + }, + MipmapStat::add, + ); + info!( + "Generated level {} mipmaps ({} processed, {} unchanged)", + level, + stat.processed, + stat.total - stat.processed, + ); + + Ok(()) + } + + fn collect_one( + &self, + level: usize, + coords: TileCoords, + prev: &TileCoordMap, + ) -> Result { + let map_stat = self.render_mipmap::>(TileKind::Map, level, coords, prev)?; + let lightmap_stat = + self.render_mipmap::>(TileKind::Lightmap, level, coords, prev)?; + Ok(map_stat + lightmap_stat) + } +} + impl<'a> TileMipmapper<'a> { /// Constructs a new TileMipmapper pub fn new(config: &'a Config, regions: &'a [TileCoords]) -> Self { TileMipmapper { config, regions } } - /// Helper to determine if no further mipmap levels are needed - /// - /// If all tile coordinates are -1 or 0, further mipmap levels will not - /// decrease the number of tiles and mipmap generated is considered finished. - fn done(tiles: &TileCoordMap) -> bool { - tiles - .0 - .iter() - .all(|(z, xs)| (-1..=0).contains(z) && xs.iter().all(|x| (-1..=0).contains(x))) - } - - /// Derives the map of populated tile coordinates for the next mipmap level - fn map_coords(tiles: &TileCoordMap) -> TileCoordMap { - let mut ret = TileCoordMap::default(); - - for (&z, xs) in &tiles.0 { - for &x in xs { - let xt = x >> 1; - let zt = z >> 1; - - ret.0.entry(zt).or_default().insert(xt); - } - } - - ret - } - /// Renders and saves a single mipmap tile image /// /// Each mipmap tile is rendered by taking 2x2 tiles from the @@ -60,174 +224,18 @@ impl<'a> TileMipmapper<'a> { level: usize, coords: TileCoords, prev: &TileCoordMap, - count_total: &mpsc::Sender<()>, - count_processed: &mpsc::Sender<()>, - ) -> Result<()> + ) -> Result where [P::Subpixel]: image::EncodableLayout, image::ImageBuffer>: Into, { - /// Tile width/height - const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; - - let version = match kind { - TileKind::Map => REGION_FILE_META_VERSION, - TileKind::Lightmap => LIGHTMAP_FILE_META_VERSION, - }; - let output_path = self.config.tile_path(kind, level, coords); - let output_timestamp = fs::read_timestamp(&output_path, version); - - let sources: Vec<_> = [(0, 0), (0, 1), (1, 0), (1, 1)] - .into_iter() - .filter_map(|(dx, dz)| { - let source_coords = TileCoords { - x: 2 * coords.x + dx, - z: 2 * coords.z + dz, - }; - if !prev.contains(source_coords) { - return None; - } - - let source_path = self.config.tile_path(kind, level - 1, source_coords); - let timestamp = match fs::modified_timestamp(&source_path) { - Ok(timestamp) => timestamp, - Err(err) => { - warn!("{}", err); - return None; - } - }; - Some(((dx, dz), source_path, timestamp)) - }) - .collect(); - - let Some(input_timestamp) = sources.iter().map(|(_, _, ts)| *ts).max() else { - return Ok(()); - }; - - count_total.send(()).unwrap(); - - if Some(input_timestamp) <= output_timestamp { - debug!( - "Skipping unchanged mipmap tile {}", - output_path - .strip_prefix(&self.config.output_dir) - .expect("tile path must be in output directory") - .display(), - ); - return Ok(()); - } - - debug!( - "Rendering mipmap tile {}", - output_path - .strip_prefix(&self.config.output_dir) - .expect("tile path must be in output directory") - .display(), - ); - - let mut image: image::DynamicImage = - image::ImageBuffer::>::new(N, N).into(); - - for ((dx, dz), source_path, _) in sources { - let source = match image::open(&source_path) { - Ok(source) => source, - Err(err) => { - warn!( - "Failed to read source image {}: {}", - source_path.display(), - err, - ); - continue; - } - }; - let resized = source.resize(N / 2, N / 2, image::imageops::FilterType::Triangle); - image::imageops::overlay( - &mut image, - &resized, - dx as i64 * (N / 2) as i64, - dz as i64 * (N / 2) as i64, - ); - } - - fs::create_with_timestamp(&output_path, version, input_timestamp, |file| { - image - .write_to(file, image::ImageFormat::Png) - .context("Failed to save image") - })?; - - count_processed.send(()).unwrap(); - Ok(()) + let merger = MapMerger::

::new(self.config, kind); + let ret = merger.merge_tiles(level, coords, prev)?; + Ok(ret.into()) } /// Runs the mipmap generation pub fn run(self) -> Result> { - let mut tile_stack = { - let mut tile_map = TileCoordMap::default(); - - for &TileCoords { x, z } in self.regions { - tile_map.0.entry(z).or_default().insert(x); - } - - vec![tile_map] - }; - - loop { - let level = tile_stack.len(); - let prev = &tile_stack[level - 1]; - if Self::done(prev) { - break; - } - - info!("Generating level {} mipmaps...", level); - - fs::create_dir_all(&self.config.tile_dir(TileKind::Map, level))?; - fs::create_dir_all(&self.config.tile_dir(TileKind::Lightmap, level))?; - - let next = Self::map_coords(prev); - - let (total_send, total_recv) = mpsc::channel(); - let (processed_send, processed_recv) = mpsc::channel(); - - next.0 - .par_iter() - .flat_map(|(&z, xs)| xs.par_iter().map(move |&x| TileCoords { x, z })) - .try_for_each(|coords| { - self.render_mipmap::>( - TileKind::Map, - level, - coords, - prev, - &total_send, - &processed_send, - )?; - self.render_mipmap::>( - TileKind::Lightmap, - level, - coords, - prev, - &total_send, - &processed_send, - )?; - - anyhow::Ok(()) - })?; - - drop(total_send); - let total = total_recv.into_iter().count(); - - drop(processed_send); - let processed = processed_recv.into_iter().count(); - - info!( - "Generated level {} mipmaps ({} processed, {} unchanged)", - level, - processed, - total - processed, - ); - - tile_stack.push(next); - } - - Ok(tile_stack) + self.collect_tiles() } } diff --git a/src/core/tile_renderer.rs b/src/core/tile_renderer.rs index b341076..09ad8a1 100644 --- a/src/core/tile_renderer.rs +++ b/src/core/tile_renderer.rs @@ -105,7 +105,8 @@ impl<'a> TileRenderer<'a> { region_loader .get_or_try_init(|| async { - storage::read(&processed_path).context("Failed to load processed region data") + storage::read_file(&processed_path, storage::Format::Bincode) + .context("Failed to load processed region data") }) .await .cloned() diff --git a/src/io/storage.rs b/src/io/storage.rs index 99a8d63..9296166 100644 --- a/src/io/storage.rs +++ b/src/io/storage.rs @@ -14,43 +14,70 @@ use serde::{de::DeserializeOwned, Serialize}; use super::fs; +/// Storage format +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum Format { + /// Encode as Bincode + /// + /// Bincode is more efficient than JSON, but cannot handle many of + /// serde's features like flatten, conditional skipping, ... + Bincode, + /// Encode as JSON + Json, +} + +/// Serializes data and writes it to a writer +pub fn write(writer: &mut W, value: &T, format: Format) -> Result<()> { + let data = match format { + Format::Bincode => bincode::serialize(value)?, + Format::Json => serde_json::to_vec(value)?, + }; + let len = u32::try_from(data.len())?; + let compressed = zstd::bulk::compress(&data, 1)?; + drop(data); + + writer.write_all(&len.to_be_bytes())?; + writer.write_all(&compressed)?; + + Ok(()) +} + /// Serializes data and stores it in a file /// /// A timestamp is stored in an assiciated metadata file. -pub fn write( +pub fn write_file( path: &Path, value: &T, + format: Format, version: fs::FileMetaVersion, timestamp: SystemTime, ) -> Result<()> { - fs::create_with_timestamp(path, version, timestamp, |file| { - let data = bincode::serialize(value)?; - let len = u32::try_from(data.len())?; - let compressed = zstd::bulk::compress(&data, 1)?; - drop(data); + fs::create_with_timestamp(path, version, timestamp, |file| write(file, value, format)) +} - file.write_all(&len.to_be_bytes())?; - file.write_all(&compressed)?; +/// Reads data from a reader and deserializes it +pub fn read(reader: &mut R, format: Format) -> Result { + let mut len_buf = [0u8; 4]; + reader.read_exact(&mut len_buf)?; + let len = usize::try_from(u32::from_be_bytes(len_buf))?; - Ok(()) - }) + let mut compressed = vec![]; + reader.read_to_end(&mut compressed)?; + let data = zstd::bulk::decompress(&compressed, len)?; + drop(compressed); + + let value = match format { + Format::Bincode => bincode::deserialize(&data)?, + Format::Json => serde_json::from_slice(&data)?, + }; + Ok(value) } /// Reads data from a file and deserializes it -pub fn read(path: &Path) -> Result { +pub fn read_file(path: &Path, format: Format) -> Result { (|| -> Result { let mut file = File::open(path)?; - - let mut len_buf = [0u8; 4]; - file.read_exact(&mut len_buf)?; - let len = usize::try_from(u32::from_be_bytes(len_buf))?; - - let mut compressed = vec![]; - file.read_to_end(&mut compressed)?; - let data = zstd::bulk::decompress(&compressed, len)?; - drop(compressed); - - Ok(bincode::deserialize(&data)?) + read(&mut file, format) })() .with_context(|| format!("Failed to read file {}", path.display())) } diff --git a/src/world/block_entity.rs b/src/world/block_entity.rs new file mode 100644 index 0000000..182ad50 --- /dev/null +++ b/src/world/block_entity.rs @@ -0,0 +1,103 @@ +//! Processing of block entity data + +use minedmap_resource::{BlockFlag, BlockType}; +use serde::{Deserialize, Serialize}; + +use super::{ + de, + sign::{BlockEntitySignExt, SignText}, +}; + +/// Kind of sign block +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] +#[serde(rename_all = "snake_case")] +pub enum SignKind { + /// Standing sign + Sign, + /// Sign attached to wall + WallSign, + /// Hanging sign + HangingSign, + /// Hanging sign attached to wall + HangingWallSign, +} + +/// Processed sign data +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] +pub struct Sign { + /// The kind of the sign + pub kind: SignKind, + /// The material of the sign + #[serde(skip_serializing_if = "Option::is_none", default)] + pub material: Option, + /// The sign's front text + #[serde(skip_serializing_if = "SignText::is_empty", default)] + pub front_text: SignText, + /// The sign's back text + #[serde(skip_serializing_if = "SignText::is_empty", default)] + pub back_text: SignText, +} + +impl Sign { + /// Processes a [de::BlockEntitySign] into a [Sign] + fn new(sign: &de::BlockEntitySign, kind: SignKind, material: Option) -> Sign { + let (front_text, back_text) = sign.text(); + let front_text = front_text.decode(); + let back_text = back_text.decode(); + Sign { + kind, + material, + front_text, + back_text, + } + } +} + +/// Data for different kinds of [BlockEntity] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] +#[serde(tag = "type", rename_all = "snake_case")] +pub enum BlockEntityData { + /// A sign block + Sign(Sign), +} + +/// A processed block entity +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] +pub struct BlockEntity { + /// Global X coordinate + pub x: i32, + /// Global Y coordinate + pub y: i32, + /// Global Z coordinate + pub z: i32, + /// Entity data + #[serde(flatten)] + pub data: BlockEntityData, +} + +impl BlockEntity { + /// Processes a [de::BlockEntity] into a [BlockEntity] + pub fn new(entity: &de::BlockEntity, block_type: Option<&BlockType>) -> Option { + let wall_sign = block_type + .map(|block_type| block_type.block_color.is(BlockFlag::WallSign)) + .unwrap_or_default(); + let (kind, sign) = match (&entity.data, wall_sign) { + (de::BlockEntityData::Sign(sign), false) => (SignKind::Sign, sign), + (de::BlockEntityData::Sign(sign), true) => (SignKind::WallSign, sign), + (de::BlockEntityData::HangingSign(sign), false) => (SignKind::HangingSign, sign), + (de::BlockEntityData::HangingSign(sign), true) => (SignKind::HangingWallSign, sign), + (de::BlockEntityData::Other, _) => return None, + }; + let material = block_type + .as_ref() + .and_then(|block_type| block_type.sign_material.as_ref()); + let data = BlockEntityData::Sign(Sign::new(sign, kind, material.cloned())); + + Some(BlockEntity { + x: entity.x, + y: entity.y, + z: entity.z, + data, + }) + } +} diff --git a/src/world/chunk.rs b/src/world/chunk.rs index 993a79e..bf1d78b 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -10,16 +10,16 @@ use std::{ use anyhow::{bail, Context, Result}; -use super::{de, section::*}; +use super::{block_entity::BlockEntity, de, section::*}; use crate::{ - resource::{BiomeTypes, BlockTypes}, + resource::{BiomeTypes, BlockType, BlockTypes}, types::*, + util::{self, ShiftMask}, }; -/// Chunk data structure wrapping a [de::Chunk] for convenient access to -/// block and biome data +/// Version-specific part of [Chunk] #[derive(Debug)] -pub enum Chunk<'a> { +pub enum ChunkInner<'a> { /// Minecraft v1.18+ chunk with biome data moved into sections V1_18 { /// Section data @@ -50,6 +50,16 @@ pub enum Chunk<'a> { Empty, } +/// Chunk data structure wrapping a [de::Chunk] for convenient access to +/// block and biome data +#[derive(Debug)] +pub struct Chunk<'a> { + /// Version-specific data + inner: ChunkInner<'a>, + /// Unprocessed block entities + block_entities: &'a Vec, +} + impl<'a> Chunk<'a> { /// Creates a new [Chunk] from a deserialized [de::Chunk] pub fn new( @@ -59,14 +69,27 @@ impl<'a> Chunk<'a> { ) -> Result<(Self, bool)> { let data_version = data.data_version.unwrap_or_default(); - match &data.chunk { - de::ChunkVariant::V1_18 { sections } => { - Self::new_v1_18(data_version, sections, block_types, biome_types) - } - de::ChunkVariant::V0 { level } => { - Self::new_v0(data_version, level, block_types, biome_types) - } - } + let ((inner, has_unknown), block_entities) = match &data.chunk { + de::ChunkVariant::V1_18 { + sections, + block_entities, + } => ( + Self::new_v1_18(data_version, sections, block_types, biome_types)?, + block_entities, + ), + de::ChunkVariant::V0 { level } => ( + Self::new_v0(data_version, level, block_types, biome_types)?, + &level.tile_entities, + ), + }; + + Ok(( + Chunk { + inner, + block_entities, + }, + has_unknown, + )) } /// [Chunk::new] implementation for Minecraft v1.18+ chunks @@ -75,7 +98,7 @@ impl<'a> Chunk<'a> { sections: &'a Vec, block_types: &'a BlockTypes, biome_types: &'a BiomeTypes, - ) -> Result<(Self, bool)> { + ) -> Result<(ChunkInner<'a>, bool)> { let mut section_map = BTreeMap::new(); let mut has_unknown = false; @@ -117,7 +140,7 @@ impl<'a> Chunk<'a> { }; } - let chunk = Chunk::V1_18 { section_map }; + let chunk = ChunkInner::V1_18 { section_map }; Ok((chunk, has_unknown)) } @@ -127,7 +150,7 @@ impl<'a> Chunk<'a> { level: &'a de::LevelV0, block_types: &'a BlockTypes, biome_types: &'a BiomeTypes, - ) -> Result<(Self, bool)> { + ) -> Result<(ChunkInner<'a>, bool)> { let mut section_map_v1_13 = BTreeMap::new(); let mut section_map_v0 = BTreeMap::new(); let mut has_unknown = false; @@ -167,12 +190,12 @@ impl<'a> Chunk<'a> { let biomes = BiomesV0::new(level.biomes.as_ref(), biome_types); let chunk = match (section_map_v1_13.is_empty(), section_map_v0.is_empty()) { - (true, true) => Chunk::Empty, - (false, true) => Chunk::V1_13 { + (true, true) => ChunkInner::Empty, + (false, true) => ChunkInner::V1_13 { section_map: section_map_v1_13, biomes: biomes?, }, - (true, false) => Chunk::V0 { + (true, false) => ChunkInner::V0 { section_map: section_map_v0, biomes: biomes?, }, @@ -186,11 +209,11 @@ impl<'a> Chunk<'a> { /// Returns true if the chunk does not contain any sections pub fn is_empty(&self) -> bool { - match self { - Chunk::V1_18 { section_map } => section_map.is_empty(), - Chunk::V1_13 { section_map, .. } => section_map.is_empty(), - Chunk::V0 { section_map, .. } => section_map.is_empty(), - Chunk::Empty => true, + match &self.inner { + ChunkInner::V1_18 { section_map } => section_map.is_empty(), + ChunkInner::V1_13 { section_map, .. } => section_map.is_empty(), + ChunkInner::V0 { section_map, .. } => section_map.is_empty(), + ChunkInner::Empty => true, } } @@ -198,28 +221,82 @@ impl<'a> Chunk<'a> { pub fn sections(&self) -> SectionIter { use SectionIterInner::*; SectionIter { - inner: match self { - Chunk::V1_18 { section_map } => V1_18 { + inner: match &self.inner { + ChunkInner::V1_18 { section_map } => V1_18 { iter: section_map.iter(), }, - Chunk::V1_13 { + ChunkInner::V1_13 { section_map, biomes, } => V1_13 { iter: section_map.iter(), biomes, }, - Chunk::V0 { + ChunkInner::V0 { section_map, biomes, } => V0 { iter: section_map.iter(), biomes, }, - Chunk::Empty => Empty, + ChunkInner::Empty => Empty, }, } } + + /// Returns the section at a [SectionY] coordinate + fn section_at(&self, y: SectionY) -> Option<&dyn Section> { + match &self.inner { + ChunkInner::V1_18 { section_map } => section_map + .get(&y) + .map(|(section, _, _)| -> &dyn Section { section }), + ChunkInner::V1_13 { section_map, .. } => section_map + .get(&y) + .map(|(section, _)| -> &dyn Section { section }), + ChunkInner::V0 { section_map, .. } => section_map + .get(&y) + .map(|(section, _)| -> &dyn Section { section }), + ChunkInner::Empty => None, + } + } + + /// Returns the [BlockType] at a given coordinate + fn block_type_at(&self, y: SectionY, coords: SectionBlockCoords) -> Result> { + let Some(section) = self.section_at(y) else { + return Ok(None); + }; + section.block_at(coords) + } + + /// Returns the [BlockType] at the coordinates of a [de::BlockEntity] + fn block_type_at_block_entity( + &self, + block_entity: &de::BlockEntity, + ) -> Result> { + let x: BlockX = util::from_flat_coord(block_entity.x).2; + let z: BlockZ = util::from_flat_coord(block_entity.z).2; + let (section_y, block_y) = block_entity.y.shift_mask(BLOCK_BITS); + + let coords = SectionBlockCoords { + xz: LayerBlockCoords { x, z }, + y: BlockY::new(block_y), + }; + + self.block_type_at(SectionY(section_y), coords) + } + + /// Processes all of the chunk's block entities + pub fn block_entities(&self) -> Result> { + let entities: Vec> = self + .block_entities + .iter() + .map(|block_entity| { + let block_type = self.block_type_at_block_entity(block_entity)?; + Ok(BlockEntity::new(block_entity, block_type)) + }) + .collect::>()?; + Ok(entities.into_iter().flatten().collect()) + } } /// Reference to block, biome and block light data of a section @@ -252,26 +329,26 @@ impl<'a, T> SectionIterTrait<'a> for T where /// Inner data structure of [SectionIter] #[derive(Debug, Clone)] enum SectionIterInner<'a> { - /// Iterator over sections of [Chunk::V1_18] + /// Iterator over sections of [ChunkInner::V1_18] V1_18 { /// Inner iterator into section map iter: btree_map::Iter<'a, SectionY, (SectionV1_13<'a>, BiomesV1_18<'a>, BlockLight<'a>)>, }, - /// Iterator over sections of [Chunk::V1_13] + /// Iterator over sections of [ChunkInner::V1_13] V1_13 { /// Inner iterator into section map iter: btree_map::Iter<'a, SectionY, (SectionV1_13<'a>, BlockLight<'a>)>, /// Chunk biome data biomes: &'a BiomesV0<'a>, }, - /// Iterator over sections of [Chunk::V0] + /// Iterator over sections of [ChunkInner::V0] V0 { /// Inner iterator into section map iter: btree_map::Iter<'a, SectionY, (SectionV0<'a>, BlockLight<'a>)>, /// Chunk biome data biomes: &'a BiomesV0<'a>, }, - /// Empty iterator over an unpopulated chunk ([Chunk::Empty]) + /// Empty iterator over an unpopulated chunk ([ChunkInner::Empty]) Empty, } diff --git a/src/world/de.rs b/src/world/de.rs index cf1b6b5..7ab8ba7 100644 --- a/src/world/de.rs +++ b/src/world/de.rs @@ -2,6 +2,8 @@ use serde::Deserialize; +use super::json_text::JSONText; + /// Element of the `palette` list of 1.18+ [block states](BlockStatesV1_18) #[derive(Debug, Deserialize)] #[serde(rename_all = "PascalCase")] @@ -104,6 +106,77 @@ pub enum BiomesV0 { ByteArray(fastnbt::ByteArray), } +/// Front/back text of a Minecraft 1.20+ sign block entry +#[derive(Debug, Deserialize)] +pub struct BlockEntitySignV1_20Text { + /// Lines of sign text + pub messages: Vec, + /// Default text color + pub color: Option, +} + +/// A sign (standing or hanging) block entity +#[derive(Debug, Deserialize)] +#[serde(untagged)] +pub enum BlockEntitySign { + /// Pre-1.20 sign block entity + /// + /// Pre-1.20 signs only have front text. + #[serde(rename_all = "PascalCase")] + V0 { + /// Line 1 of the sign text + text1: JSONText, + /// Line 2 of the sign text + text2: JSONText, + /// Line 3 of the sign text + text3: JSONText, + /// Line 4 of the sign text + text4: JSONText, + /// Default text color + color: Option, + }, + /// 1.20+ sign block entity + V1_20 { + /// The sign's front text + front_text: BlockEntitySignV1_20Text, + /// The sign's back text + back_text: BlockEntitySignV1_20Text, + }, +} + +/// Data for different kinds of block entities +#[derive(Debug, Deserialize)] +#[serde(tag = "id")] +pub enum BlockEntityData { + /// Regular sign + /// + /// This includes standing signs and signs attached to the side of blocks + #[serde(rename = "minecraft:sign", alias = "minecraft:standing_sign")] + Sign(BlockEntitySign), + /// Hanging sign + #[serde(rename = "minecraft:hanging_sign")] + HangingSign(BlockEntitySign), + /// Other block entity types not handled by MinedMap + #[serde(other)] + Other, +} + +/// A block entity +/// +/// Block entities were called tile entities pre-1.18 +#[derive(Debug, Deserialize)] +pub struct BlockEntity { + /// Entity global X coordinate + pub x: i32, + /// Entity global Y coordinate + pub y: i32, + /// Entity global Z coordinate + pub z: i32, + /// Kind-specific entity data + #[serde(flatten)] + pub data: BlockEntityData, +} + /// `Level` compound element found in pre-1.18 [chunks](Chunk) #[derive(Debug, Deserialize)] #[serde(rename_all = "PascalCase")] @@ -113,6 +186,9 @@ pub struct LevelV0 { pub sections: Vec, /// Biome data pub biomes: Option, + /// List of block entities + #[serde(default)] + pub tile_entities: Vec, } /// Version-specific part of a [Chunk] compound @@ -123,6 +199,9 @@ pub enum ChunkVariant { V1_18 { /// List of chunk sections sections: Vec, + /// List of block entities + #[serde(default)] + block_entities: Vec, }, /// Pre-1.18 chunk data #[serde(rename_all = "PascalCase")] diff --git a/src/world/json_text.rs b/src/world/json_text.rs new file mode 100644 index 0000000..a153179 --- /dev/null +++ b/src/world/json_text.rs @@ -0,0 +1,177 @@ +//! Newtype and helper methods for handling Minecraft Raw JSON Text + +use std::{collections::VecDeque, fmt::Display, sync::Arc}; + +use serde::{Deserialize, Serialize}; + +/// A span of formatted text +/// +/// A [JSONText] consists of a tree of [FormattedText] nodes (canonically +/// represented as a [FormattedTextTree], but other kinds are possible with +/// is handled by [DeserializedText]. +/// +/// Formatting that is not set in a node is inherited from the parent. +#[derive(Debug, Serialize, Deserialize, Default, PartialEq, Eq, PartialOrd, Ord)] +pub struct FormattedText { + #[serde(default)] + /// Text content + pub text: String, + /// Text color + #[serde(skip_serializing_if = "Option::is_none")] + pub color: Option>, + /// Bold formatting + #[serde(skip_serializing_if = "Option::is_none")] + pub bold: Option, + /// Italic formatting + #[serde(skip_serializing_if = "Option::is_none")] + pub italic: Option, + /// Underlines formatting + #[serde(skip_serializing_if = "Option::is_none")] + pub underlined: Option, + /// Strikethrough formatting + #[serde(skip_serializing_if = "Option::is_none")] + pub strikethrough: Option, + /// Obfuscated formatting + #[serde(skip_serializing_if = "Option::is_none")] + pub obfuscated: Option, +} + +impl FormattedText { + /// Fills in unset formatting fields from a parent node + pub fn inherit(self, parent: &Self) -> Self { + FormattedText { + text: self.text, + color: self.color.or_else(|| parent.color.clone()), + bold: self.bold.or(parent.bold), + italic: self.italic.or(parent.italic), + underlined: self.underlined.or(parent.underlined), + strikethrough: self.strikethrough.or(parent.strikethrough), + obfuscated: self.obfuscated.or(parent.obfuscated), + } + } +} + +impl Display for FormattedText { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.text.fmt(f) + } +} + +/// A tree of [FormattedText] nodes +/// +/// Each node including the root has a `text` and a list of children (`extra`). +#[derive(Debug, Deserialize, Default)] +pub struct FormattedTextTree { + /// Root node content + #[serde(flatten)] + text: FormattedText, + /// List of child trees + #[serde(default)] + extra: VecDeque, +} + +impl From for FormattedTextTree { + fn from(value: String) -> Self { + FormattedTextTree { + text: FormattedText { + text: value, + ..Default::default() + }, + extra: VecDeque::new(), + } + } +} + +/// List of [FormattedText] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] +pub struct FormattedTextList(pub Vec); + +impl FormattedTextList { + /// Returns `true` when [FormattedTextList] does not contain any text + pub fn is_empty(&self) -> bool { + self.0.iter().all(|text| text.text.is_empty()) + } +} + +impl Display for FormattedTextList { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for text in &self.0 { + text.fmt(f)?; + } + + Ok(()) + } +} + +/// Raw deserialized [JSONText] +/// +/// A [JSONText] can contain various different JSON types. +#[derive(Debug, Deserialize)] +#[serde(untagged)] +pub enum DeserializedText { + /// Unformatted string + String(String), + /// Unformatted number (will be converted to a string) + Number(f32), + /// Unformatted boolean (will be converted to a string) + Boolean(bool), + /// List of [DeserializedText] + /// + /// The tail elements are appended as children of the head element. + List(VecDeque), + /// The canonical [FormattedTextTree] structure + Object(FormattedTextTree), +} + +impl DeserializedText { + /// Converts a [DeserializedText] into the regular [FormattedTextTree] format + /// + /// Most variants are simply converted to strings. A list is handled by + /// appending all tail elements to the `extra` field of the head. + pub fn canonicalize(self) -> FormattedTextTree { + match self { + DeserializedText::Object(obj) => obj, + DeserializedText::String(s) => FormattedTextTree::from(s), + DeserializedText::Number(n) => FormattedTextTree::from(n.to_string()), + DeserializedText::Boolean(b) => FormattedTextTree::from(b.to_string()), + DeserializedText::List(mut list) => { + let mut obj = list + .pop_front() + .map(|t| t.canonicalize()) + .unwrap_or_default(); + obj.extra.append(&mut list); + obj + } + } + } + + /// Converts the tree of [FormattedText] nodes into a linear list by + /// copying formatting flags into each node. + pub fn linearize(self, parent: &FormattedText) -> FormattedTextList { + let obj = self.canonicalize(); + let mut ret = vec![obj.text.inherit(parent)]; + + for extra in obj.extra { + ret.append(&mut extra.linearize(&ret[0]).0); + } + + FormattedTextList(ret) + } +} + +impl Default for DeserializedText { + fn default() -> Self { + DeserializedText::Object(FormattedTextTree::from(String::new())) + } +} + +/// Minecraft Raw JSON Text +#[derive(Debug, Deserialize)] +pub struct JSONText(pub String); + +impl JSONText { + /// Deserializes a [JSONText] into a [DeserializedText] + pub fn deserialize(&self) -> DeserializedText { + serde_json::from_str(&self.0).unwrap_or_default() + } +} diff --git a/src/world/layer.rs b/src/world/layer.rs index ce88107..576dfa4 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; use super::chunk::{Chunk, SectionIterItem}; use crate::{ - resource::{Biome, BlockFlag, BlockType}, + resource::{Biome, BlockColor, BlockFlag}, types::*, }; @@ -31,8 +31,8 @@ impl BlockHeight { } } -/// Array optionally storing a [BlockType] for each coordinate of a chunk -pub type BlockArray = LayerBlockArray>; +/// Array optionally storing a [BlockColor] for each coordinate of a chunk +pub type BlockArray = LayerBlockArray>; /// Array optionally storing a biome index for each coordinate of a chunk /// @@ -49,7 +49,7 @@ pub type DepthArray = LayerBlockArray>; /// References to LayerData entries for a single coordinate pair struct LayerEntry<'a> { /// The block type of the referenced entry - block: &'a mut Option, + block: &'a mut Option, /// The biome type of the referenced entry biome: &'a mut Option, /// The block light of the referenced entry @@ -86,7 +86,7 @@ impl<'a> LayerEntry<'a> { let Some(block_type) = section .section .block_at(coords)? - .filter(|block_type| block_type.is(BlockFlag::Opaque)) + .filter(|block_type| block_type.block_color.is(BlockFlag::Opaque)) else { if self.is_empty() { *self.block_light = section.block_light.block_light_at(coords); @@ -96,7 +96,7 @@ impl<'a> LayerEntry<'a> { }; if self.is_empty() { - *self.block = Some(block_type); + *self.block = Some(block_type.block_color); if let Some(biome) = section.biomes.biome_at(section.y, coords)? { let (biome_index, _) = biome_list.insert_full(*biome); *self.biome = NonZeroU16::new( @@ -107,7 +107,7 @@ impl<'a> LayerEntry<'a> { } } - if block_type.is(BlockFlag::Water) { + if block_type.block_color.is(BlockFlag::Water) { return Ok(false); } diff --git a/src/world/mod.rs b/src/world/mod.rs index 57aa7ed..6426c92 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -1,6 +1,9 @@ //! Data structures describing Minecraft save data +pub mod block_entity; pub mod chunk; pub mod de; +pub mod json_text; pub mod layer; pub mod section; +pub mod sign; diff --git a/src/world/section.rs b/src/world/section.rs index 97e0061..62b510b 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -44,7 +44,7 @@ fn palette_bits(len: usize, min: u8, max: u8) -> Option { /// Trait for common functions of [SectionV1_13] and [SectionV0] pub trait Section: Debug { /// Returns the [BlockType] at a coordinate tuple inside the section - fn block_at(&self, coords: SectionBlockCoords) -> Result>; + fn block_at(&self, coords: SectionBlockCoords) -> Result>; } /// Minecraft v1.13+ section block data @@ -53,7 +53,7 @@ pub struct SectionV1_13<'a> { /// Packed block type data block_states: Option<&'a [i64]>, /// List of block types indexed by entries encoded in *block_states* - palette: Vec>, + palette: Vec>, /// Number of bits per block in *block_states* bits: u8, /// Set to true if packed block entries in *block_states* are aligned to i64 @@ -146,7 +146,7 @@ impl<'a> SectionV1_13<'a> { } impl<'a> Section for SectionV1_13<'a> { - fn block_at(&self, coords: SectionBlockCoords) -> Result> { + fn block_at(&self, coords: SectionBlockCoords) -> Result> { let index = self.palette_index_at(coords); Ok(*self .palette @@ -189,7 +189,7 @@ impl<'a> SectionV0<'a> { } impl<'a> Section for SectionV0<'a> { - fn block_at(&self, coords: SectionBlockCoords) -> Result> { + fn block_at(&self, coords: SectionBlockCoords) -> Result> { let offset = coords.offset(); let block = self.blocks[offset] as u8; diff --git a/src/world/sign.rs b/src/world/sign.rs new file mode 100644 index 0000000..616f7fa --- /dev/null +++ b/src/world/sign.rs @@ -0,0 +1,132 @@ +//! Processing of sign text + +use std::{fmt::Display, sync::Arc}; + +use serde::{Deserialize, Serialize}; + +use super::{ + de, + json_text::{FormattedText, FormattedTextList, JSONText}, +}; + +/// Version-independent reference to (front or back) sign text +#[derive(Debug, Default)] +pub struct RawSignText<'a> { + /// Lines of sign text + /// + /// A regular sign always has 4 lines of text. The back of pre-1.20 + /// signs is represented as a [SignText] without any `messages`. + pub messages: Vec<&'a JSONText>, + /// Sign color + /// + /// Defaults to "black". + pub color: Option<&'a str>, +} + +impl<'a> RawSignText<'a> { + /// Decodes the [RawSignText] into a [SignText] + pub fn decode(&self) -> SignText { + let color = self.color.map(|c| Arc::new(c.to_owned())); + let parent = FormattedText { + color, + ..Default::default() + }; + SignText( + self.messages + .iter() + .map(|message| message.deserialize().linearize(&parent)) + .collect(), + ) + } +} + +impl<'a> From<&'a de::BlockEntitySignV1_20Text> for RawSignText<'a> { + fn from(value: &'a de::BlockEntitySignV1_20Text) -> Self { + RawSignText { + messages: value.messages.iter().collect(), + color: value.color.as_deref(), + } + } +} + +/// Helper methods for [de::BlockEntitySign] +pub trait BlockEntitySignExt { + /// Returns the front and back text of a sign in a version-indepentent format + fn text(&self) -> (RawSignText, RawSignText); +} + +impl BlockEntitySignExt for de::BlockEntitySign { + fn text(&self) -> (RawSignText, RawSignText) { + match self { + de::BlockEntitySign::V0 { + text1, + text2, + text3, + text4, + color, + } => ( + RawSignText { + messages: vec![text1, text2, text3, text4], + color: color.as_deref(), + }, + Default::default(), + ), + de::BlockEntitySign::V1_20 { + front_text, + back_text, + } => (front_text.into(), back_text.into()), + } + } +} + +#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] +/// Deserialized and linearized sign text +pub struct SignText(pub Vec); + +impl SignText { + /// Checks if all lines of the sign text are empty + pub fn is_empty(&self) -> bool { + self.0.iter().all(|line| line.is_empty()) + } +} + +impl Display for SignText { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut iter = self.0.iter(); + + let Some(first) = iter.next() else { + return Ok(()); + }; + first.fmt(f)?; + + for text in iter { + f.write_str("\n")?; + text.fmt(f)?; + } + + Ok(()) + } +} + +#[cfg(test)] +mod test { + use super::*; + + fn formatted_text(text: &str) -> FormattedText { + FormattedText { + text: text.to_string(), + ..Default::default() + } + } + + #[test] + fn test_sign_text_display() { + let sign_text = SignText(vec![ + FormattedTextList(vec![formatted_text("a"), formatted_text("b")]), + FormattedTextList(vec![formatted_text("c")]), + FormattedTextList(vec![formatted_text("d")]), + FormattedTextList(vec![formatted_text("e")]), + ]); + assert_eq!("ab\nc\nd\ne", sign_text.to_string()); + } +} diff --git a/viewer/MinedMap.js b/viewer/MinedMap.js index 1288dc9..e784eec 100644 --- a/viewer/MinedMap.js +++ b/viewer/MinedMap.js @@ -17,6 +17,61 @@ function contains(array, elem) { return false; } +const signKinds = { + sign: { + iconSize: [26, 28], + popupAnchor: [0, -20], + }, + wall_sign: { + iconSize: [26, 18], + popupAnchor: [0, -15], + }, + hanging_sign: { + iconSize: [28, 24], + popupAnchor: [0, -18], + }, + hanging_wall_sign: { + iconSize: [28, 28], + popupAnchor: [0, -20], + }, +} + +const params = {}; +const signIcons = {}; +const markers = {}; + +let updateHash = () => {}; + +function coordKey(coords) { + if (!coords) + return null; + + return `${coords[0]},${coords[1]}`; +} + +function getMarker(coords) { + return markers[coordKey(coords)]; +} + +function signIcon(material, kind) { + function createSignIcon(material, kind) { + const {iconSize, popupAnchor} = signKinds[kind]; + + return L.icon({ + iconUrl: `images/icon/${material}_${kind}.png`, + iconSize, + popupAnchor, + shadowUrl: `images/icon/shadow_${kind}.png`, + shadowSize: [iconSize[0]+8, iconSize[1]+8], + className: 'overzoomed', + }); + } + + + let icons = signIcons[material] ??= {}; + return icons[kind] ??= createSignIcon(material, kind); +} + const MinedMapLayer = L.TileLayer.extend({ initialize: function (mipmaps, layer) { L.TileLayer.prototype.initialize.call(this, '', { @@ -98,39 +153,230 @@ const parseHash = function () { return args; } +const colors = { + black: '#000000', + dark_blue: '#0000AA', + dark_green: '#00AA00', + dark_aqua: '#00AAAA', + dark_red: '#AA0000', + dark_purple: '#AA00AA', + gold: '#FFAA00', + gray: '#AAAAAA', + dark_gray: '#555555', + blue: '#5555FF', + green: '#55FF55', + aqua: '#55FFFF', + red: '#FF5555', + light_purple: '#FF55FF', + yellow: '#FFFF55', + white: '#FFFFFF', +}; + +function formatSignLine(line) { + const el = document.createElement('span'); + el.style.whiteSpace = 'pre'; + + for (const span of line) { + const child = document.createElement('span'); + child.textContent = span.text; + + const color = colors[span.color ?? 'black'] || colors['black']; + + if (span.bold) + child.style.fontWeight = 'bold'; + if (span.italic) + child.style.fontStyle = 'italic'; + + child.style.textDecoration = ''; + if (span.underlined) + child.style.textDecoration += ' underline'; + if (span.strikethrough) + child.style.textDecoration += ' line-through'; + + child.style.color = color; + if (span.obfuscated) { + child.style.backgroundColor = color; + child.className = 'obfuscated'; + } + + el.appendChild(child); + } + return el; +} + +function createSign(sign, back) { + // standing signs + function px(base) { + const scale = 11; + return (base*scale)+'px'; + } + // hanging signs + function pxh(base) { + const scale = 16; + return (base*scale)+'px'; + } + + const sizes = { + sign: { + width: px(24), + height: px(12), + paddingTop: px(0), + paddingBottom: px(14), + }, + wall_sign: { + width: px(24), + height: px(12), + paddingTop: px(0), + paddingBottom: px(0), + }, + hanging_sign: { + width: pxh(16), + height: pxh(10), + paddingTop: pxh(4), + paddingBottom: pxh(0), + }, + hanging_wall_sign: { + width: pxh(16), + height: pxh(10), + paddingTop: pxh(6), + paddingBottom: pxh(0), + }, + }; + const size = sizes[sign.kind]; + + const wrapper = document.createElement('div'); + wrapper.classList = 'sign-wrapper'; + + const title = document.createElement('div'); + title.classList = 'sign-title' + title.textContent = `Sign at ${sign.x}/${sign.y}/${sign.z}`; + if (back) + title.textContent += ' (back)'; + title.textContent += ':'; + + wrapper.appendChild(title); + + const container = document.createElement('div'); + container.style.width = size.width; + container.style.height = size.height; + container.style.paddingTop = size.paddingTop; + container.style.paddingBottom = size.paddingBottom; + container.style.backgroundImage = `url(images/bg/${sign.material}_${sign.kind}.png)`; + container.classList = 'sign-container overzoomed'; + + const content = document.createElement('div'); + content.classList = 'sign-content'; + + let text = []; + if (!back && sign.front_text) + text = sign.front_text; + else if (back && sign.back_text) + text = sign.back_text; + + for (const line of text) { + content.appendChild(formatSignLine(line)); + content.appendChild(document.createElement('br')); + } + + container.appendChild(content); + wrapper.appendChild(container); + + return wrapper; +} + +async function loadSigns(signLayer) { + const response = await fetch('data/entities.json', {cache: 'no-store'}); + const res = await response.json(); + + const groups = {}; + + // Group signs by x,z coordinates + for (const sign of res.signs) { + const key = coordKey([sign.x, sign.z]); + const group = groups[key] ??= []; + group.push(sign); + } + + for (const [key, group] of Object.entries(groups)) { + const el = document.createElement('div'); + + let material; + let kind; + + // Sort from top to bottom + group.sort((a, b) => b.y - a.y); + + for (const sign of group) { + el.appendChild(createSign(sign, false)); + + if (sign.back_text) + el.appendChild(createSign(sign, true)); + + material ??= sign.material; + kind ??= sign.kind; + } + + // Default material + material ??= 'oak'; + + const [x, z] = key.split(',').map((i) => +i); + + const popup = L.popup().setContent(el); + + popup.on('add', () => { + params.marker = [x, z]; + updateHash(); + }); + popup.on('remove', () => { + params.marker = null; + updateHash(); + }); + + const marker = L.marker([-z-0.5, x+0.5], { + icon: signIcon(material, kind), + }).addTo(signLayer).bindPopup(popup); + + markers[coordKey([x, z])] = marker; + + if (params.marker && x === params.marker[0] && z === params.marker[1]) + marker.openPopup(); + } +} window.createMap = function () { - const xhr = new XMLHttpRequest(); - xhr.onload = function () { - const res = JSON.parse(this.responseText), - mipmaps = res.mipmaps, - spawn = res.spawn; - - let x, z, zoom, light; + (async function () { + const response = await fetch('data/info.json', {cache: 'no-store'}); + const res = await response.json(); + const {mipmaps, spawn} = res; + const features = res.features || {}; const updateParams = function () { const args = parseHash(); - zoom = parseInt(args['zoom']); - x = parseFloat(args['x']); - z = parseFloat(args['z']); - light = parseInt(args['light']); + params.zoom = parseInt(args['zoom']); + params.x = parseFloat(args['x']); + params.z = parseFloat(args['z']); + params.light = parseInt(args['light']); + params.signs = parseInt(args['signs'] ?? '1'); + params.marker = (args['marker'] ?? '').split(',').map((i) => +i); - if (isNaN(zoom)) - zoom = 0; - if (isNaN(x)) - x = spawn.x; - if (isNaN(z)) - z = spawn.z; + if (isNaN(params.zoom)) + params.zoom = 0; + if (isNaN(params.x)) + params.x = spawn.x; + if (isNaN(params.z)) + params.z = spawn.z; + if (!features.signs || isNaN(params.marker[0]) || isNaN(params.marker[1])) + params.marker = null; }; updateParams(); const map = L.map('map', { - center: [-z, x], - zoom: zoom, + center: [-params.z, params.x], + zoom: params.zoom, minZoom: -(mipmaps.length-1), - maxZoom: 3, + maxZoom: 5, crs: L.CRS.Simple, maxBounds: [ [-512*(mipmaps[0].bounds.maxZ+1), 512*mipmaps[0].bounds.minX], @@ -138,17 +384,25 @@ window.createMap = function () { ], }); - const mapLayer = new MinedMapLayer(mipmaps, 'map'); - const lightLayer = new MinedMapLayer(mipmaps, 'light'); + const overlayMaps = {}; + const mapLayer = new MinedMapLayer(mipmaps, 'map'); mapLayer.addTo(map); - if (light) + const lightLayer = new MinedMapLayer(mipmaps, 'light'); + overlayMaps['Illumination'] = lightLayer; + if (params.light) map.addLayer(lightLayer); - const overlayMaps = { - "Illumination": lightLayer, - }; + let signLayer; + if (features.signs) { + signLayer = L.layerGroup(); + loadSigns(signLayer); + if (params.signs) + map.addLayer(signLayer); + + overlayMaps['Signs'] = signLayer; + } L.control.layers({}, overlayMaps).addTo(map); @@ -160,26 +414,37 @@ window.createMap = function () { }); const makeHash = function () { - let ret = '#x='+x+'&z='+z; + let ret = '#x='+params.x+'&z='+params.z; - if (zoom != 0) - ret += '&zoom='+zoom; + if (params.zoom != 0) + ret += '&zoom='+params.zoom; if (map.hasLayer(lightLayer)) ret += '&light=1'; + if (features.signs && !map.hasLayer(signLayer)) + ret += '&signs=0'; + if (params.marker) { + ret += `&marker=${params.marker[0]},${params.marker[1]}`; + } return ret; }; - const updateHash = function () { + updateHash = function () { window.location.hash = makeHash(); }; - const refreshHash = function () { - zoom = map.getZoom(); - center = map.getCenter(); - x = Math.round(center.lng); - z = Math.round(-center.lat); + const refreshHash = function (ev) { + if (ev.type === 'layeradd' || ev.type === 'layerremove') { + if (ev.layer !== lightLayer && ev.layer !== signLayer) + return; + } + + const center = map.getCenter(); + + params.zoom = map.getZoom(); + params.x = Math.round(center.lng); + params.z = Math.round(-center.lat); updateHash(); } @@ -195,20 +460,29 @@ window.createMap = function () { if (window.location.hash === makeHash()) return; + const prevMarkerCoords = params.marker; + updateParams(); - map.setView([-z, x], zoom); - - if (light) + if (params.light) map.addLayer(lightLayer); else map.removeLayer(lightLayer); + if (features.signs) { + if (params.signs) + map.addLayer(signLayer); + else + map.removeLayer(signLayer); + + if (coordKey(prevMarkerCoords) !== coordKey(params.marker)) + getMarker(params.marker)?.openPopup(); + } + + map.setView([-params.z, params.x], params.zoom); + updateHash(); }; - }; - - xhr.open('GET', 'data/info.json', true); - xhr.send(); + })(); } diff --git a/viewer/images/README.md b/viewer/images/README.md new file mode 100644 index 0000000..2e840f1 --- /dev/null +++ b/viewer/images/README.md @@ -0,0 +1,7 @@ +# README + +The images in this directory are assets directly taken from Minecraft, or are derived from Minecraft +assets. They are copyrighted by Mojang/Microsoft, and are used in accordance with the +[Minecraft Usage Guidelines](https://www.minecraft.net/en-us/usage-guidelines). + + diff --git a/viewer/images/bg/acacia_hanging_sign.png b/viewer/images/bg/acacia_hanging_sign.png new file mode 100644 index 0000000..33e3191 Binary files /dev/null and b/viewer/images/bg/acacia_hanging_sign.png differ diff --git a/viewer/images/bg/acacia_hanging_wall_sign.png b/viewer/images/bg/acacia_hanging_wall_sign.png new file mode 100644 index 0000000..c975fc3 Binary files /dev/null and b/viewer/images/bg/acacia_hanging_wall_sign.png differ diff --git a/viewer/images/bg/acacia_sign.png b/viewer/images/bg/acacia_sign.png new file mode 100644 index 0000000..ccc6e47 Binary files /dev/null and b/viewer/images/bg/acacia_sign.png differ diff --git a/viewer/images/bg/acacia_wall_sign.png b/viewer/images/bg/acacia_wall_sign.png new file mode 100644 index 0000000..f7ec621 Binary files /dev/null and b/viewer/images/bg/acacia_wall_sign.png differ diff --git a/viewer/images/bg/bamboo_hanging_sign.png b/viewer/images/bg/bamboo_hanging_sign.png new file mode 100644 index 0000000..5a66129 Binary files /dev/null and b/viewer/images/bg/bamboo_hanging_sign.png differ diff --git a/viewer/images/bg/bamboo_hanging_wall_sign.png b/viewer/images/bg/bamboo_hanging_wall_sign.png new file mode 100644 index 0000000..325e4f0 Binary files /dev/null and b/viewer/images/bg/bamboo_hanging_wall_sign.png differ diff --git a/viewer/images/bg/bamboo_sign.png b/viewer/images/bg/bamboo_sign.png new file mode 100644 index 0000000..dc19aef Binary files /dev/null and b/viewer/images/bg/bamboo_sign.png differ diff --git a/viewer/images/bg/bamboo_wall_sign.png b/viewer/images/bg/bamboo_wall_sign.png new file mode 100644 index 0000000..8182862 Binary files /dev/null and b/viewer/images/bg/bamboo_wall_sign.png differ diff --git a/viewer/images/bg/birch_hanging_sign.png b/viewer/images/bg/birch_hanging_sign.png new file mode 100644 index 0000000..4b4972c Binary files /dev/null and b/viewer/images/bg/birch_hanging_sign.png differ diff --git a/viewer/images/bg/birch_hanging_wall_sign.png b/viewer/images/bg/birch_hanging_wall_sign.png new file mode 100644 index 0000000..b744d54 Binary files /dev/null and b/viewer/images/bg/birch_hanging_wall_sign.png differ diff --git a/viewer/images/bg/birch_sign.png b/viewer/images/bg/birch_sign.png new file mode 100644 index 0000000..0d76b7a Binary files /dev/null and b/viewer/images/bg/birch_sign.png differ diff --git a/viewer/images/bg/birch_wall_sign.png b/viewer/images/bg/birch_wall_sign.png new file mode 100644 index 0000000..c83d292 Binary files /dev/null and b/viewer/images/bg/birch_wall_sign.png differ diff --git a/viewer/images/bg/cherry_hanging_sign.png b/viewer/images/bg/cherry_hanging_sign.png new file mode 100644 index 0000000..2d6cf71 Binary files /dev/null and b/viewer/images/bg/cherry_hanging_sign.png differ diff --git a/viewer/images/bg/cherry_hanging_wall_sign.png b/viewer/images/bg/cherry_hanging_wall_sign.png new file mode 100644 index 0000000..a7325f3 Binary files /dev/null and b/viewer/images/bg/cherry_hanging_wall_sign.png differ diff --git a/viewer/images/bg/cherry_sign.png b/viewer/images/bg/cherry_sign.png new file mode 100644 index 0000000..91b1949 Binary files /dev/null and b/viewer/images/bg/cherry_sign.png differ diff --git a/viewer/images/bg/cherry_wall_sign.png b/viewer/images/bg/cherry_wall_sign.png new file mode 100644 index 0000000..48d9511 Binary files /dev/null and b/viewer/images/bg/cherry_wall_sign.png differ diff --git a/viewer/images/bg/crimson_hanging_sign.png b/viewer/images/bg/crimson_hanging_sign.png new file mode 100644 index 0000000..aa3dabe Binary files /dev/null and b/viewer/images/bg/crimson_hanging_sign.png differ diff --git a/viewer/images/bg/crimson_hanging_wall_sign.png b/viewer/images/bg/crimson_hanging_wall_sign.png new file mode 100644 index 0000000..35a7892 Binary files /dev/null and b/viewer/images/bg/crimson_hanging_wall_sign.png differ diff --git a/viewer/images/bg/crimson_sign.png b/viewer/images/bg/crimson_sign.png new file mode 100644 index 0000000..08e2322 Binary files /dev/null and b/viewer/images/bg/crimson_sign.png differ diff --git a/viewer/images/bg/crimson_wall_sign.png b/viewer/images/bg/crimson_wall_sign.png new file mode 100644 index 0000000..ce47274 Binary files /dev/null and b/viewer/images/bg/crimson_wall_sign.png differ diff --git a/viewer/images/bg/dark_oak_hanging_sign.png b/viewer/images/bg/dark_oak_hanging_sign.png new file mode 100644 index 0000000..7155078 Binary files /dev/null and b/viewer/images/bg/dark_oak_hanging_sign.png differ diff --git a/viewer/images/bg/dark_oak_hanging_wall_sign.png b/viewer/images/bg/dark_oak_hanging_wall_sign.png new file mode 100644 index 0000000..73479e8 Binary files /dev/null and b/viewer/images/bg/dark_oak_hanging_wall_sign.png differ diff --git a/viewer/images/bg/dark_oak_sign.png b/viewer/images/bg/dark_oak_sign.png new file mode 100644 index 0000000..8b1307d Binary files /dev/null and b/viewer/images/bg/dark_oak_sign.png differ diff --git a/viewer/images/bg/dark_oak_wall_sign.png b/viewer/images/bg/dark_oak_wall_sign.png new file mode 100644 index 0000000..a163f04 Binary files /dev/null and b/viewer/images/bg/dark_oak_wall_sign.png differ diff --git a/viewer/images/bg/jungle_hanging_sign.png b/viewer/images/bg/jungle_hanging_sign.png new file mode 100644 index 0000000..ecf1e87 Binary files /dev/null and b/viewer/images/bg/jungle_hanging_sign.png differ diff --git a/viewer/images/bg/jungle_hanging_wall_sign.png b/viewer/images/bg/jungle_hanging_wall_sign.png new file mode 100644 index 0000000..5cf2b40 Binary files /dev/null and b/viewer/images/bg/jungle_hanging_wall_sign.png differ diff --git a/viewer/images/bg/jungle_sign.png b/viewer/images/bg/jungle_sign.png new file mode 100644 index 0000000..eb7d54d Binary files /dev/null and b/viewer/images/bg/jungle_sign.png differ diff --git a/viewer/images/bg/jungle_wall_sign.png b/viewer/images/bg/jungle_wall_sign.png new file mode 100644 index 0000000..6eb610b Binary files /dev/null and b/viewer/images/bg/jungle_wall_sign.png differ diff --git a/viewer/images/bg/mangrove_hanging_sign.png b/viewer/images/bg/mangrove_hanging_sign.png new file mode 100644 index 0000000..7e36396 Binary files /dev/null and b/viewer/images/bg/mangrove_hanging_sign.png differ diff --git a/viewer/images/bg/mangrove_hanging_wall_sign.png b/viewer/images/bg/mangrove_hanging_wall_sign.png new file mode 100644 index 0000000..4fd9948 Binary files /dev/null and b/viewer/images/bg/mangrove_hanging_wall_sign.png differ diff --git a/viewer/images/bg/mangrove_sign.png b/viewer/images/bg/mangrove_sign.png new file mode 100644 index 0000000..d03bfd0 Binary files /dev/null and b/viewer/images/bg/mangrove_sign.png differ diff --git a/viewer/images/bg/mangrove_wall_sign.png b/viewer/images/bg/mangrove_wall_sign.png new file mode 100644 index 0000000..8fe527a Binary files /dev/null and b/viewer/images/bg/mangrove_wall_sign.png differ diff --git a/viewer/images/bg/oak_hanging_sign.png b/viewer/images/bg/oak_hanging_sign.png new file mode 100644 index 0000000..fea3a3f Binary files /dev/null and b/viewer/images/bg/oak_hanging_sign.png differ diff --git a/viewer/images/bg/oak_hanging_wall_sign.png b/viewer/images/bg/oak_hanging_wall_sign.png new file mode 100644 index 0000000..9212d07 Binary files /dev/null and b/viewer/images/bg/oak_hanging_wall_sign.png differ diff --git a/viewer/images/bg/oak_sign.png b/viewer/images/bg/oak_sign.png new file mode 100644 index 0000000..fca0a80 Binary files /dev/null and b/viewer/images/bg/oak_sign.png differ diff --git a/viewer/images/bg/oak_wall_sign.png b/viewer/images/bg/oak_wall_sign.png new file mode 100644 index 0000000..b6f9879 Binary files /dev/null and b/viewer/images/bg/oak_wall_sign.png differ diff --git a/viewer/images/bg/spruce_hanging_sign.png b/viewer/images/bg/spruce_hanging_sign.png new file mode 100644 index 0000000..295a2de Binary files /dev/null and b/viewer/images/bg/spruce_hanging_sign.png differ diff --git a/viewer/images/bg/spruce_hanging_wall_sign.png b/viewer/images/bg/spruce_hanging_wall_sign.png new file mode 100644 index 0000000..87a62f9 Binary files /dev/null and b/viewer/images/bg/spruce_hanging_wall_sign.png differ diff --git a/viewer/images/bg/spruce_sign.png b/viewer/images/bg/spruce_sign.png new file mode 100644 index 0000000..cc5cbab Binary files /dev/null and b/viewer/images/bg/spruce_sign.png differ diff --git a/viewer/images/bg/spruce_wall_sign.png b/viewer/images/bg/spruce_wall_sign.png new file mode 100644 index 0000000..f8730b9 Binary files /dev/null and b/viewer/images/bg/spruce_wall_sign.png differ diff --git a/viewer/images/bg/warped_hanging_sign.png b/viewer/images/bg/warped_hanging_sign.png new file mode 100644 index 0000000..100e0fc Binary files /dev/null and b/viewer/images/bg/warped_hanging_sign.png differ diff --git a/viewer/images/bg/warped_hanging_wall_sign.png b/viewer/images/bg/warped_hanging_wall_sign.png new file mode 100644 index 0000000..a80b913 Binary files /dev/null and b/viewer/images/bg/warped_hanging_wall_sign.png differ diff --git a/viewer/images/bg/warped_sign.png b/viewer/images/bg/warped_sign.png new file mode 100644 index 0000000..8fdc181 Binary files /dev/null and b/viewer/images/bg/warped_sign.png differ diff --git a/viewer/images/bg/warped_wall_sign.png b/viewer/images/bg/warped_wall_sign.png new file mode 100644 index 0000000..86a7cab Binary files /dev/null and b/viewer/images/bg/warped_wall_sign.png differ diff --git a/viewer/images/icon/acacia_hanging_sign.png b/viewer/images/icon/acacia_hanging_sign.png new file mode 100644 index 0000000..79c8ee5 Binary files /dev/null and b/viewer/images/icon/acacia_hanging_sign.png differ diff --git a/viewer/images/icon/acacia_hanging_wall_sign.png b/viewer/images/icon/acacia_hanging_wall_sign.png new file mode 100644 index 0000000..b8872cb Binary files /dev/null and b/viewer/images/icon/acacia_hanging_wall_sign.png differ diff --git a/viewer/images/icon/acacia_sign.png b/viewer/images/icon/acacia_sign.png new file mode 100644 index 0000000..c698b7d Binary files /dev/null and b/viewer/images/icon/acacia_sign.png differ diff --git a/viewer/images/icon/acacia_wall_sign.png b/viewer/images/icon/acacia_wall_sign.png new file mode 100644 index 0000000..83de3ac Binary files /dev/null and b/viewer/images/icon/acacia_wall_sign.png differ diff --git a/viewer/images/icon/bamboo_hanging_sign.png b/viewer/images/icon/bamboo_hanging_sign.png new file mode 100644 index 0000000..8acef55 Binary files /dev/null and b/viewer/images/icon/bamboo_hanging_sign.png differ diff --git a/viewer/images/icon/bamboo_hanging_wall_sign.png b/viewer/images/icon/bamboo_hanging_wall_sign.png new file mode 100644 index 0000000..a23377e Binary files /dev/null and b/viewer/images/icon/bamboo_hanging_wall_sign.png differ diff --git a/viewer/images/icon/bamboo_sign.png b/viewer/images/icon/bamboo_sign.png new file mode 100644 index 0000000..d8702d1 Binary files /dev/null and b/viewer/images/icon/bamboo_sign.png differ diff --git a/viewer/images/icon/bamboo_wall_sign.png b/viewer/images/icon/bamboo_wall_sign.png new file mode 100644 index 0000000..9af0ac2 Binary files /dev/null and b/viewer/images/icon/bamboo_wall_sign.png differ diff --git a/viewer/images/icon/birch_hanging_sign.png b/viewer/images/icon/birch_hanging_sign.png new file mode 100644 index 0000000..79adc54 Binary files /dev/null and b/viewer/images/icon/birch_hanging_sign.png differ diff --git a/viewer/images/icon/birch_hanging_wall_sign.png b/viewer/images/icon/birch_hanging_wall_sign.png new file mode 100644 index 0000000..85f9c2e Binary files /dev/null and b/viewer/images/icon/birch_hanging_wall_sign.png differ diff --git a/viewer/images/icon/birch_sign.png b/viewer/images/icon/birch_sign.png new file mode 100644 index 0000000..f05a4b4 Binary files /dev/null and b/viewer/images/icon/birch_sign.png differ diff --git a/viewer/images/icon/birch_wall_sign.png b/viewer/images/icon/birch_wall_sign.png new file mode 100644 index 0000000..b82e681 Binary files /dev/null and b/viewer/images/icon/birch_wall_sign.png differ diff --git a/viewer/images/icon/cherry_hanging_sign.png b/viewer/images/icon/cherry_hanging_sign.png new file mode 100644 index 0000000..2ea0a3f Binary files /dev/null and b/viewer/images/icon/cherry_hanging_sign.png differ diff --git a/viewer/images/icon/cherry_hanging_wall_sign.png b/viewer/images/icon/cherry_hanging_wall_sign.png new file mode 100644 index 0000000..d14b399 Binary files /dev/null and b/viewer/images/icon/cherry_hanging_wall_sign.png differ diff --git a/viewer/images/icon/cherry_sign.png b/viewer/images/icon/cherry_sign.png new file mode 100644 index 0000000..d9c7f49 Binary files /dev/null and b/viewer/images/icon/cherry_sign.png differ diff --git a/viewer/images/icon/cherry_wall_sign.png b/viewer/images/icon/cherry_wall_sign.png new file mode 100644 index 0000000..8ca0429 Binary files /dev/null and b/viewer/images/icon/cherry_wall_sign.png differ diff --git a/viewer/images/icon/crimson_hanging_sign.png b/viewer/images/icon/crimson_hanging_sign.png new file mode 100644 index 0000000..629b277 Binary files /dev/null and b/viewer/images/icon/crimson_hanging_sign.png differ diff --git a/viewer/images/icon/crimson_hanging_wall_sign.png b/viewer/images/icon/crimson_hanging_wall_sign.png new file mode 100644 index 0000000..9df4aa2 Binary files /dev/null and b/viewer/images/icon/crimson_hanging_wall_sign.png differ diff --git a/viewer/images/icon/crimson_sign.png b/viewer/images/icon/crimson_sign.png new file mode 100644 index 0000000..7cf1ae7 Binary files /dev/null and b/viewer/images/icon/crimson_sign.png differ diff --git a/viewer/images/icon/crimson_wall_sign.png b/viewer/images/icon/crimson_wall_sign.png new file mode 100644 index 0000000..5fc699c Binary files /dev/null and b/viewer/images/icon/crimson_wall_sign.png differ diff --git a/viewer/images/icon/dark_oak_hanging_sign.png b/viewer/images/icon/dark_oak_hanging_sign.png new file mode 100644 index 0000000..a64df06 Binary files /dev/null and b/viewer/images/icon/dark_oak_hanging_sign.png differ diff --git a/viewer/images/icon/dark_oak_hanging_wall_sign.png b/viewer/images/icon/dark_oak_hanging_wall_sign.png new file mode 100644 index 0000000..5ec5d94 Binary files /dev/null and b/viewer/images/icon/dark_oak_hanging_wall_sign.png differ diff --git a/viewer/images/icon/dark_oak_sign.png b/viewer/images/icon/dark_oak_sign.png new file mode 100644 index 0000000..569b97d Binary files /dev/null and b/viewer/images/icon/dark_oak_sign.png differ diff --git a/viewer/images/icon/dark_oak_wall_sign.png b/viewer/images/icon/dark_oak_wall_sign.png new file mode 100644 index 0000000..e9bdeb3 Binary files /dev/null and b/viewer/images/icon/dark_oak_wall_sign.png differ diff --git a/viewer/images/icon/jungle_hanging_sign.png b/viewer/images/icon/jungle_hanging_sign.png new file mode 100644 index 0000000..ec89fff Binary files /dev/null and b/viewer/images/icon/jungle_hanging_sign.png differ diff --git a/viewer/images/icon/jungle_hanging_wall_sign.png b/viewer/images/icon/jungle_hanging_wall_sign.png new file mode 100644 index 0000000..fba8629 Binary files /dev/null and b/viewer/images/icon/jungle_hanging_wall_sign.png differ diff --git a/viewer/images/icon/jungle_sign.png b/viewer/images/icon/jungle_sign.png new file mode 100644 index 0000000..4853e08 Binary files /dev/null and b/viewer/images/icon/jungle_sign.png differ diff --git a/viewer/images/icon/jungle_wall_sign.png b/viewer/images/icon/jungle_wall_sign.png new file mode 100644 index 0000000..c3d72d2 Binary files /dev/null and b/viewer/images/icon/jungle_wall_sign.png differ diff --git a/viewer/images/icon/mangrove_hanging_sign.png b/viewer/images/icon/mangrove_hanging_sign.png new file mode 100644 index 0000000..f53bf22 Binary files /dev/null and b/viewer/images/icon/mangrove_hanging_sign.png differ diff --git a/viewer/images/icon/mangrove_hanging_wall_sign.png b/viewer/images/icon/mangrove_hanging_wall_sign.png new file mode 100644 index 0000000..79a010a Binary files /dev/null and b/viewer/images/icon/mangrove_hanging_wall_sign.png differ diff --git a/viewer/images/icon/mangrove_sign.png b/viewer/images/icon/mangrove_sign.png new file mode 100644 index 0000000..467c922 Binary files /dev/null and b/viewer/images/icon/mangrove_sign.png differ diff --git a/viewer/images/icon/mangrove_wall_sign.png b/viewer/images/icon/mangrove_wall_sign.png new file mode 100644 index 0000000..b1cadce Binary files /dev/null and b/viewer/images/icon/mangrove_wall_sign.png differ diff --git a/viewer/images/icon/oak_hanging_sign.png b/viewer/images/icon/oak_hanging_sign.png new file mode 100644 index 0000000..060c4e2 Binary files /dev/null and b/viewer/images/icon/oak_hanging_sign.png differ diff --git a/viewer/images/icon/oak_hanging_wall_sign.png b/viewer/images/icon/oak_hanging_wall_sign.png new file mode 100644 index 0000000..2bb9dff Binary files /dev/null and b/viewer/images/icon/oak_hanging_wall_sign.png differ diff --git a/viewer/images/icon/oak_sign.png b/viewer/images/icon/oak_sign.png new file mode 100644 index 0000000..41b46a5 Binary files /dev/null and b/viewer/images/icon/oak_sign.png differ diff --git a/viewer/images/icon/oak_wall_sign.png b/viewer/images/icon/oak_wall_sign.png new file mode 100644 index 0000000..bfb9ff7 Binary files /dev/null and b/viewer/images/icon/oak_wall_sign.png differ diff --git a/viewer/images/icon/shadow_hanging_sign.png b/viewer/images/icon/shadow_hanging_sign.png new file mode 100644 index 0000000..dbd19a6 Binary files /dev/null and b/viewer/images/icon/shadow_hanging_sign.png differ diff --git a/viewer/images/icon/shadow_hanging_wall_sign.png b/viewer/images/icon/shadow_hanging_wall_sign.png new file mode 100644 index 0000000..771cef5 Binary files /dev/null and b/viewer/images/icon/shadow_hanging_wall_sign.png differ diff --git a/viewer/images/icon/shadow_sign.png b/viewer/images/icon/shadow_sign.png new file mode 100644 index 0000000..9bf1cde Binary files /dev/null and b/viewer/images/icon/shadow_sign.png differ diff --git a/viewer/images/icon/shadow_wall_sign.png b/viewer/images/icon/shadow_wall_sign.png new file mode 100644 index 0000000..fe46765 Binary files /dev/null and b/viewer/images/icon/shadow_wall_sign.png differ diff --git a/viewer/images/icon/spruce_hanging_sign.png b/viewer/images/icon/spruce_hanging_sign.png new file mode 100644 index 0000000..bf3c6d0 Binary files /dev/null and b/viewer/images/icon/spruce_hanging_sign.png differ diff --git a/viewer/images/icon/spruce_hanging_wall_sign.png b/viewer/images/icon/spruce_hanging_wall_sign.png new file mode 100644 index 0000000..c1c872b Binary files /dev/null and b/viewer/images/icon/spruce_hanging_wall_sign.png differ diff --git a/viewer/images/icon/spruce_sign.png b/viewer/images/icon/spruce_sign.png new file mode 100644 index 0000000..faff405 Binary files /dev/null and b/viewer/images/icon/spruce_sign.png differ diff --git a/viewer/images/icon/spruce_wall_sign.png b/viewer/images/icon/spruce_wall_sign.png new file mode 100644 index 0000000..69a9ad9 Binary files /dev/null and b/viewer/images/icon/spruce_wall_sign.png differ diff --git a/viewer/images/icon/warped_hanging_sign.png b/viewer/images/icon/warped_hanging_sign.png new file mode 100644 index 0000000..80dd99e Binary files /dev/null and b/viewer/images/icon/warped_hanging_sign.png differ diff --git a/viewer/images/icon/warped_hanging_wall_sign.png b/viewer/images/icon/warped_hanging_wall_sign.png new file mode 100644 index 0000000..1519d0b Binary files /dev/null and b/viewer/images/icon/warped_hanging_wall_sign.png differ diff --git a/viewer/images/icon/warped_sign.png b/viewer/images/icon/warped_sign.png new file mode 100644 index 0000000..4c3530b Binary files /dev/null and b/viewer/images/icon/warped_sign.png differ diff --git a/viewer/images/icon/warped_wall_sign.png b/viewer/images/icon/warped_wall_sign.png new file mode 100644 index 0000000..59614c6 Binary files /dev/null and b/viewer/images/icon/warped_wall_sign.png differ diff --git a/viewer/index.html b/viewer/index.html index df57cb6..caf32a0 100644 --- a/viewer/index.html +++ b/viewer/index.html @@ -22,7 +22,19 @@ background: #333; } - img.overzoomed { + .leaflet-container a.leaflet-popup-close-button { + color: #ccc; + } + + .leaflet-container a.leaflet-popup-close-button:hover { + color: #fff; + } + + .leaflet-popup-content-wrapper, .leaflet-popup-tip { + background: rgba(64, 64, 64, 0.5); + } + + .overzoomed { image-rendering: -moz-crisp-edges; image-rendering: -o-crisp-edges; image-rendering: -webkit-optimize-contrast; @@ -30,6 +42,42 @@ image-rendering: pixelated; -ms-interpolation-mode: nearest-neighbor; } + + .sign-wrapper { + padding: 0; + padding-left: 4px; + margin-bottom: 2em; + } + + .sign-wrapper:last-child { + margin-bottom: 0; + } + + .sign-title { + color: #fff; + font-weight: bold; + margin-bottom: 0.5em; + } + + .sign-container { + padding: 0; + background-size: cover; + display: flex; + align-items: center; + justify-content: center; + } + + .sign-content { + padding: 0; + font-size: 18px; + line-height: 1.5; + text-align: center; + font-family: sans; + } + + span.obfuscated:hover { + background-color: transparent !important; + }