aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2023-07-14 22:20:40 -0500
committerGitHub <noreply@github.com>2023-07-14 22:20:40 -0500
commit7405427199e5a994d4a6a706f84434a69cb7a7d9 (patch)
treeca537e5d761bc053187d952fced0915c850b92aa
parentd1afd02aa84e7b4450c1607277f078eb2a0f1bf3 (diff)
downloadazalea-drasl-7405427199e5a994d4a6a706f84434a69cb7a7d9.tar.xz
Mining (#95)
* more mining stuff * initialize azalea-tags crate * more mining stuff 2 * mining in ecs * well technically mining works but no codegen for how long it takes to mine each block yet * rename downloads to __cache__ it was bothering me since it's not *just* downloads * codegen block behavior * fix not sending packet to finish breaking block * mining animation 🎉 * clippy * cleanup, move Client::mine into a client extension * add azalea/src/mining.rs --------- Co-authored-by: mat <git@matdoes.dev>
-rw-r--r--Cargo.lock129
-rwxr-xr-xCargo.toml1
-rwxr-xr-xazalea-block/azalea-block-macros/src/lib.rs35
-rwxr-xr-xazalea-block/src/behavior.rs36
-rwxr-xr-xazalea-block/src/generated.rs2012
-rwxr-xr-xazalea-block/src/lib.rs80
-rwxr-xr-xazalea-buf/src/read.rs15
-rw-r--r--azalea-client/Cargo.toml1
-rwxr-xr-xazalea-client/src/account.rs5
-rw-r--r--azalea-client/src/client.rs28
-rw-r--r--azalea-client/src/entity_query.rs6
-rw-r--r--azalea-client/src/events.rs2
-rw-r--r--azalea-client/src/interact.rs88
-rw-r--r--azalea-client/src/inventory.rs25
-rw-r--r--azalea-client/src/lib.rs2
-rw-r--r--azalea-client/src/local_player.rs10
-rw-r--r--azalea-client/src/mining.rs537
-rw-r--r--azalea-client/src/movement.rs31
-rw-r--r--azalea-client/src/packet_handling.rs41
-rwxr-xr-xazalea-client/src/player.rs2
-rwxr-xr-xazalea-core/src/lib.rs63
-rw-r--r--azalea-core/src/math.rs56
-rwxr-xr-xazalea-core/src/particle.rs (renamed from azalea-core/src/particle/mod.rs)0
-rw-r--r--azalea-core/src/tier.rs46
-rw-r--r--azalea-entity/Cargo.toml25
-rw-r--r--azalea-entity/src/attributes.rs (renamed from azalea-world/src/entity/attributes.rs)0
-rwxr-xr-xazalea-entity/src/data.rs (renamed from azalea-world/src/entity/data.rs)2
-rwxr-xr-xazalea-entity/src/dimensions.rs (renamed from azalea-world/src/entity/dimensions.rs)0
-rw-r--r--azalea-entity/src/effects.rs26
-rw-r--r--azalea-entity/src/enchantments.rs8
-rw-r--r--azalea-entity/src/info.rs (renamed from azalea-world/src/entity/info.rs)58
-rw-r--r--azalea-entity/src/lib.rs (renamed from azalea-world/src/entity/mod.rs)34
-rw-r--r--azalea-entity/src/metadata.rs (renamed from azalea-world/src/entity/metadata.rs)2
-rw-r--r--azalea-entity/src/mining.rs170
-rw-r--r--azalea-entity/src/systems.rs181
-rw-r--r--azalea-inventory/src/lib.rs4
-rw-r--r--azalea-physics/Cargo.toml1
-rw-r--r--azalea-physics/src/clip.rs2
-rwxr-xr-xazalea-physics/src/collision/mergers.rs5
-rw-r--r--azalea-physics/src/collision/mod.rs10
-rwxr-xr-xazalea-physics/src/collision/shape.rs2
-rw-r--r--azalea-physics/src/collision/world_collisions.rs4
-rw-r--r--azalea-physics/src/lib.rs23
-rw-r--r--azalea-protocol/Cargo.toml1
-rwxr-xr-xazalea-protocol/src/packets/game/clientbound_add_entity_packet.rs2
-rwxr-xr-xazalea-protocol/src/packets/game/clientbound_add_player_packet.rs2
-rwxr-xr-xazalea-protocol/src/packets/game/clientbound_level_particles_packet.rs2
-rwxr-xr-xazalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs2
-rwxr-xr-xazalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs2
-rwxr-xr-xazalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs10
-rw-r--r--azalea-registry/Cargo.toml1
-rwxr-xr-xazalea-registry/src/lib.rs2
-rw-r--r--azalea-registry/src/tags/blocks.rs3374
-rw-r--r--azalea-registry/src/tags/fluids.rs12
-rw-r--r--azalea-registry/src/tags/items.rs1379
-rw-r--r--azalea-registry/src/tags/mod.rs3
-rw-r--r--azalea-world/src/container.rs13
-rw-r--r--azalea-world/src/lib.rs1
-rw-r--r--azalea-world/src/world.rs204
-rw-r--r--azalea/Cargo.toml1
-rw-r--r--azalea/examples/testbot.rs21
-rw-r--r--azalea/src/bot.rs5
-rw-r--r--azalea/src/lib.rs4
-rw-r--r--azalea/src/mining.rs40
-rw-r--r--azalea/src/pathfinder/mod.rs12
-rw-r--r--azalea/src/prelude.rs4
-rw-r--r--azalea/src/swarm/events.rs2
-rwxr-xr-xcodegen/.gitignore4
-rwxr-xr-xcodegen/genblocks.py2
-rwxr-xr-xcodegen/genregistries.py26
-rwxr-xr-xcodegen/lib/code/blocks.py24
-rwxr-xr-xcodegen/lib/code/shapes.py2
-rw-r--r--codegen/lib/code/tags.py35
-rwxr-xr-xcodegen/lib/download.py76
-rwxr-xr-xcodegen/lib/extract.py35
-rwxr-xr-xcodegen/migrate.py5
76 files changed, 7518 insertions, 1598 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ec106c39..e3a9ab65 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -87,9 +87,9 @@ checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
[[package]]
name = "async-channel"
-version = "1.8.0"
+version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833"
+checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35"
dependencies = [
"concurrent-queue",
"event-listener",
@@ -98,9 +98,9 @@ dependencies = [
[[package]]
name = "async-compression"
-version = "0.4.0"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b0122885821398cc923ece939e24d1056a2384ee719432397fa9db87230ff11"
+checksum = "62b74f44609f0f91493e3082d3734d98497e094777144380ea4db9f9905dd5b6"
dependencies = [
"flate2",
"futures-core",
@@ -178,6 +178,7 @@ dependencies = [
"azalea-chat",
"azalea-client",
"azalea-core",
+ "azalea-entity",
"azalea-inventory",
"azalea-physics",
"azalea-protocol",
@@ -293,6 +294,7 @@ dependencies = [
"azalea-chat",
"azalea-core",
"azalea-crypto",
+ "azalea-entity",
"azalea-inventory",
"azalea-nbt",
"azalea-physics",
@@ -350,6 +352,29 @@ dependencies = [
]
[[package]]
+name = "azalea-entity"
+version = "0.1.0"
+dependencies = [
+ "azalea-block",
+ "azalea-buf",
+ "azalea-chat",
+ "azalea-core",
+ "azalea-inventory",
+ "azalea-nbt",
+ "azalea-registry",
+ "azalea-world",
+ "bevy_app",
+ "bevy_ecs",
+ "derive_more",
+ "enum-as-inner 0.6.0",
+ "log",
+ "nohash-hasher",
+ "parking_lot",
+ "thiserror",
+ "uuid",
+]
+
+[[package]]
name = "azalea-inventory"
version = "0.7.0"
dependencies = [
@@ -401,6 +426,7 @@ version = "0.7.0"
dependencies = [
"azalea-block",
"azalea-core",
+ "azalea-entity",
"azalea-inventory",
"azalea-registry",
"azalea-world",
@@ -426,6 +452,7 @@ dependencies = [
"azalea-chat",
"azalea-core",
"azalea-crypto",
+ "azalea-entity",
"azalea-inventory",
"azalea-nbt",
"azalea-protocol-macros",
@@ -465,6 +492,7 @@ version = "0.7.0"
dependencies = [
"azalea-buf",
"azalea-registry-macros",
+ "once_cell",
"serde",
]
@@ -933,9 +961,9 @@ dependencies = [
[[package]]
name = "const-oid"
-version = "0.9.2"
+version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913"
+checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747"
[[package]]
name = "convert_case"
@@ -945,9 +973,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
[[package]]
name = "cpufeatures"
-version = "0.2.8"
+version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c"
+checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1"
dependencies = [
"libc",
]
@@ -1058,9 +1086,9 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
[[package]]
name = "der"
-version = "0.7.6"
+version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56acb310e15652100da43d130af8d97b509e95af61aab1c5a7939ef24337ee17"
+checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946"
dependencies = [
"const-oid",
"pem-rfc7468",
@@ -1151,15 +1179,15 @@ dependencies = [
[[package]]
name = "equivalent"
-version = "1.0.0"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1"
+checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "erased-serde"
-version = "0.3.25"
+version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f2b0c2380453a92ea8b6c8e5f64ecaafccddde8ceab55ff7a8ac1029f894569"
+checksum = "f94c0e13118e7d7533271f754a168ae8400e6a1cc043f2bfd53cc7290f1a1de3"
dependencies = [
"serde",
]
@@ -1531,10 +1559,11 @@ dependencies = [
[[package]]
name = "hyper-rustls"
-version = "0.24.0"
+version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7"
+checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97"
dependencies = [
+ "futures-util",
"http",
"hyper",
"rustls",
@@ -1612,9 +1641,9 @@ checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
[[package]]
name = "is-terminal"
-version = "0.4.8"
+version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24fddda5af7e54bf7da53067d6e802dbcc381d0a8eef629df528e3ebf68755cb"
+checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
dependencies = [
"hermit-abi",
"rustix",
@@ -1632,9 +1661,9 @@ dependencies = [
[[package]]
name = "itoa"
-version = "1.0.6"
+version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
+checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a"
[[package]]
name = "js-sys"
@@ -1783,9 +1812,9 @@ dependencies = [
[[package]]
name = "num"
-version = "0.4.0"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606"
+checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af"
dependencies = [
"num-bigint",
"num-complex",
@@ -1808,9 +1837,9 @@ dependencies = [
[[package]]
name = "num-bigint-dig"
-version = "0.8.2"
+version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2399c9463abc5f909349d8aa9ba080e0b88b3ce2885389b60b993f39b1a56905"
+checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151"
dependencies = [
"byteorder",
"lazy_static",
@@ -2153,7 +2182,7 @@ dependencies = [
"aho-corasick",
"memchr",
"regex-automata 0.3.2",
- "regex-syntax 0.7.3",
+ "regex-syntax 0.7.4",
]
[[package]]
@@ -2173,7 +2202,7 @@ checksum = "83d3daa6976cffb758ec878f108ba0e062a45b2d6ca3a2cca965338855476caf"
dependencies = [
"aho-corasick",
"memchr",
- "regex-syntax 0.7.3",
+ "regex-syntax 0.7.4",
]
[[package]]
@@ -2184,9 +2213,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
-version = "0.7.3"
+version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ab07dc67230e4a4718e70fd5c20055a4334b121f1f9db8fe63ef39ce9b8c846"
+checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
[[package]]
name = "reqwest"
@@ -2299,9 +2328,9 @@ dependencies = [
[[package]]
name = "rustix"
-version = "0.38.1"
+version = "0.38.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fbc6396159432b5c8490d4e301d8c705f61860b8b6c863bf79942ce5401968f3"
+checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5"
dependencies = [
"bitflags 2.3.3",
"errno",
@@ -2312,9 +2341,9 @@ dependencies = [
[[package]]
name = "rustls"
-version = "0.21.2"
+version = "0.21.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e32ca28af694bc1bbf399c33a516dbdf1c90090b8ab23c2bc24f834aa2247f5f"
+checksum = "79ea77c539259495ce8ca47f53e66ae0330a8819f67e23ac96ca02f50e7b7d36"
dependencies = [
"log",
"ring",
@@ -2333,9 +2362,9 @@ dependencies = [
[[package]]
name = "rustls-webpki"
-version = "0.100.1"
+version = "0.101.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b"
+checksum = "15f36a6828982f422756984e47912a7a51dcbc2a197aa791158f8ca61cd8204e"
dependencies = [
"ring",
"untrusted",
@@ -2343,15 +2372,15 @@ dependencies = [
[[package]]
name = "rustversion"
-version = "1.0.12"
+version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06"
+checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f"
[[package]]
name = "ryu"
-version = "1.0.13"
+version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
+checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9"
[[package]]
name = "same-file"
@@ -2386,27 +2415,27 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
[[package]]
name = "serde"
-version = "1.0.170"
+version = "1.0.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a56657f512baabca8f840542f9ca8152aecf182c473c26e46e58d6aab4f6e439"
+checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_bytes"
-version = "0.11.10"
+version = "0.11.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3c5113243e4a3a1c96587342d067f3e6b0f50790b6cf40d2868eb647a3eef0e"
+checksum = "5a16be4fe5320ade08736447e3198294a5ea9a6d44dde6f35f0a5e06859c427a"
dependencies = [
"serde",
]
[[package]]
name = "serde_derive"
-version = "1.0.170"
+version = "1.0.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77d477848e6b23adba0db397777d5aad864555bc17fd9c89abb3b8009788b7b8"
+checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682"
dependencies = [
"proc-macro2",
"quote",
@@ -2415,9 +2444,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.100"
+version = "1.0.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c"
+checksum = "b5062a995d481b2308b6064e9af76011f2921c35f97b0468811ed9f6cd91dfed"
dependencies = [
"itoa",
"ryu",
@@ -2723,9 +2752,9 @@ checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
[[package]]
name = "toml_edit"
-version = "0.19.11"
+version = "0.19.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "266f016b7f039eec8a1a80dfe6156b633d208b9fccca5e4db1d6775b0c4e34a7"
+checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78"
dependencies = [
"indexmap 2.0.0",
"toml_datetime",
@@ -3162,9 +3191,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
[[package]]
name = "winnow"
-version = "0.4.7"
+version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448"
+checksum = "81a2094c43cc94775293eaa0e499fbc30048a6d824ac82c0351a8c0bf9112529"
dependencies = [
"memchr",
]
diff --git a/Cargo.toml b/Cargo.toml
index ac961997..c9bbddbb 100755
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -16,6 +16,7 @@ members = [
"azalea-physics",
"azalea-registry",
"azalea-inventory",
+ "azalea-entity",
]
resolver = "2"
diff --git a/azalea-block/azalea-block-macros/src/lib.rs b/azalea-block/azalea-block-macros/src/lib.rs
index c12f7b86..11510a0a 100755
--- a/azalea-block/azalea-block-macros/src/lib.rs
+++ b/azalea-block/azalea-block-macros/src/lib.rs
@@ -312,6 +312,9 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
let mut from_registry_block_to_blockstate_match = quote! {};
let mut from_registry_block_to_blockstates_match = quote! {};
+ // a list of block state ids that are waterlogged
+ let mut waterlogged_state_ids: Vec<u32> = Vec::new();
+
for block in &input.block_definitions.blocks {
let block_property_names = &block
.properties_and_defaults
@@ -448,15 +451,21 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
is_default = false;
}
- let property_type = if property.is_enum {
+ let property_value = if property.is_enum {
quote! {properties::#property_struct_name_ident::#variant}
} else {
quote! {#variant}
};
from_block_to_state_combination_match_inner.extend(quote! {
- #property_name: #property_type,
+ #property_name: #property_value,
});
+
+ // if "waterlogged" is a property and it's true for this state then add it to
+ // waterlogged_state_ids
+ if property_name == "waterlogged" && property_value.to_string() == "true" {
+ waterlogged_state_ids.push(state_id)
+ }
}
from_block_to_state_match_inner.extend(quote! {
@@ -473,7 +482,16 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
}
let Some(default_state_id) = default_state_id else {
- let defaults = properties_with_name.iter().map(|p| if let TokenTree::Ident(i) = p.default.clone().into_iter().last().unwrap() { i.to_string() } else { panic!() }).collect::<Vec<_>>();
+ let defaults = properties_with_name
+ .iter()
+ .map(|p| {
+ if let TokenTree::Ident(i) = p.default.clone().into_iter().last().unwrap() {
+ i.to_string()
+ } else {
+ panic!()
+ }
+ })
+ .collect::<Vec<_>>();
panic!("Couldn't get default state id for {block_name_pascal_case}, combinations={block_properties_vec:?}, defaults={defaults:?}")
};
@@ -570,6 +588,9 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
fn as_block_state(&self) -> BlockState {
#from_block_to_state_match
}
+ fn as_registry_block(&self) -> azalea_registry::Block {
+ azalea_registry::Block::#block_name_pascal_case
+ }
}
impl From<#block_struct_name> for BlockState {
@@ -590,6 +611,8 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
block_structs.extend(block_struct);
}
+ let waterlogged_state_ids_match = quote! { #(#waterlogged_state_ids)|* };
+
let last_state_id = state_id - 1;
let mut generated = quote! {
impl BlockState {
@@ -598,6 +621,12 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
pub fn max_state() -> u32 {
#last_state_id
}
+
+ /// Whether the given block state is waterlogged. This checks for
+ /// the `waterlogged` field, so it'll return false for water.
+ pub fn waterlogged(&self) -> bool {
+ matches!(self.id, #waterlogged_state_ids_match)
+ }
}
pub mod properties {
diff --git a/azalea-block/src/behavior.rs b/azalea-block/src/behavior.rs
index 18854fff..498ba06f 100755
--- a/azalea-block/src/behavior.rs
+++ b/azalea-block/src/behavior.rs
@@ -1,35 +1,55 @@
pub struct BlockBehavior {
- pub has_collision: bool,
pub friction: f32,
pub jump_factor: f32,
+ pub destroy_time: f32,
+ pub explosion_resistance: f32,
+ pub requires_correct_tool_for_drops: bool,
}
impl Default for BlockBehavior {
fn default() -> Self {
Self {
- has_collision: true,
friction: 0.6,
jump_factor: 1.0,
+ destroy_time: 0.,
+ explosion_resistance: 0.,
+ requires_correct_tool_for_drops: false,
}
}
}
impl BlockBehavior {
- #[inline]
- pub fn no_collision(mut self) -> Self {
- self.has_collision = false;
- self
+ pub fn new() -> Self {
+ Self::default()
}
- #[inline]
pub fn friction(mut self, friction: f32) -> Self {
self.friction = friction;
self
}
- #[inline]
pub fn jump_factor(mut self, jump_factor: f32) -> Self {
self.jump_factor = jump_factor;
self
}
+
+ pub fn destroy_time(mut self, destroy_time: f32) -> Self {
+ self.destroy_time = destroy_time;
+ self
+ }
+
+ pub fn explosion_resistance(mut self, explosion_resistance: f32) -> Self {
+ self.explosion_resistance = f32::max(0., explosion_resistance);
+ self
+ }
+
+ pub fn strength(self, destroy_time: f32, explosion_resistance: f32) -> Self {
+ self.destroy_time(destroy_time)
+ .explosion_resistance(explosion_resistance)
+ }
+
+ pub fn requires_correct_tool_for_drops(mut self) -> Self {
+ self.requires_correct_tool_for_drops = true;
+ self
+ }
}
diff --git a/azalea-block/src/generated.rs b/azalea-block/src/generated.rs
index e2faed85..f5c8eee5 100755
--- a/azalea-block/src/generated.rs
+++ b/azalea-block/src/generated.rs
@@ -1506,7 +1506,7 @@ make_block_states! {
_1,
_2,
},
- "age" => SnifferEggAge {
+ "hatch" => SnifferEggHatch {
_0,
_1,
_2,
@@ -1928,414 +1928,414 @@ make_block_states! {
"cracked" => bool,
},
Blocks => {
- air => BlockBehavior::default(), {},
- stone => BlockBehavior::default(), {},
- granite => BlockBehavior::default(), {},
- polished_granite => BlockBehavior::default(), {},
- diorite => BlockBehavior::default(), {},
- polished_diorite => BlockBehavior::default(), {},
- andesite => BlockBehavior::default(), {},
- polished_andesite => BlockBehavior::default(), {},
- grass_block => BlockBehavior::default(), {
+ air => BlockBehavior::new(), {},
+ stone => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ granite => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ polished_granite => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ diorite => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ polished_diorite => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ andesite => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ polished_andesite => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ grass_block => BlockBehavior::new().strength(0.6, 0.6), {
snowy: false,
},
- dirt => BlockBehavior::default(), {},
- coarse_dirt => BlockBehavior::default(), {},
- podzol => BlockBehavior::default(), {
+ dirt => BlockBehavior::new().strength(0.5, 0.5), {},
+ coarse_dirt => BlockBehavior::new().strength(0.5, 0.5), {},
+ podzol => BlockBehavior::new().strength(0.5, 0.5), {
snowy: false,
},
- cobblestone => BlockBehavior::default(), {},
- oak_planks => BlockBehavior::default(), {},
- spruce_planks => BlockBehavior::default(), {},
- birch_planks => BlockBehavior::default(), {},
- jungle_planks => BlockBehavior::default(), {},
- acacia_planks => BlockBehavior::default(), {},
- cherry_planks => BlockBehavior::default(), {},
- dark_oak_planks => BlockBehavior::default(), {},
- mangrove_planks => BlockBehavior::default(), {},
- bamboo_planks => BlockBehavior::default(), {},
- bamboo_mosaic => BlockBehavior::default(), {},
- oak_sapling => BlockBehavior::default(), {
+ cobblestone => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {},
+ oak_planks => BlockBehavior::new().strength(2.0, 3.0), {},
+ spruce_planks => BlockBehavior::new().strength(2.0, 3.0), {},
+ birch_planks => BlockBehavior::new().strength(2.0, 3.0), {},
+ jungle_planks => BlockBehavior::new().strength(2.0, 3.0), {},
+ acacia_planks => BlockBehavior::new().strength(2.0, 3.0), {},
+ cherry_planks => BlockBehavior::new().strength(2.0, 3.0), {},
+ dark_oak_planks => BlockBehavior::new().strength(2.0, 3.0), {},
+ mangrove_planks => BlockBehavior::new().strength(2.0, 3.0), {},
+ bamboo_planks => BlockBehavior::new().strength(2.0, 3.0), {},
+ bamboo_mosaic => BlockBehavior::new().strength(2.0, 3.0), {},
+ oak_sapling => BlockBehavior::new(), {
stage: OakSaplingStage::_0,
},
- spruce_sapling => BlockBehavior::default(), {
+ spruce_sapling => BlockBehavior::new(), {
stage: SpruceSaplingStage::_0,
},
- birch_sapling => BlockBehavior::default(), {
+ birch_sapling => BlockBehavior::new(), {
stage: BirchSaplingStage::_0,
},
- jungle_sapling => BlockBehavior::default(), {
+ jungle_sapling => BlockBehavior::new(), {
stage: JungleSaplingStage::_0,
},
- acacia_sapling => BlockBehavior::default(), {
+ acacia_sapling => BlockBehavior::new(), {
stage: AcaciaSaplingStage::_0,
},
- cherry_sapling => BlockBehavior::default(), {
+ cherry_sapling => BlockBehavior::new(), {
stage: CherrySaplingStage::_0,
},
- dark_oak_sapling => BlockBehavior::default(), {
+ dark_oak_sapling => BlockBehavior::new(), {
stage: DarkOakSaplingStage::_0,
},
- mangrove_propagule => BlockBehavior::default(), {
+ mangrove_propagule => BlockBehavior::new(), {
age: MangrovePropaguleAge::_0,
hanging: false,
stage: MangrovePropaguleStage::_0,
waterlogged: false,
},
- bedrock => BlockBehavior::default(), {},
- water => BlockBehavior::default(), {
+ bedrock => BlockBehavior::new().strength(-1.0, 3600000.0), {},
+ water => BlockBehavior::new().strength(100.0, 100.0), {
level: WaterLevel::_0,
},
- lava => BlockBehavior::default(), {
+ lava => BlockBehavior::new().strength(100.0, 100.0), {
level: LavaLevel::_0,
},
- sand => BlockBehavior::default(), {},
- suspicious_sand => BlockBehavior::default(), {
+ sand => BlockBehavior::new().strength(0.5, 0.5), {},
+ suspicious_sand => BlockBehavior::new().strength(0.25, 0.25), {
dusted: SuspiciousSandDusted::_0,
},
- red_sand => BlockBehavior::default(), {},
- gravel => BlockBehavior::default(), {},
- suspicious_gravel => BlockBehavior::default(), {
+ red_sand => BlockBehavior::new().strength(0.5, 0.5), {},
+ gravel => BlockBehavior::new().strength(0.6, 0.6), {},
+ suspicious_gravel => BlockBehavior::new().strength(0.25, 0.25), {
dusted: SuspiciousGravelDusted::_0,
},
- gold_ore => BlockBehavior::default(), {},
- deepslate_gold_ore => BlockBehavior::default(), {},
- iron_ore => BlockBehavior::default(), {},
- deepslate_iron_ore => BlockBehavior::default(), {},
- coal_ore => BlockBehavior::default(), {},
- deepslate_coal_ore => BlockBehavior::default(), {},
- nether_gold_ore => BlockBehavior::default(), {},
- oak_log => BlockBehavior::default(), {
+ gold_ore => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 3.0), {},
+ deepslate_gold_ore => BlockBehavior::new().requires_correct_tool_for_drops().strength(4.5, 3.0), {},
+ iron_ore => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 3.0), {},
+ deepslate_iron_ore => BlockBehavior::new().requires_correct_tool_for_drops().strength(4.5, 3.0), {},
+ coal_ore => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 3.0), {},
+ deepslate_coal_ore => BlockBehavior::new().requires_correct_tool_for_drops().strength(4.5, 3.0), {},
+ nether_gold_ore => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 3.0), {},
+ oak_log => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- spruce_log => BlockBehavior::default(), {
+ spruce_log => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- birch_log => BlockBehavior::default(), {
+ birch_log => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- jungle_log => BlockBehavior::default(), {
+ jungle_log => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- acacia_log => BlockBehavior::default(), {
+ acacia_log => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- cherry_log => BlockBehavior::default(), {
+ cherry_log => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- dark_oak_log => BlockBehavior::default(), {
+ dark_oak_log => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- mangrove_log => BlockBehavior::default(), {
+ mangrove_log => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- mangrove_roots => BlockBehavior::default(), {
+ mangrove_roots => BlockBehavior::new().strength(0.7, 0.7), {
waterlogged: false,
},
- muddy_mangrove_roots => BlockBehavior::default(), {
+ muddy_mangrove_roots => BlockBehavior::new().strength(0.7, 0.7), {
axis: Axis::Y,
},
- bamboo_block => BlockBehavior::default(), {
+ bamboo_block => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_spruce_log => BlockBehavior::default(), {
+ stripped_spruce_log => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_birch_log => BlockBehavior::default(), {
+ stripped_birch_log => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_jungle_log => BlockBehavior::default(), {
+ stripped_jungle_log => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_acacia_log => BlockBehavior::default(), {
+ stripped_acacia_log => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_cherry_log => BlockBehavior::default(), {
+ stripped_cherry_log => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_dark_oak_log => BlockBehavior::default(), {
+ stripped_dark_oak_log => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_oak_log => BlockBehavior::default(), {
+ stripped_oak_log => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_mangrove_log => BlockBehavior::default(), {
+ stripped_mangrove_log => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_bamboo_block => BlockBehavior::default(), {
+ stripped_bamboo_block => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- oak_wood => BlockBehavior::default(), {
+ oak_wood => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- spruce_wood => BlockBehavior::default(), {
+ spruce_wood => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- birch_wood => BlockBehavior::default(), {
+ birch_wood => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- jungle_wood => BlockBehavior::default(), {
+ jungle_wood => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- acacia_wood => BlockBehavior::default(), {
+ acacia_wood => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- cherry_wood => BlockBehavior::default(), {
+ cherry_wood => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- dark_oak_wood => BlockBehavior::default(), {
+ dark_oak_wood => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- mangrove_wood => BlockBehavior::default(), {
+ mangrove_wood => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_oak_wood => BlockBehavior::default(), {
+ stripped_oak_wood => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_spruce_wood => BlockBehavior::default(), {
+ stripped_spruce_wood => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_birch_wood => BlockBehavior::default(), {
+ stripped_birch_wood => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_jungle_wood => BlockBehavior::default(), {
+ stripped_jungle_wood => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_acacia_wood => BlockBehavior::default(), {
+ stripped_acacia_wood => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_cherry_wood => BlockBehavior::default(), {
+ stripped_cherry_wood => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_dark_oak_wood => BlockBehavior::default(), {
+ stripped_dark_oak_wood => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_mangrove_wood => BlockBehavior::default(), {
+ stripped_mangrove_wood => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- oak_leaves => BlockBehavior::default(), {
+ oak_leaves => BlockBehavior::new().strength(0.2, 0.2), {
distance: OakLeavesDistance::_7,
persistent: false,
waterlogged: false,
},
- spruce_leaves => BlockBehavior::default(), {
+ spruce_leaves => BlockBehavior::new().strength(0.2, 0.2), {
distance: SpruceLeavesDistance::_7,
persistent: false,
waterlogged: false,
},
- birch_leaves => BlockBehavior::default(), {
+ birch_leaves => BlockBehavior::new().strength(0.2, 0.2), {
distance: BirchLeavesDistance::_7,
persistent: false,
waterlogged: false,
},
- jungle_leaves => BlockBehavior::default(), {
+ jungle_leaves => BlockBehavior::new().strength(0.2, 0.2), {
distance: JungleLeavesDistance::_7,
persistent: false,
waterlogged: false,
},
- acacia_leaves => BlockBehavior::default(), {
+ acacia_leaves => BlockBehavior::new().strength(0.2, 0.2), {
distance: AcaciaLeavesDistance::_7,
persistent: false,
waterlogged: false,
},
- cherry_leaves => BlockBehavior::default(), {
+ cherry_leaves => BlockBehavior::new().strength(0.2, 0.2), {
distance: CherryLeavesDistance::_7,
persistent: false,
waterlogged: false,
},
- dark_oak_leaves => BlockBehavior::default(), {
+ dark_oak_leaves => BlockBehavior::new().strength(0.2, 0.2), {
distance: DarkOakLeavesDistance::_7,
persistent: false,
waterlogged: false,
},
- mangrove_leaves => BlockBehavior::default(), {
+ mangrove_leaves => BlockBehavior::new().strength(0.2, 0.2), {
distance: MangroveLeavesDistance::_7,
persistent: false,
waterlogged: false,
},
- azalea_leaves => BlockBehavior::default(), {
+ azalea_leaves => BlockBehavior::new().strength(0.2, 0.2), {
distance: AzaleaLeavesDistance::_7,
persistent: false,
waterlogged: false,
},
- flowering_azalea_leaves => BlockBehavior::default(), {
+ flowering_azalea_leaves => BlockBehavior::new().strength(0.2, 0.2), {
distance: FloweringAzaleaLeavesDistance::_7,
persistent: false,
waterlogged: false,
},
- sponge => BlockBehavior::default(), {},
- wet_sponge => BlockBehavior::default(), {},
- glass => BlockBehavior::default(), {},
- lapis_ore => BlockBehavior::default(), {},
- deepslate_lapis_ore => BlockBehavior::default(), {},
- lapis_block => BlockBehavior::default(), {},
- dispenser => BlockBehavior::default(), {
+ sponge => BlockBehavior::new().strength(0.6, 0.6), {},
+ wet_sponge => BlockBehavior::new().strength(0.6, 0.6), {},
+ glass => BlockBehavior::new().strength(0.3, 0.3), {},
+ lapis_ore => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 3.0), {},
+ deepslate_lapis_ore => BlockBehavior::new().requires_correct_tool_for_drops().strength(4.5, 3.0), {},
+ lapis_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 3.0), {},
+ dispenser => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 3.5), {
facing: FacingCubic::North,
triggered: false,
},
- sandstone => BlockBehavior::default(), {},
- chiseled_sandstone => BlockBehavior::default(), {},
- cut_sandstone => BlockBehavior::default(), {},
- note_block => BlockBehavior::default(), {
+ sandstone => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8), {},
+ chiseled_sandstone => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8), {},
+ cut_sandstone => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8), {},
+ note_block => BlockBehavior::new().strength(0.8, 0.8), {
instrument: Sound::Harp,
note: NoteBlockNote::_0,
powered: false,
},
- white_bed => BlockBehavior::default(), {
+ white_bed => BlockBehavior::new().strength(0.2, 0.2), {
facing: FacingCardinal::North,
occupied: false,
part: Part::Foot,
},
- orange_bed => BlockBehavior::default(), {
+ orange_bed => BlockBehavior::new().strength(0.2, 0.2), {
facing: FacingCardinal::North,
occupied: false,
part: Part::Foot,
},
- magenta_bed => BlockBehavior::default(), {
+ magenta_bed => BlockBehavior::new().strength(0.2, 0.2), {
facing: FacingCardinal::North,
occupied: false,
part: Part::Foot,
},
- light_blue_bed => BlockBehavior::default(), {
+ light_blue_bed => BlockBehavior::new().strength(0.2, 0.2), {
facing: FacingCardinal::North,
occupied: false,
part: Part::Foot,
},
- yellow_bed => BlockBehavior::default(), {
+ yellow_bed => BlockBehavior::new().strength(0.2, 0.2), {
facing: FacingCardinal::North,
occupied: false,
part: Part::Foot,
},
- lime_bed => BlockBehavior::default(), {
+ lime_bed => BlockBehavior::new().strength(0.2, 0.2), {
facing: FacingCardinal::North,
occupied: false,
part: Part::Foot,
},
- pink_bed => BlockBehavior::default(), {
+ pink_bed => BlockBehavior::new().strength(0.2, 0.2), {
facing: FacingCardinal::North,
occupied: false,
part: Part::Foot,
},
- gray_bed => BlockBehavior::default(), {
+ gray_bed => BlockBehavior::new().strength(0.2, 0.2), {
facing: FacingCardinal::North,
occupied: false,
part: Part::Foot,
},
- light_gray_bed => BlockBehavior::default(), {
+ light_gray_bed => BlockBehavior::new().strength(0.2, 0.2), {
facing: FacingCardinal::North,
occupied: false,
part: Part::Foot,
},
- cyan_bed => BlockBehavior::default(), {
+ cyan_bed => BlockBehavior::new().strength(0.2, 0.2), {
facing: FacingCardinal::North,
occupied: false,
part: Part::Foot,
},
- purple_bed => BlockBehavior::default(), {
+ purple_bed => BlockBehavior::new().strength(0.2, 0.2), {
facing: FacingCardinal::North,
occupied: false,
part: Part::Foot,
},
- blue_bed => BlockBehavior::default(), {
+ blue_bed => BlockBehavior::new().strength(0.2, 0.2), {
facing: FacingCardinal::North,
occupied: false,
part: Part::Foot,
},
- brown_bed => BlockBehavior::default(), {
+ brown_bed => BlockBehavior::new().strength(0.2, 0.2), {
facing: FacingCardinal::North,
occupied: false,
part: Part::Foot,
},
- green_bed => BlockBehavior::default(), {
+ green_bed => BlockBehavior::new().strength(0.2, 0.2), {
facing: FacingCardinal::North,
occupied: false,
part: Part::Foot,
},
- red_bed => BlockBehavior::default(), {
+ red_bed => BlockBehavior::new().strength(0.2, 0.2), {
facing: FacingCardinal::North,
occupied: false,
part: Part::Foot,
},
- black_bed => BlockBehavior::default(), {
+ black_bed => BlockBehavior::new().strength(0.2, 0.2), {
facing: FacingCardinal::North,
occupied: false,
part: Part::Foot,
},
- powered_rail => BlockBehavior::default(), {
+ powered_rail => BlockBehavior::new().strength(0.7, 0.7), {
powered: false,
shape: RailShape::NorthSouth,
waterlogged: false,
},
- detector_rail => BlockBehavior::default(), {
+ detector_rail => BlockBehavior::new().strength(0.7, 0.7), {
powered: false,
shape: RailShape::NorthSouth,
waterlogged: false,
},
- sticky_piston => BlockBehavior::default(), {
+ sticky_piston => BlockBehavior::new().strength(1.5, 1.5), {
extended: false,
facing: FacingCubic::North,
},
- cobweb => BlockBehavior::default(), {},
- grass => BlockBehavior::default(), {},
- fern => BlockBehavior::default(), {},
- dead_bush => BlockBehavior::default(), {},
- seagrass => BlockBehavior::default(), {},
- tall_seagrass => BlockBehavior::default(), {
+ cobweb => BlockBehavior::new().requires_correct_tool_for_drops().strength(4.0, 4.0), {},
+ grass => BlockBehavior::new(), {},
+ fern => BlockBehavior::new(), {},
+ dead_bush => BlockBehavior::new(), {},
+ seagrass => BlockBehavior::new(), {},
+ tall_seagrass => BlockBehavior::new(), {
half: Half::Lower,
},
- piston => BlockBehavior::default(), {
+ piston => BlockBehavior::new().strength(1.5, 1.5), {
extended: false,
facing: FacingCubic::North,
},
- piston_head => BlockBehavior::default(), {
+ piston_head => BlockBehavior::new().strength(1.5, 1.5), {
kind: PistonType::Normal,
facing: FacingCubic::North,
short: false,
},
- white_wool => BlockBehavior::default(), {},
- orange_wool => BlockBehavior::default(), {},
- magenta_wool => BlockBehavior::default(), {},
- light_blue_wool => BlockBehavior::default(), {},
- yellow_wool => BlockBehavior::default(), {},
- lime_wool => BlockBehavior::default(), {},
- pink_wool => BlockBehavior::default(), {},
- gray_wool => BlockBehavior::default(), {},
- light_gray_wool => BlockBehavior::default(), {},
- cyan_wool => BlockBehavior::default(), {},
- purple_wool => BlockBehavior::default(), {},
- blue_wool => BlockBehavior::default(), {},
- brown_wool => BlockBehavior::default(), {},
- green_wool => BlockBehavior::default(), {},
- red_wool => BlockBehavior::default(), {},
- black_wool => BlockBehavior::default(), {},
- moving_piston => BlockBehavior::default(), {
+ white_wool => BlockBehavior::new().strength(0.8, 0.8), {},
+ orange_wool => BlockBehavior::new().strength(0.8, 0.8), {},
+ magenta_wool => BlockBehavior::new().strength(0.8, 0.8), {},
+ light_blue_wool => BlockBehavior::new().strength(0.8, 0.8), {},
+ yellow_wool => BlockBehavior::new().strength(0.8, 0.8), {},
+ lime_wool => BlockBehavior::new().strength(0.8, 0.8), {},
+ pink_wool => BlockBehavior::new().strength(0.8, 0.8), {},
+ gray_wool => BlockBehavior::new().strength(0.8, 0.8), {},
+ light_gray_wool => BlockBehavior::new().strength(0.8, 0.8), {},
+ cyan_wool => BlockBehavior::new().strength(0.8, 0.8), {},
+ purple_wool => BlockBehavior::new().strength(0.8, 0.8), {},
+ blue_wool => BlockBehavior::new().strength(0.8, 0.8), {},
+ brown_wool => BlockBehavior::new().strength(0.8, 0.8), {},
+ green_wool => BlockBehavior::new().strength(0.8, 0.8), {},
+ red_wool => BlockBehavior::new().strength(0.8, 0.8), {},
+ black_wool => BlockBehavior::new().strength(0.8, 0.8), {},
+ moving_piston => BlockBehavior::new().destroy_time(-1.0), {
kind: PistonType::Normal,
facing: FacingCubic::North,
},
- dandelion => BlockBehavior::default(), {},
- torchflower => BlockBehavior::default(), {},
- poppy => BlockBehavior::default(), {},
- blue_orchid => BlockBehavior::default(), {},
- allium => BlockBehavior::default(), {},
- azure_bluet => BlockBehavior::default(), {},
- red_tulip => BlockBehavior::default(), {},
- orange_tulip => BlockBehavior::default(), {},
- white_tulip => BlockBehavior::default(), {},
- pink_tulip => BlockBehavior::default(), {},
- oxeye_daisy => BlockBehavior::default(), {},
- cornflower => BlockBehavior::default(), {},
- wither_rose => BlockBehavior::default(), {},
- lily_of_the_valley => BlockBehavior::default(), {},
- brown_mushroom => BlockBehavior::default(), {},
- red_mushroom => BlockBehavior::default(), {},
- gold_block => BlockBehavior::default(), {},
- iron_block => BlockBehavior::default(), {},
- bricks => BlockBehavior::default(), {},
- tnt => BlockBehavior::default(), {
+ dandelion => BlockBehavior::new(), {},
+ torchflower => BlockBehavior::new(), {},
+ poppy => BlockBehavior::new(), {},
+ blue_orchid => BlockBehavior::new(), {},
+ allium => BlockBehavior::new(), {},
+ azure_bluet => BlockBehavior::new(), {},
+ red_tulip => BlockBehavior::new(), {},
+ orange_tulip => BlockBehavior::new(), {},
+ white_tulip => BlockBehavior::new(), {},
+ pink_tulip => BlockBehavior::new(), {},
+ oxeye_daisy => BlockBehavior::new(), {},
+ cornflower => BlockBehavior::new(), {},
+ wither_rose => BlockBehavior::new(), {},
+ lily_of_the_valley => BlockBehavior::new(), {},
+ brown_mushroom => BlockBehavior::new(), {},
+ red_mushroom => BlockBehavior::new(), {},
+ gold_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {},
+ iron_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 6.0), {},
+ bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {},
+ tnt => BlockBehavior::new(), {
unstable: false,
},
- bookshelf => BlockBehavior::default(), {},
- chiseled_bookshelf => BlockBehavior::default(), {
+ bookshelf => BlockBehavior::new().strength(1.5, 1.5), {},
+ chiseled_bookshelf => BlockBehavior::new().strength(1.5, 1.5), {
facing: FacingCardinal::North,
slot_0_occupied: false,
slot_1_occupied: false,
@@ -2344,13 +2344,13 @@ make_block_states! {
slot_4_occupied: false,
slot_5_occupied: false,
},
- mossy_cobblestone => BlockBehavior::default(), {},
- obsidian => BlockBehavior::default(), {},
- torch => BlockBehavior::default(), {},
- wall_torch => BlockBehavior::default(), {
+ mossy_cobblestone => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {},
+ obsidian => BlockBehavior::new().requires_correct_tool_for_drops().strength(50.0, 1200.0), {},
+ torch => BlockBehavior::new(), {},
+ wall_torch => BlockBehavior::new(), {
facing: FacingCardinal::North,
},
- fire => BlockBehavior::default(), {
+ fire => BlockBehavior::new(), {
age: FireAge::_0,
east: false,
north: false,
@@ -2358,439 +2358,439 @@ make_block_states! {
up: false,
west: false,
},
- soul_fire => BlockBehavior::default(), {},
- spawner => BlockBehavior::default(), {},
- oak_stairs => BlockBehavior::default(), {
+ soul_fire => BlockBehavior::new(), {},
+ spawner => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 5.0), {},
+ oak_stairs => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- chest => BlockBehavior::default(), {
+ chest => BlockBehavior::new().strength(2.5, 2.5), {
kind: ChestType::Single,
facing: FacingCardinal::North,
waterlogged: false,
},
- redstone_wire => BlockBehavior::default(), {
+ redstone_wire => BlockBehavior::new(), {
east: WireEast::None,
north: WireNorth::None,
power: RedstoneWirePower::_0,
south: WireSouth::None,
west: WireWest::None,
},
- diamond_ore => BlockBehavior::default(), {},
- deepslate_diamond_ore => BlockBehavior::default(), {},
- diamond_block => BlockBehavior::default(), {},
- crafting_table => BlockBehavior::default(), {},
- wheat => BlockBehavior::default(), {
+ diamond_ore => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 3.0), {},
+ deepslate_diamond_ore => BlockBehavior::new().requires_correct_tool_for_drops().strength(4.5, 3.0), {},
+ diamond_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 6.0), {},
+ crafting_table => BlockBehavior::new().strength(2.5, 2.5), {},
+ wheat => BlockBehavior::new(), {
age: WheatAge::_0,
},
- farmland => BlockBehavior::default(), {
+ farmland => BlockBehavior::new().strength(0.6, 0.6), {
moisture: FarmlandMoisture::_0,
},
- furnace => BlockBehavior::default(), {
+ furnace => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 3.5), {
facing: FacingCardinal::North,
lit: false,
},
- oak_sign => BlockBehavior::default(), {
+ oak_sign => BlockBehavior::new().strength(1.0, 1.0), {
rotation: OakSignRotation::_0,
waterlogged: false,
},
- spruce_sign => BlockBehavior::default(), {
+ spruce_sign => BlockBehavior::new().strength(1.0, 1.0), {
rotation: SpruceSignRotation::_0,
waterlogged: false,
},
- birch_sign => BlockBehavior::default(), {
+ birch_sign => BlockBehavior::new().strength(1.0, 1.0), {
rotation: BirchSignRotation::_0,
waterlogged: false,
},
- acacia_sign => BlockBehavior::default(), {
+ acacia_sign => BlockBehavior::new().strength(1.0, 1.0), {
rotation: AcaciaSignRotation::_0,
waterlogged: false,
},
- cherry_sign => BlockBehavior::default(), {
+ cherry_sign => BlockBehavior::new().strength(1.0, 1.0), {
rotation: CherrySignRotation::_0,
waterlogged: false,
},
- jungle_sign => BlockBehavior::default(), {
+ jungle_sign => BlockBehavior::new().strength(1.0, 1.0), {
rotation: JungleSignRotation::_0,
waterlogged: false,
},
- dark_oak_sign => BlockBehavior::default(), {
+ dark_oak_sign => BlockBehavior::new().strength(1.0, 1.0), {
rotation: DarkOakSignRotation::_0,
waterlogged: false,
},
- mangrove_sign => BlockBehavior::default(), {
+ mangrove_sign => BlockBehavior::new().strength(1.0, 1.0), {
rotation: MangroveSignRotation::_0,
waterlogged: false,
},
- bamboo_sign => BlockBehavior::default(), {
+ bamboo_sign => BlockBehavior::new().strength(1.0, 1.0), {
rotation: BambooSignRotation::_0,
waterlogged: false,
},
- oak_door => BlockBehavior::default(), {
+ oak_door => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: Half::Lower,
hinge: Hinge::Left,
open: false,
powered: false,
},
- ladder => BlockBehavior::default(), {
+ ladder => BlockBehavior::new().strength(0.4, 0.4), {
facing: FacingCardinal::North,
waterlogged: false,
},
- rail => BlockBehavior::default(), {
+ rail => BlockBehavior::new().strength(0.7, 0.7), {
shape: Shape::NorthSouth,
waterlogged: false,
},
- cobblestone_stairs => BlockBehavior::default(), {
+ cobblestone_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- oak_wall_sign => BlockBehavior::default(), {
+ oak_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- spruce_wall_sign => BlockBehavior::default(), {
+ spruce_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- birch_wall_sign => BlockBehavior::default(), {
+ birch_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- acacia_wall_sign => BlockBehavior::default(), {
+ acacia_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- cherry_wall_sign => BlockBehavior::default(), {
+ cherry_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- jungle_wall_sign => BlockBehavior::default(), {
+ jungle_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- dark_oak_wall_sign => BlockBehavior::default(), {
+ dark_oak_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- mangrove_wall_sign => BlockBehavior::default(), {
+ mangrove_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- bamboo_wall_sign => BlockBehavior::default(), {
+ bamboo_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- oak_hanging_sign => BlockBehavior::default(), {
+ oak_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
attached: false,
rotation: OakHangingSignRotation::_0,
waterlogged: false,
},
- spruce_hanging_sign => BlockBehavior::default(), {
+ spruce_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
attached: false,
rotation: SpruceHangingSignRotation::_0,
waterlogged: false,
},
- birch_hanging_sign => BlockBehavior::default(), {
+ birch_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
attached: false,
rotation: BirchHangingSignRotation::_0,
waterlogged: false,
},
- acacia_hanging_sign => BlockBehavior::default(), {
+ acacia_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
attached: false,
rotation: AcaciaHangingSignRotation::_0,
waterlogged: false,
},
- cherry_hanging_sign => BlockBehavior::default(), {
+ cherry_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
attached: false,
rotation: CherryHangingSignRotation::_0,
waterlogged: false,
},
- jungle_hanging_sign => BlockBehavior::default(), {
+ jungle_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
attached: false,
rotation: JungleHangingSignRotation::_0,
waterlogged: false,
},
- dark_oak_hanging_sign => BlockBehavior::default(), {
+ dark_oak_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
attached: false,
rotation: DarkOakHangingSignRotation::_0,
waterlogged: false,
},
- crimson_hanging_sign => BlockBehavior::default(), {
+ crimson_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
attached: false,
rotation: CrimsonHangingSignRotation::_0,
waterlogged: false,
},
- warped_hanging_sign => BlockBehavior::default(), {
+ warped_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
attached: false,
rotation: WarpedHangingSignRotation::_0,
waterlogged: false,
},
- mangrove_hanging_sign => BlockBehavior::default(), {
+ mangrove_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
attached: false,
rotation: MangroveHangingSignRotation::_0,
waterlogged: false,
},
- bamboo_hanging_sign => BlockBehavior::default(), {
+ bamboo_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
attached: false,
rotation: BambooHangingSignRotation::_0,
waterlogged: false,
},
- oak_wall_hanging_sign => BlockBehavior::default(), {
+ oak_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- spruce_wall_hanging_sign => BlockBehavior::default(), {
+ spruce_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- birch_wall_hanging_sign => BlockBehavior::default(), {
+ birch_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- acacia_wall_hanging_sign => BlockBehavior::default(), {
+ acacia_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- cherry_wall_hanging_sign => BlockBehavior::default(), {
+ cherry_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- jungle_wall_hanging_sign => BlockBehavior::default(), {
+ jungle_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- dark_oak_wall_hanging_sign => BlockBehavior::default(), {
+ dark_oak_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- mangrove_wall_hanging_sign => BlockBehavior::default(), {
+ mangrove_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- crimson_wall_hanging_sign => BlockBehavior::default(), {
+ crimson_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- warped_wall_hanging_sign => BlockBehavior::default(), {
+ warped_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- bamboo_wall_hanging_sign => BlockBehavior::default(), {
+ bamboo_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- lever => BlockBehavior::default(), {
+ lever => BlockBehavior::new().strength(0.5, 0.5), {
face: Face::Wall,
facing: FacingCardinal::North,
powered: false,
},
- stone_pressure_plate => BlockBehavior::default(), {
+ stone_pressure_plate => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.5, 0.5), {
powered: false,
},
- iron_door => BlockBehavior::default(), {
+ iron_door => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 5.0), {
facing: FacingCardinal::North,
half: Half::Lower,
hinge: Hinge::Left,
open: false,
powered: false,
},
- oak_pressure_plate => BlockBehavior::default(), {
+ oak_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
powered: false,
},
- spruce_pressure_plate => BlockBehavior::default(), {
+ spruce_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
powered: false,
},
- birch_pressure_plate => BlockBehavior::default(), {
+ birch_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
powered: false,
},
- jungle_pressure_plate => BlockBehavior::default(), {
+ jungle_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
powered: false,
},
- acacia_pressure_plate => BlockBehavior::default(), {
+ acacia_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
powered: false,
},
- cherry_pressure_plate => BlockBehavior::default(), {
+ cherry_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
powered: false,
},
- dark_oak_pressure_plate => BlockBehavior::default(), {
+ dark_oak_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
powered: false,
},
- mangrove_pressure_plate => BlockBehavior::default(), {
+ mangrove_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
powered: false,
},
- bamboo_pressure_plate => BlockBehavior::default(), {
+ bamboo_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
powered: false,
},
- redstone_ore => BlockBehavior::default(), {
+ redstone_ore => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 3.0), {
lit: false,
},
- deepslate_redstone_ore => BlockBehavior::default(), {
+ deepslate_redstone_ore => BlockBehavior::new().requires_correct_tool_for_drops().strength(4.5, 3.0), {
lit: false,
},
- redstone_torch => BlockBehavior::default(), {
+ redstone_torch => BlockBehavior::new(), {
lit: true,
},
- redstone_wall_torch => BlockBehavior::default(), {
+ redstone_wall_torch => BlockBehavior::new(), {
facing: FacingCardinal::North,
lit: true,
},
- stone_button => BlockBehavior::default(), {
+ stone_button => BlockBehavior::new().strength(0.5, 0.5), {
face: Face::Wall,
facing: FacingCardinal::North,
powered: false,
},
- snow => BlockBehavior::default(), {
+ snow => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.1, 0.1), {
layers: SnowLayers::_1,
},
- ice => BlockBehavior::default(), {},
- snow_block => BlockBehavior::default(), {},
- cactus => BlockBehavior::default(), {
+ ice => BlockBehavior::new().strength(0.5, 0.5).friction(0.98), {},
+ snow_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.2, 0.2), {},
+ cactus => BlockBehavior::new().strength(0.4, 0.4), {
age: CactusAge::_0,
},
- clay => BlockBehavior::default(), {},
- sugar_cane => BlockBehavior::default(), {
+ clay => BlockBehavior::new().strength(0.6, 0.6), {},
+ sugar_cane => BlockBehavior::new(), {
age: SugarCaneAge::_0,
},
- jukebox => BlockBehavior::default(), {
+ jukebox => BlockBehavior::new().strength(2.0, 6.0), {
has_record: false,
},
- oak_fence => BlockBehavior::default(), {
+ oak_fence => BlockBehavior::new().strength(2.0, 3.0), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- pumpkin => BlockBehavior::default(), {},
- netherrack => BlockBehavior::default(), {},
- soul_sand => BlockBehavior::default(), {},
- soul_soil => BlockBehavior::default(), {},
- basalt => BlockBehavior::default(), {
+ pumpkin => BlockBehavior::new().strength(1.0, 1.0), {},
+ netherrack => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.4, 0.4), {},
+ soul_sand => BlockBehavior::new().strength(0.5, 0.5), {},
+ soul_soil => BlockBehavior::new().strength(0.5, 0.5), {},
+ basalt => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {
axis: Axis::Y,
},
- polished_basalt => BlockBehavior::default(), {
+ polished_basalt => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {
axis: Axis::Y,
},
- soul_torch => BlockBehavior::default(), {},
- soul_wall_torch => BlockBehavior::default(), {
+ soul_torch => BlockBehavior::new(), {},
+ soul_wall_torch => BlockBehavior::new(), {
facing: FacingCardinal::North,
},
- glowstone => BlockBehavior::default(), {},
- nether_portal => BlockBehavior::default(), {
+ glowstone => BlockBehavior::new().strength(0.3, 0.3), {},
+ nether_portal => BlockBehavior::new().destroy_time(-1.0), {
axis: AxisXZ::X,
},
- carved_pumpkin => BlockBehavior::default(), {
+ carved_pumpkin => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- jack_o_lantern => BlockBehavior::default(), {
+ jack_o_lantern => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- cake => BlockBehavior::default(), {
+ cake => BlockBehavior::new().strength(0.5, 0.5), {
bites: CakeBites::_0,
},
- repeater => BlockBehavior::default(), {
+ repeater => BlockBehavior::new(), {
delay: RepeaterDelay::_1,
facing: FacingCardinal::North,
locked: false,
powered: false,
},
- white_stained_glass => BlockBehavior::default(), {},
- orange_stained_glass => BlockBehavior::default(), {},
- magenta_stained_glass => BlockBehavior::default(), {},
- light_blue_stained_glass => BlockBehavior::default(), {},
- yellow_stained_glass => BlockBehavior::default(), {},
- lime_stained_glass => BlockBehavior::default(), {},
- pink_stained_glass => BlockBehavior::default(), {},
- gray_stained_glass => BlockBehavior::default(), {},
- light_gray_stained_glass => BlockBehavior::default(), {},
- cyan_stained_glass => BlockBehavior::default(), {},
- purple_stained_glass => BlockBehavior::default(), {},
- blue_stained_glass => BlockBehavior::default(), {},
- brown_stained_glass => BlockBehavior::default(), {},
- green_stained_glass => BlockBehavior::default(), {},
- red_stained_glass => BlockBehavior::default(), {},
- black_stained_glass => BlockBehavior::default(), {},
- oak_trapdoor => BlockBehavior::default(), {
+ white_stained_glass => BlockBehavior::new().strength(0.3, 0.3), {},
+ orange_stained_glass => BlockBehavior::new().strength(0.3, 0.3), {},
+ magenta_stained_glass => BlockBehavior::new().strength(0.3, 0.3), {},
+ light_blue_stained_glass => BlockBehavior::new().strength(0.3, 0.3), {},
+ yellow_stained_glass => BlockBehavior::new().strength(0.3, 0.3), {},
+ lime_stained_glass => BlockBehavior::new().strength(0.3, 0.3), {},
+ pink_stained_glass => BlockBehavior::new().strength(0.3, 0.3), {},
+ gray_stained_glass => BlockBehavior::new().strength(0.3, 0.3), {},
+ light_gray_stained_glass => BlockBehavior::new().strength(0.3, 0.3), {},
+ cyan_stained_glass => BlockBehavior::new().strength(0.3, 0.3), {},
+ purple_stained_glass => BlockBehavior::new().strength(0.3, 0.3), {},
+ blue_stained_glass => BlockBehavior::new().strength(0.3, 0.3), {},
+ brown_stained_glass => BlockBehavior::new().strength(0.3, 0.3), {},
+ green_stained_glass => BlockBehavior::new().strength(0.3, 0.3), {},
+ red_stained_glass => BlockBehavior::new().strength(0.3, 0.3), {},
+ black_stained_glass => BlockBehavior::new().strength(0.3, 0.3), {},
+ oak_trapdoor => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
open: false,
powered: false,
waterlogged: false,
},
- spruce_trapdoor => BlockBehavior::default(), {
+ spruce_trapdoor => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
open: false,
powered: false,
waterlogged: false,
},
- birch_trapdoor => BlockBehavior::default(), {
+ birch_trapdoor => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
open: false,
powered: false,
waterlogged: false,
},
- jungle_trapdoor => BlockBehavior::default(), {
+ jungle_trapdoor => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
open: false,
powered: false,
waterlogged: false,
},
- acacia_trapdoor => BlockBehavior::default(), {
+ acacia_trapdoor => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
open: false,
powered: false,
waterlogged: false,
},
- cherry_trapdoor => BlockBehavior::default(), {
+ cherry_trapdoor => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
open: false,
powered: false,
waterlogged: false,
},
- dark_oak_trapdoor => BlockBehavior::default(), {
+ dark_oak_trapdoor => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
open: false,
powered: false,
waterlogged: false,
},
- mangrove_trapdoor => BlockBehavior::default(), {
+ mangrove_trapdoor => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
open: false,
powered: false,
waterlogged: false,
},
- bamboo_trapdoor => BlockBehavior::default(), {
+ bamboo_trapdoor => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
open: false,
powered: false,
waterlogged: false,
},
- stone_bricks => BlockBehavior::default(), {},
- mossy_stone_bricks => BlockBehavior::default(), {},
- cracked_stone_bricks => BlockBehavior::default(), {},
- chiseled_stone_bricks => BlockBehavior::default(), {},
- packed_mud => BlockBehavior::default(), {},
- mud_bricks => BlockBehavior::default(), {},
- infested_stone => BlockBehavior::default(), {},
- infested_cobblestone => BlockBehavior::default(), {},
- infested_stone_bricks => BlockBehavior::default(), {},
- infested_mossy_stone_bricks => BlockBehavior::default(), {},
- infested_cracked_stone_bricks => BlockBehavior::default(), {},
- infested_chiseled_stone_bricks => BlockBehavior::default(), {},
- brown_mushroom_block => BlockBehavior::default(), {
+ stone_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ mossy_stone_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ cracked_stone_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ chiseled_stone_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ packed_mud => BlockBehavior::new().strength(1.0, 3.0), {},
+ mud_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 3.0), {},
+ infested_stone => BlockBehavior::new().strength(0.75, 0.75), {},
+ infested_cobblestone => BlockBehavior::new().strength(1.0, 0.75), {},
+ infested_stone_bricks => BlockBehavior::new().strength(0.75, 0.75), {},
+ infested_mossy_stone_bricks => BlockBehavior::new().strength(0.75, 0.75), {},
+ infested_cracked_stone_bricks => BlockBehavior::new().strength(0.75, 0.75), {},
+ infested_chiseled_stone_bricks => BlockBehavior::new().strength(0.75, 0.75), {},
+ brown_mushroom_block => BlockBehavior::new().strength(0.2, 0.2), {
down: true,
east: true,
north: true,
@@ -2798,7 +2798,7 @@ make_block_states! {
up: true,
west: true,
},
- red_mushroom_block => BlockBehavior::default(), {
+ red_mushroom_block => BlockBehavior::new().strength(0.2, 0.2), {
down: true,
east: true,
north: true,
@@ -2806,7 +2806,7 @@ make_block_states! {
up: true,
west: true,
},
- mushroom_stem => BlockBehavior::default(), {
+ mushroom_stem => BlockBehavior::new().strength(0.2, 0.2), {
down: true,
east: true,
north: true,
@@ -2814,45 +2814,45 @@ make_block_states! {
up: true,
west: true,
},
- iron_bars => BlockBehavior::default(), {
+ iron_bars => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 6.0), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- chain => BlockBehavior::default(), {
+ chain => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 6.0), {
axis: Axis::Y,
waterlogged: false,
},
- glass_pane => BlockBehavior::default(), {
+ glass_pane => BlockBehavior::new().strength(0.3, 0.3), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- melon => BlockBehavior::default(), {},
- attached_pumpkin_stem => BlockBehavior::default(), {
+ melon => BlockBehavior::new().strength(1.0, 1.0), {},
+ attached_pumpkin_stem => BlockBehavior::new(), {
facing: FacingCardinal::North,
},
- attached_melon_stem => BlockBehavior::default(), {
+ attached_melon_stem => BlockBehavior::new(), {
facing: FacingCardinal::North,
},
- pumpkin_stem => BlockBehavior::default(), {
+ pumpkin_stem => BlockBehavior::new(), {
age: PumpkinStemAge::_0,
},
- melon_stem => BlockBehavior::default(), {
+ melon_stem => BlockBehavior::new(), {
age: MelonStemAge::_0,
},
- vine => BlockBehavior::default(), {
+ vine => BlockBehavior::new().strength(0.2, 0.2), {
east: false,
north: false,
south: false,
up: false,
west: false,
},
- glow_lichen => BlockBehavior::default(), {
+ glow_lichen => BlockBehavior::new().strength(0.2, 0.2), {
down: false,
east: false,
north: false,
@@ -2861,97 +2861,97 @@ make_block_states! {
waterlogged: false,
west: false,
},
- oak_fence_gate => BlockBehavior::default(), {
+ oak_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
in_wall: false,
open: false,
powered: false,
},
- brick_stairs => BlockBehavior::default(), {
+ brick_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- stone_brick_stairs => BlockBehavior::default(), {
+ stone_brick_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- mud_brick_stairs => BlockBehavior::default(), {
+ mud_brick_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- mycelium => BlockBehavior::default(), {
+ mycelium => BlockBehavior::new().strength(0.6, 0.6), {
snowy: false,
},
- lily_pad => BlockBehavior::default(), {},
- nether_bricks => BlockBehavior::default(), {},
- nether_brick_fence => BlockBehavior::default(), {
+ lily_pad => BlockBehavior::new(), {},
+ nether_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {},
+ nether_brick_fence => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- nether_brick_stairs => BlockBehavior::default(), {
+ nether_brick_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- nether_wart => BlockBehavior::default(), {
+ nether_wart => BlockBehavior::new(), {
age: NetherWartAge::_0,
},
- enchanting_table => BlockBehavior::default(), {},
- brewing_stand => BlockBehavior::default(), {
+ enchanting_table => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 1200.0), {},
+ brewing_stand => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.5, 0.5), {
has_bottle: false,
has_bottle: false,
has_bottle: false,
},
- cauldron => BlockBehavior::default(), {},
- water_cauldron => BlockBehavior::default(), {
+ cauldron => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 2.0), {},
+ water_cauldron => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 2.0), {
level: WaterCauldronLevel::_1,
},
- lava_cauldron => BlockBehavior::default(), {},
- powder_snow_cauldron => BlockBehavior::default(), {
+ lava_cauldron => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 2.0), {},
+ powder_snow_cauldron => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 2.0), {
level: PowderSnowCauldronLevel::_1,
},
- end_portal => BlockBehavior::default(), {},
- end_portal_frame => BlockBehavior::default(), {
+ end_portal => BlockBehavior::new().strength(-1.0, 3600000.0), {},
+ end_portal_frame => BlockBehavior::new().strength(-1.0, 3600000.0), {
eye: false,
facing: FacingCardinal::North,
},
- end_stone => BlockBehavior::default(), {},
- dragon_egg => BlockBehavior::default(), {},
- redstone_lamp => BlockBehavior::default(), {
+ end_stone => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 9.0), {},
+ dragon_egg => BlockBehavior::new().strength(3.0, 9.0), {},
+ redstone_lamp => BlockBehavior::new().strength(0.3, 0.3), {
lit: false,
},
- cocoa => BlockBehavior::default(), {
+ cocoa => BlockBehavior::new().strength(0.2, 3.0), {
age: CocoaAge::_0,
facing: FacingCardinal::North,
},
- sandstone_stairs => BlockBehavior::default(), {
+ sandstone_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- emerald_ore => BlockBehavior::default(), {},
- deepslate_emerald_ore => BlockBehavior::default(), {},
- ender_chest => BlockBehavior::default(), {
+ emerald_ore => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 3.0), {},
+ deepslate_emerald_ore => BlockBehavior::new().requires_correct_tool_for_drops().strength(4.5, 3.0), {},
+ ender_chest => BlockBehavior::new().requires_correct_tool_for_drops().strength(22.5, 600.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- tripwire_hook => BlockBehavior::default(), {
+ tripwire_hook => BlockBehavior::new(), {
attached: false,
facing: FacingCardinal::North,
powered: false,
},
- tripwire => BlockBehavior::default(), {
+ tripwire => BlockBehavior::new(), {
attached: false,
disarmed: false,
east: false,
@@ -2960,31 +2960,31 @@ make_block_states! {
south: false,
west: false,
},
- emerald_block => BlockBehavior::default(), {},
- spruce_stairs => BlockBehavior::default(), {
+ emerald_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 6.0), {},
+ spruce_stairs => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- birch_stairs => BlockBehavior::default(), {
+ birch_stairs => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- jungle_stairs => BlockBehavior::default(), {
+ jungle_stairs => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- command_block => BlockBehavior::default(), {
+ command_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(-1.0, 3600000.0), {
conditional: false,
facing: FacingCubic::North,
},
- beacon => BlockBehavior::default(), {},
- cobblestone_wall => BlockBehavior::default(), {
+ beacon => BlockBehavior::new().strength(3.0, 3.0), {},
+ cobblestone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -2992,7 +2992,7 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- mossy_cobblestone_wall => BlockBehavior::default(), {
+ mossy_cobblestone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -3000,802 +3000,802 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- flower_pot => BlockBehavior::default(), {},
- potted_torchflower => BlockBehavior::default(), {},
- potted_oak_sapling => BlockBehavior::default(), {},
- potted_spruce_sapling => BlockBehavior::default(), {},
- potted_birch_sapling => BlockBehavior::default(), {},
- potted_jungle_sapling => BlockBehavior::default(), {},
- potted_acacia_sapling => BlockBehavior::default(), {},
- potted_cherry_sapling => BlockBehavior::default(), {},
- potted_dark_oak_sapling => BlockBehavior::default(), {},
- potted_mangrove_propagule => BlockBehavior::default(), {},
- potted_fern => BlockBehavior::default(), {},
- potted_dandelion => BlockBehavior::default(), {},
- potted_poppy => BlockBehavior::default(), {},
- potted_blue_orchid => BlockBehavior::default(), {},
- potted_allium => BlockBehavior::default(), {},
- potted_azure_bluet => BlockBehavior::default(), {},
- potted_red_tulip => BlockBehavior::default(), {},
- potted_orange_tulip => BlockBehavior::default(), {},
- potted_white_tulip => BlockBehavior::default(), {},
- potted_pink_tulip => BlockBehavior::default(), {},
- potted_oxeye_daisy => BlockBehavior::default(), {},
- potted_cornflower => BlockBehavior::default(), {},
- potted_lily_of_the_valley => BlockBehavior::default(), {},
- potted_wither_rose => BlockBehavior::default(), {},
- potted_red_mushroom => BlockBehavior::default(), {},
- potted_brown_mushroom => BlockBehavior::default(), {},
- potted_dead_bush => BlockBehavior::default(), {},
- potted_cactus => BlockBehavior::default(), {},
- carrots => BlockBehavior::default(), {
+ flower_pot => BlockBehavior::new(), {},
+ potted_torchflower => BlockBehavior::new(), {},
+ potted_oak_sapling => BlockBehavior::new(), {},
+ potted_spruce_sapling => BlockBehavior::new(), {},
+ potted_birch_sapling => BlockBehavior::new(), {},
+ potted_jungle_sapling => BlockBehavior::new(), {},
+ potted_acacia_sapling => BlockBehavior::new(), {},
+ potted_cherry_sapling => BlockBehavior::new(), {},
+ potted_dark_oak_sapling => BlockBehavior::new(), {},
+ potted_mangrove_propagule => BlockBehavior::new(), {},
+ potted_fern => BlockBehavior::new(), {},
+ potted_dandelion => BlockBehavior::new(), {},
+ potted_poppy => BlockBehavior::new(), {},
+ potted_blue_orchid => BlockBehavior::new(), {},
+ potted_allium => BlockBehavior::new(), {},
+ potted_azure_bluet => BlockBehavior::new(), {},
+ potted_red_tulip => BlockBehavior::new(), {},
+ potted_orange_tulip => BlockBehavior::new(), {},
+ potted_white_tulip => BlockBehavior::new(), {},
+ potted_pink_tulip => BlockBehavior::new(), {},
+ potted_oxeye_daisy => BlockBehavior::new(), {},
+ potted_cornflower => BlockBehavior::new(), {},
+ potted_lily_of_the_valley => BlockBehavior::new(), {},
+ potted_wither_rose => BlockBehavior::new(), {},
+ potted_red_mushroom => BlockBehavior::new(), {},
+ potted_brown_mushroom => BlockBehavior::new(), {},
+ potted_dead_bush => BlockBehavior::new(), {},
+ potted_cactus => BlockBehavior::new(), {},
+ carrots => BlockBehavior::new(), {
age: CarrotsAge::_0,
},
- potatoes => BlockBehavior::default(), {
+ potatoes => BlockBehavior::new(), {
age: PotatoesAge::_0,
},
- oak_button => BlockBehavior::default(), {
+ oak_button => BlockBehavior::new().strength(0.5, 0.5), {
face: Face::Wall,
facing: FacingCardinal::North,
powered: false,
},
- spruce_button => BlockBehavior::default(), {
+ spruce_button => BlockBehavior::new().strength(0.5, 0.5), {
face: Face::Wall,
facing: FacingCardinal::North,
powered: false,
},
- birch_button => BlockBehavior::default(), {
+ birch_button => BlockBehavior::new().strength(0.5, 0.5), {
face: Face::Wall,
facing: FacingCardinal::North,
powered: false,
},
- jungle_button => BlockBehavior::default(), {
+ jungle_button => BlockBehavior::new().strength(0.5, 0.5), {
face: Face::Wall,
facing: FacingCardinal::North,
powered: false,
},
- acacia_button => BlockBehavior::default(), {
+ acacia_button => BlockBehavior::new().strength(0.5, 0.5), {
face: Face::Wall,
facing: FacingCardinal::North,
powered: false,
},
- cherry_button => BlockBehavior::default(), {
+ cherry_button => BlockBehavior::new().strength(0.5, 0.5), {
face: Face::Wall,
facing: FacingCardinal::North,
powered: false,
},
- dark_oak_button => BlockBehavior::default(), {
+ dark_oak_button => BlockBehavior::new().strength(0.5, 0.5), {
face: Face::Wall,
facing: FacingCardinal::North,
powered: false,
},
- mangrove_button => BlockBehavior::default(), {
+ mangrove_button => BlockBehavior::new().strength(0.5, 0.5), {
face: Face::Wall,
facing: FacingCardinal::North,
powered: false,
},
- bamboo_button => BlockBehavior::default(), {
+ bamboo_button => BlockBehavior::new().strength(0.5, 0.5), {
face: Face::Wall,
facing: FacingCardinal::North,
powered: false,
},
- skeleton_skull => BlockBehavior::default(), {
+ skeleton_skull => BlockBehavior::new().strength(1.0, 1.0), {
rotation: SkeletonSkullRotation::_0,
},
- skeleton_wall_skull => BlockBehavior::default(), {
+ skeleton_wall_skull => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- wither_skeleton_skull => BlockBehavior::default(), {
+ wither_skeleton_skull => BlockBehavior::new().strength(1.0, 1.0), {
rotation: WitherSkeletonSkullRotation::_0,
},
- wither_skeleton_wall_skull => BlockBehavior::default(), {
+ wither_skeleton_wall_skull => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- zombie_head => BlockBehavior::default(), {
+ zombie_head => BlockBehavior::new().strength(1.0, 1.0), {
rotation: ZombieHeadRotation::_0,
},
- zombie_wall_head => BlockBehavior::default(), {
+ zombie_wall_head => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- player_head => BlockBehavior::default(), {
+ player_head => BlockBehavior::new().strength(1.0, 1.0), {
rotation: PlayerHeadRotation::_0,
},
- player_wall_head => BlockBehavior::default(), {
+ player_wall_head => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- creeper_head => BlockBehavior::default(), {
+ creeper_head => BlockBehavior::new().strength(1.0, 1.0), {
rotation: CreeperHeadRotation::_0,
},
- creeper_wall_head => BlockBehavior::default(), {
+ creeper_wall_head => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- dragon_head => BlockBehavior::default(), {
+ dragon_head => BlockBehavior::new().strength(1.0, 1.0), {
rotation: DragonHeadRotation::_0,
},
- dragon_wall_head => BlockBehavior::default(), {
+ dragon_wall_head => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- piglin_head => BlockBehavior::default(), {
+ piglin_head => BlockBehavior::new().strength(1.0, 1.0), {
rotation: PiglinHeadRotation::_0,
},
- piglin_wall_head => BlockBehavior::default(), {
+ piglin_wall_head => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- anvil => BlockBehavior::default(), {
+ anvil => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 1200.0), {
facing: FacingCardinal::North,
},
- chipped_anvil => BlockBehavior::default(), {
+ chipped_anvil => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 1200.0), {
facing: FacingCardinal::North,
},
- damaged_anvil => BlockBehavior::default(), {
+ damaged_anvil => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 1200.0), {
facing: FacingCardinal::North,
},
- trapped_chest => BlockBehavior::default(), {
+ trapped_chest => BlockBehavior::new().strength(2.5, 2.5), {
kind: ChestType::Single,
facing: FacingCardinal::North,
waterlogged: false,
},
- light_weighted_pressure_plate => BlockBehavior::default(), {
+ light_weighted_pressure_plate => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.5, 0.5), {
power: LightWeightedPressurePlatePower::_0,
},
- heavy_weighted_pressure_plate => BlockBehavior::default(), {
+ heavy_weighted_pressure_plate => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.5, 0.5), {
power: HeavyWeightedPressurePlatePower::_0,
},
- comparator => BlockBehavior::default(), {
+ comparator => BlockBehavior::new(), {
facing: FacingCardinal::North,
mode: ComparatorType::Compare,
powered: false,
},
- daylight_detector => BlockBehavior::default(), {
+ daylight_detector => BlockBehavior::new().strength(0.2, 0.2), {
inverted: false,
power: DaylightDetectorPower::_0,
},
- redstone_block => BlockBehavior::default(), {},
- nether_quartz_ore => BlockBehavior::default(), {},
- hopper => BlockBehavior::default(), {
+ redstone_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 6.0), {},
+ nether_quartz_ore => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 3.0), {},
+ hopper => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 4.8), {
enabled: true,
facing: Facing::Down,
},
- quartz_block => BlockBehavior::default(), {},
- chiseled_quartz_block => BlockBehavior::default(), {},
- quartz_pillar => BlockBehavior::default(), {
+ quartz_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8), {},
+ chiseled_quartz_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8), {},
+ quartz_pillar => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8), {
axis: Axis::Y,
},
- quartz_stairs => BlockBehavior::default(), {
+ quartz_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- activator_rail => BlockBehavior::default(), {
+ activator_rail => BlockBehavior::new().strength(0.7, 0.7), {
powered: false,
shape: RailShape::NorthSouth,
waterlogged: false,
},
- dropper => BlockBehavior::default(), {
+ dropper => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 3.5), {
facing: FacingCubic::North,
triggered: false,
},
- white_terracotta => BlockBehavior::default(), {},
- orange_terracotta => BlockBehavior::default(), {},
- magenta_terracotta => BlockBehavior::default(), {},
- light_blue_terracotta => BlockBehavior::default(), {},
- yellow_terracotta => BlockBehavior::default(), {},
- lime_terracotta => BlockBehavior::default(), {},
- pink_terracotta => BlockBehavior::default(), {},
- gray_terracotta => BlockBehavior::default(), {},
- light_gray_terracotta => BlockBehavior::default(), {},
- cyan_terracotta => BlockBehavior::default(), {},
- purple_terracotta => BlockBehavior::default(), {},
- blue_terracotta => BlockBehavior::default(), {},
- brown_terracotta => BlockBehavior::default(), {},
- green_terracotta => BlockBehavior::default(), {},
- red_terracotta => BlockBehavior::default(), {},
- black_terracotta => BlockBehavior::default(), {},
- white_stained_glass_pane => BlockBehavior::default(), {
+ white_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {},
+ orange_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {},
+ magenta_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {},
+ light_blue_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {},
+ yellow_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {},
+ lime_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {},
+ pink_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {},
+ gray_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {},
+ light_gray_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {},
+ cyan_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {},
+ purple_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {},
+ blue_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {},
+ brown_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {},
+ green_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {},
+ red_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {},
+ black_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {},
+ white_stained_glass_pane => BlockBehavior::new().strength(0.3, 0.3), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- orange_stained_glass_pane => BlockBehavior::default(), {
+ orange_stained_glass_pane => BlockBehavior::new().strength(0.3, 0.3), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- magenta_stained_glass_pane => BlockBehavior::default(), {
+ magenta_stained_glass_pane => BlockBehavior::new().strength(0.3, 0.3), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- light_blue_stained_glass_pane => BlockBehavior::default(), {
+ light_blue_stained_glass_pane => BlockBehavior::new().strength(0.3, 0.3), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- yellow_stained_glass_pane => BlockBehavior::default(), {
+ yellow_stained_glass_pane => BlockBehavior::new().strength(0.3, 0.3), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- lime_stained_glass_pane => BlockBehavior::default(), {
+ lime_stained_glass_pane => BlockBehavior::new().strength(0.3, 0.3), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- pink_stained_glass_pane => BlockBehavior::default(), {
+ pink_stained_glass_pane => BlockBehavior::new().strength(0.3, 0.3), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- gray_stained_glass_pane => BlockBehavior::default(), {
+ gray_stained_glass_pane => BlockBehavior::new().strength(0.3, 0.3), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- light_gray_stained_glass_pane => BlockBehavior::default(), {
+ light_gray_stained_glass_pane => BlockBehavior::new().strength(0.3, 0.3), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- cyan_stained_glass_pane => BlockBehavior::default(), {
+ cyan_stained_glass_pane => BlockBehavior::new().strength(0.3, 0.3), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- purple_stained_glass_pane => BlockBehavior::default(), {
+ purple_stained_glass_pane => BlockBehavior::new().strength(0.3, 0.3), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- blue_stained_glass_pane => BlockBehavior::default(), {
+ blue_stained_glass_pane => BlockBehavior::new().strength(0.3, 0.3), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- brown_stained_glass_pane => BlockBehavior::default(), {
+ brown_stained_glass_pane => BlockBehavior::new().strength(0.3, 0.3), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- green_stained_glass_pane => BlockBehavior::default(), {
+ green_stained_glass_pane => BlockBehavior::new().strength(0.3, 0.3), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- red_stained_glass_pane => BlockBehavior::default(), {
+ red_stained_glass_pane => BlockBehavior::new().strength(0.3, 0.3), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- black_stained_glass_pane => BlockBehavior::default(), {
+ black_stained_glass_pane => BlockBehavior::new().strength(0.3, 0.3), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- acacia_stairs => BlockBehavior::default(), {
+ acacia_stairs => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- cherry_stairs => BlockBehavior::default(), {
+ cherry_stairs => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- dark_oak_stairs => BlockBehavior::default(), {
+ dark_oak_stairs => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- mangrove_stairs => BlockBehavior::default(), {
+ mangrove_stairs => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- bamboo_stairs => BlockBehavior::default(), {
+ bamboo_stairs => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- bamboo_mosaic_stairs => BlockBehavior::default(), {
+ bamboo_mosaic_stairs => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- slime_block => BlockBehavior::default(), {},
- barrier => BlockBehavior::default(), {},
- light => BlockBehavior::default(), {
+ slime_block => BlockBehavior::new().friction(0.8), {},
+ barrier => BlockBehavior::new().strength(-1.0, 3600000.8), {},
+ light => BlockBehavior::new().strength(-1.0, 3600000.8), {
level: LightLevel::_15,
waterlogged: false,
},
- iron_trapdoor => BlockBehavior::default(), {
+ iron_trapdoor => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 5.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
open: false,
powered: false,
waterlogged: false,
},
- prismarine => BlockBehavior::default(), {},
- prismarine_bricks => BlockBehavior::default(), {},
- dark_prismarine => BlockBehavior::default(), {},
- prismarine_stairs => BlockBehavior::default(), {
+ prismarine => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ prismarine_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ dark_prismarine => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ prismarine_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- prismarine_brick_stairs => BlockBehavior::default(), {
+ prismarine_brick_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- dark_prismarine_stairs => BlockBehavior::default(), {
+ dark_prismarine_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- prismarine_slab => BlockBehavior::default(), {
+ prismarine_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- prismarine_brick_slab => BlockBehavior::default(), {
+ prismarine_brick_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- dark_prismarine_slab => BlockBehavior::default(), {
+ dark_prismarine_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- sea_lantern => BlockBehavior::default(), {},
- hay_block => BlockBehavior::default(), {
+ sea_lantern => BlockBehavior::new().strength(0.3, 0.3), {},
+ hay_block => BlockBehavior::new().strength(0.5, 0.5), {
axis: Axis::Y,
},
- white_carpet => BlockBehavior::default(), {},
- orange_carpet => BlockBehavior::default(), {},
- magenta_carpet => BlockBehavior::default(), {},
- light_blue_carpet => BlockBehavior::default(), {},
- yellow_carpet => BlockBehavior::default(), {},
- lime_carpet => BlockBehavior::default(), {},
- pink_carpet => BlockBehavior::default(), {},
- gray_carpet => BlockBehavior::default(), {},
- light_gray_carpet => BlockBehavior::default(), {},
- cyan_carpet => BlockBehavior::default(), {},
- purple_carpet => BlockBehavior::default(), {},
- blue_carpet => BlockBehavior::default(), {},
- brown_carpet => BlockBehavior::default(), {},
- green_carpet => BlockBehavior::default(), {},
- red_carpet => BlockBehavior::default(), {},
- black_carpet => BlockBehavior::default(), {},
- terracotta => BlockBehavior::default(), {},
- coal_block => BlockBehavior::default(), {},
- packed_ice => BlockBehavior::default(), {},
- sunflower => BlockBehavior::default(), {
+ white_carpet => BlockBehavior::new().strength(0.1, 0.1), {},
+ orange_carpet => BlockBehavior::new().strength(0.1, 0.1), {},
+ magenta_carpet => BlockBehavior::new().strength(0.1, 0.1), {},
+ light_blue_carpet => BlockBehavior::new().strength(0.1, 0.1), {},
+ yellow_carpet => BlockBehavior::new().strength(0.1, 0.1), {},
+ lime_carpet => BlockBehavior::new().strength(0.1, 0.1), {},
+ pink_carpet => BlockBehavior::new().strength(0.1, 0.1), {},
+ gray_carpet => BlockBehavior::new().strength(0.1, 0.1), {},
+ light_gray_carpet => BlockBehavior::new().strength(0.1, 0.1), {},
+ cyan_carpet => BlockBehavior::new().strength(0.1, 0.1), {},
+ purple_carpet => BlockBehavior::new().strength(0.1, 0.1), {},
+ blue_carpet => BlockBehavior::new().strength(0.1, 0.1), {},
+ brown_carpet => BlockBehavior::new().strength(0.1, 0.1), {},
+ green_carpet => BlockBehavior::new().strength(0.1, 0.1), {},
+ red_carpet => BlockBehavior::new().strength(0.1, 0.1), {},
+ black_carpet => BlockBehavior::new().strength(0.1, 0.1), {},
+ terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {},
+ coal_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 6.0), {},
+ packed_ice => BlockBehavior::new().strength(0.5, 0.5).friction(0.98), {},
+ sunflower => BlockBehavior::new(), {
half: Half::Lower,
},
- lilac => BlockBehavior::default(), {
+ lilac => BlockBehavior::new(), {
half: Half::Lower,
},
- rose_bush => BlockBehavior::default(), {
+ rose_bush => BlockBehavior::new(), {
half: Half::Lower,
},
- peony => BlockBehavior::default(), {
+ peony => BlockBehavior::new(), {
half: Half::Lower,
},
- tall_grass => BlockBehavior::default(), {
+ tall_grass => BlockBehavior::new(), {
half: Half::Lower,
},
- large_fern => BlockBehavior::default(), {
+ large_fern => BlockBehavior::new(), {
half: Half::Lower,
},
- white_banner => BlockBehavior::default(), {
+ white_banner => BlockBehavior::new().strength(1.0, 1.0), {
rotation: WhiteBannerRotation::_0,
},
- orange_banner => BlockBehavior::default(), {
+ orange_banner => BlockBehavior::new().strength(1.0, 1.0), {
rotation: OrangeBannerRotation::_0,
},
- magenta_banner => BlockBehavior::default(), {
+ magenta_banner => BlockBehavior::new().strength(1.0, 1.0), {
rotation: MagentaBannerRotation::_0,
},
- light_blue_banner => BlockBehavior::default(), {
+ light_blue_banner => BlockBehavior::new().strength(1.0, 1.0), {
rotation: LightBlueBannerRotation::_0,
},
- yellow_banner => BlockBehavior::default(), {
+ yellow_banner => BlockBehavior::new().strength(1.0, 1.0), {
rotation: YellowBannerRotation::_0,
},
- lime_banner => BlockBehavior::default(), {
+ lime_banner => BlockBehavior::new().strength(1.0, 1.0), {
rotation: LimeBannerRotation::_0,
},
- pink_banner => BlockBehavior::default(), {
+ pink_banner => BlockBehavior::new().strength(1.0, 1.0), {
rotation: PinkBannerRotation::_0,
},
- gray_banner => BlockBehavior::default(), {
+ gray_banner => BlockBehavior::new().strength(1.0, 1.0), {
rotation: GrayBannerRotation::_0,
},
- light_gray_banner => BlockBehavior::default(), {
+ light_gray_banner => BlockBehavior::new().strength(1.0, 1.0), {
rotation: LightGrayBannerRotation::_0,
},
- cyan_banner => BlockBehavior::default(), {
+ cyan_banner => BlockBehavior::new().strength(1.0, 1.0), {
rotation: CyanBannerRotation::_0,
},
- purple_banner => BlockBehavior::default(), {
+ purple_banner => BlockBehavior::new().strength(1.0, 1.0), {
rotation: PurpleBannerRotation::_0,
},
- blue_banner => BlockBehavior::default(), {
+ blue_banner => BlockBehavior::new().strength(1.0, 1.0), {
rotation: BlueBannerRotation::_0,
},
- brown_banner => BlockBehavior::default(), {
+ brown_banner => BlockBehavior::new().strength(1.0, 1.0), {
rotation: BrownBannerRotation::_0,
},
- green_banner => BlockBehavior::default(), {
+ green_banner => BlockBehavior::new().strength(1.0, 1.0), {
rotation: GreenBannerRotation::_0,
},
- red_banner => BlockBehavior::default(), {
+ red_banner => BlockBehavior::new().strength(1.0, 1.0), {
rotation: RedBannerRotation::_0,
},
- black_banner => BlockBehavior::default(), {
+ black_banner => BlockBehavior::new().strength(1.0, 1.0), {
rotation: BlackBannerRotation::_0,
},
- white_wall_banner => BlockBehavior::default(), {
+ white_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- orange_wall_banner => BlockBehavior::default(), {
+ orange_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- magenta_wall_banner => BlockBehavior::default(), {
+ magenta_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- light_blue_wall_banner => BlockBehavior::default(), {
+ light_blue_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- yellow_wall_banner => BlockBehavior::default(), {
+ yellow_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- lime_wall_banner => BlockBehavior::default(), {
+ lime_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- pink_wall_banner => BlockBehavior::default(), {
+ pink_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- gray_wall_banner => BlockBehavior::default(), {
+ gray_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- light_gray_wall_banner => BlockBehavior::default(), {
+ light_gray_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- cyan_wall_banner => BlockBehavior::default(), {
+ cyan_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- purple_wall_banner => BlockBehavior::default(), {
+ purple_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- blue_wall_banner => BlockBehavior::default(), {
+ blue_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- brown_wall_banner => BlockBehavior::default(), {
+ brown_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- green_wall_banner => BlockBehavior::default(), {
+ green_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- red_wall_banner => BlockBehavior::default(), {
+ red_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- black_wall_banner => BlockBehavior::default(), {
+ black_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
},
- red_sandstone => BlockBehavior::default(), {},
- chiseled_red_sandstone => BlockBehavior::default(), {},
- cut_red_sandstone => BlockBehavior::default(), {},
- red_sandstone_stairs => BlockBehavior::default(), {
+ red_sandstone => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8), {},
+ chiseled_red_sandstone => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8), {},
+ cut_red_sandstone => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8), {},
+ red_sandstone_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- oak_slab => BlockBehavior::default(), {
+ oak_slab => BlockBehavior::new().strength(2.0, 3.0), {
kind: Type::Bottom,
waterlogged: false,
},
- spruce_slab => BlockBehavior::default(), {
+ spruce_slab => BlockBehavior::new().strength(2.0, 3.0), {
kind: Type::Bottom,
waterlogged: false,
},
- birch_slab => BlockBehavior::default(), {
+ birch_slab => BlockBehavior::new().strength(2.0, 3.0), {
kind: Type::Bottom,
waterlogged: false,
},
- jungle_slab => BlockBehavior::default(), {
+ jungle_slab => BlockBehavior::new().strength(2.0, 3.0), {
kind: Type::Bottom,
waterlogged: false,
},
- acacia_slab => BlockBehavior::default(), {
+ acacia_slab => BlockBehavior::new().strength(2.0, 3.0), {
kind: Type::Bottom,
waterlogged: false,
},
- cherry_slab => BlockBehavior::default(), {
+ cherry_slab => BlockBehavior::new().strength(2.0, 3.0), {
kind: Type::Bottom,
waterlogged: false,
},
- dark_oak_slab => BlockBehavior::default(), {
+ dark_oak_slab => BlockBehavior::new().strength(2.0, 3.0), {
kind: Type::Bottom,
waterlogged: false,
},
- mangrove_slab => BlockBehavior::default(), {
+ mangrove_slab => BlockBehavior::new().strength(2.0, 3.0), {
kind: Type::Bottom,
waterlogged: false,
},
- bamboo_slab => BlockBehavior::default(), {
+ bamboo_slab => BlockBehavior::new().strength(2.0, 3.0), {
kind: Type::Bottom,
waterlogged: false,
},
- bamboo_mosaic_slab => BlockBehavior::default(), {
+ bamboo_mosaic_slab => BlockBehavior::new().strength(2.0, 3.0), {
kind: Type::Bottom,
waterlogged: false,
},
- stone_slab => BlockBehavior::default(), {
+ stone_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- smooth_stone_slab => BlockBehavior::default(), {
+ smooth_stone_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- sandstone_slab => BlockBehavior::default(), {
+ sandstone_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- cut_sandstone_slab => BlockBehavior::default(), {
+ cut_sandstone_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- petrified_oak_slab => BlockBehavior::default(), {
+ petrified_oak_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- cobblestone_slab => BlockBehavior::default(), {
+ cobblestone_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- brick_slab => BlockBehavior::default(), {
+ brick_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- stone_brick_slab => BlockBehavior::default(), {
+ stone_brick_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- mud_brick_slab => BlockBehavior::default(), {
+ mud_brick_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 3.0), {
kind: Type::Bottom,
waterlogged: false,
},
- nether_brick_slab => BlockBehavior::default(), {
+ nether_brick_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- quartz_slab => BlockBehavior::default(), {
+ quartz_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- red_sandstone_slab => BlockBehavior::default(), {
+ red_sandstone_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- cut_red_sandstone_slab => BlockBehavior::default(), {
+ cut_red_sandstone_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- purpur_slab => BlockBehavior::default(), {
+ purpur_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- smooth_stone => BlockBehavior::default(), {},
- smooth_sandstone => BlockBehavior::default(), {},
- smooth_quartz => BlockBehavior::default(), {},
- smooth_red_sandstone => BlockBehavior::default(), {},
- spruce_fence_gate => BlockBehavior::default(), {
+ smooth_stone => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {},
+ smooth_sandstone => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {},
+ smooth_quartz => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {},
+ smooth_red_sandstone => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {},
+ spruce_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
in_wall: false,
open: false,
powered: false,
},
- birch_fence_gate => BlockBehavior::default(), {
+ birch_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
in_wall: false,
open: false,
powered: false,
},
- jungle_fence_gate => BlockBehavior::default(), {
+ jungle_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
in_wall: false,
open: false,
powered: false,
},
- acacia_fence_gate => BlockBehavior::default(), {
+ acacia_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
in_wall: false,
open: false,
powered: false,
},
- cherry_fence_gate => BlockBehavior::default(), {
+ cherry_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
in_wall: false,
open: false,
powered: false,
},
- dark_oak_fence_gate => BlockBehavior::default(), {
+ dark_oak_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
in_wall: false,
open: false,
powered: false,
},
- mangrove_fence_gate => BlockBehavior::default(), {
+ mangrove_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
in_wall: false,
open: false,
powered: false,
},
- bamboo_fence_gate => BlockBehavior::default(), {
+ bamboo_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
in_wall: false,
open: false,
powered: false,
},
- spruce_fence => BlockBehavior::default(), {
+ spruce_fence => BlockBehavior::new().strength(2.0, 3.0), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- birch_fence => BlockBehavior::default(), {
+ birch_fence => BlockBehavior::new().strength(2.0, 3.0), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- jungle_fence => BlockBehavior::default(), {
+ jungle_fence => BlockBehavior::new().strength(2.0, 3.0), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- acacia_fence => BlockBehavior::default(), {
+ acacia_fence => BlockBehavior::new().strength(2.0, 3.0), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- cherry_fence => BlockBehavior::default(), {
+ cherry_fence => BlockBehavior::new().strength(2.0, 3.0), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- dark_oak_fence => BlockBehavior::default(), {
+ dark_oak_fence => BlockBehavior::new().strength(2.0, 3.0), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- mangrove_fence => BlockBehavior::default(), {
+ mangrove_fence => BlockBehavior::new().strength(2.0, 3.0), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- bamboo_fence => BlockBehavior::default(), {
+ bamboo_fence => BlockBehavior::new().strength(2.0, 3.0), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- spruce_door => BlockBehavior::default(), {
+ spruce_door => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: Half::Lower,
hinge: Hinge::Left,
open: false,
powered: false,
},
- birch_door => BlockBehavior::default(), {
+ birch_door => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: Half::Lower,
hinge: Hinge::Left,
open: false,
powered: false,
},
- jungle_door => BlockBehavior::default(), {
+ jungle_door => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: Half::Lower,
hinge: Hinge::Left,
open: false,
powered: false,
},
- acacia_door => BlockBehavior::default(), {
+ acacia_door => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: Half::Lower,
hinge: Hinge::Left,
open: false,
powered: false,
},
- cherry_door => BlockBehavior::default(), {
+ cherry_door => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: Half::Lower,
hinge: Hinge::Left,
open: false,
powered: false,
},
- dark_oak_door => BlockBehavior::default(), {
+ dark_oak_door => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: Half::Lower,
hinge: Hinge::Left,
open: false,
powered: false,
},
- mangrove_door => BlockBehavior::default(), {
+ mangrove_door => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: Half::Lower,
hinge: Hinge::Left,
open: false,
powered: false,
},
- bamboo_door => BlockBehavior::default(), {
+ bamboo_door => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: Half::Lower,
hinge: Hinge::Left,
open: false,
powered: false,
},
- end_rod => BlockBehavior::default(), {
+ end_rod => BlockBehavior::new(), {
facing: FacingCubic::Up,
},
- chorus_plant => BlockBehavior::default(), {
+ chorus_plant => BlockBehavior::new().strength(0.4, 0.4), {
down: false,
east: false,
north: false,
@@ -3803,467 +3803,467 @@ make_block_states! {
up: false,
west: false,
},
- chorus_flower => BlockBehavior::default(), {
+ chorus_flower => BlockBehavior::new().strength(0.4, 0.4), {
age: ChorusFlowerAge::_0,
},
- purpur_block => BlockBehavior::default(), {},
- purpur_pillar => BlockBehavior::default(), {
+ purpur_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ purpur_pillar => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
axis: Axis::Y,
},
- purpur_stairs => BlockBehavior::default(), {
+ purpur_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- end_stone_bricks => BlockBehavior::default(), {},
- torchflower_crop => BlockBehavior::default(), {
+ end_stone_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 9.0), {},
+ torchflower_crop => BlockBehavior::new(), {
age: TorchflowerCropAge::_0,
},
- pitcher_crop => BlockBehavior::default(), {
+ pitcher_crop => BlockBehavior::new(), {
age: _0_1_2_3_4::_0,
half: UpperLower::Lower,
},
- pitcher_plant => BlockBehavior::default(), {
+ pitcher_plant => BlockBehavior::new(), {
half: Half::Lower,
},
- beetroots => BlockBehavior::default(), {
+ beetroots => BlockBehavior::new(), {
age: BeetrootsAge::_0,
},
- dirt_path => BlockBehavior::default(), {},
- end_gateway => BlockBehavior::default(), {},
- repeating_command_block => BlockBehavior::default(), {
+ dirt_path => BlockBehavior::new().strength(0.65, 0.65), {},
+ end_gateway => BlockBehavior::new().strength(-1.0, 3600000.0), {},
+ repeating_command_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(-1.0, 3600000.0), {
conditional: false,
facing: FacingCubic::North,
},
- chain_command_block => BlockBehavior::default(), {
+ chain_command_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(-1.0, 3600000.0), {
conditional: false,
facing: FacingCubic::North,
},
- frosted_ice => BlockBehavior::default(), {
+ frosted_ice => BlockBehavior::new().strength(0.5, 0.5).friction(0.98), {
age: FrostedIceAge::_0,
},
- magma_block => BlockBehavior::default(), {},
- nether_wart_block => BlockBehavior::default(), {},
- red_nether_bricks => BlockBehavior::default(), {},
- bone_block => BlockBehavior::default(), {
+ magma_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.5, 0.5), {},
+ nether_wart_block => BlockBehavior::new().strength(1.0, 1.0), {},
+ red_nether_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {},
+ bone_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 2.0), {
axis: Axis::Y,
},
- structure_void => BlockBehavior::default(), {},
- observer => BlockBehavior::default(), {
+ structure_void => BlockBehavior::new(), {},
+ observer => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 3.0), {
facing: FacingCubic::South,
powered: false,
},
- shulker_box => BlockBehavior::default(), {
+ shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
facing: FacingCubic::Up,
},
- white_shulker_box => BlockBehavior::default(), {
+ white_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
facing: FacingCubic::Up,
},
- orange_shulker_box => BlockBehavior::default(), {
+ orange_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
facing: FacingCubic::Up,
},
- magenta_shulker_box => BlockBehavior::default(), {
+ magenta_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
facing: FacingCubic::Up,
},
- light_blue_shulker_box => BlockBehavior::default(), {
+ light_blue_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
facing: FacingCubic::Up,
},
- yellow_shulker_box => BlockBehavior::default(), {
+ yellow_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
facing: FacingCubic::Up,
},
- lime_shulker_box => BlockBehavior::default(), {
+ lime_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
facing: FacingCubic::Up,
},
- pink_shulker_box => BlockBehavior::default(), {
+ pink_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
facing: FacingCubic::Up,
},
- gray_shulker_box => BlockBehavior::default(), {
+ gray_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
facing: FacingCubic::Up,
},
- light_gray_shulker_box => BlockBehavior::default(), {
+ light_gray_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
facing: FacingCubic::Up,
},
- cyan_shulker_box => BlockBehavior::default(), {
+ cyan_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
facing: FacingCubic::Up,
},
- purple_shulker_box => BlockBehavior::default(), {
+ purple_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
facing: FacingCubic::Up,
},
- blue_shulker_box => BlockBehavior::default(), {
+ blue_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
facing: FacingCubic::Up,
},
- brown_shulker_box => BlockBehavior::default(), {
+ brown_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
facing: FacingCubic::Up,
},
- green_shulker_box => BlockBehavior::default(), {
+ green_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
facing: FacingCubic::Up,
},
- red_shulker_box => BlockBehavior::default(), {
+ red_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
facing: FacingCubic::Up,
},
- black_shulker_box => BlockBehavior::default(), {
+ black_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
facing: FacingCubic::Up,
},
- white_glazed_terracotta => BlockBehavior::default(), {
+ white_glazed_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.4, 1.4), {
facing: FacingCardinal::North,
},
- orange_glazed_terracotta => BlockBehavior::default(), {
+ orange_glazed_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.4, 1.4), {
facing: FacingCardinal::North,
},
- magenta_glazed_terracotta => BlockBehavior::default(), {
+ magenta_glazed_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.4, 1.4), {
facing: FacingCardinal::North,
},
- light_blue_glazed_terracotta => BlockBehavior::default(), {
+ light_blue_glazed_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.4, 1.4), {
facing: FacingCardinal::North,
},
- yellow_glazed_terracotta => BlockBehavior::default(), {
+ yellow_glazed_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.4, 1.4), {
facing: FacingCardinal::North,
},
- lime_glazed_terracotta => BlockBehavior::default(), {
+ lime_glazed_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.4, 1.4), {
facing: FacingCardinal::North,
},
- pink_glazed_terracotta => BlockBehavior::default(), {
+ pink_glazed_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.4, 1.4), {
facing: FacingCardinal::North,
},
- gray_glazed_terracotta => BlockBehavior::default(), {
+ gray_glazed_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.4, 1.4), {
facing: FacingCardinal::North,
},
- light_gray_glazed_terracotta => BlockBehavior::default(), {
+ light_gray_glazed_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.4, 1.4), {
facing: FacingCardinal::North,
},
- cyan_glazed_terracotta => BlockBehavior::default(), {
+ cyan_glazed_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.4, 1.4), {
facing: FacingCardinal::North,
},
- purple_glazed_terracotta => BlockBehavior::default(), {
+ purple_glazed_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.4, 1.4), {
facing: FacingCardinal::North,
},
- blue_glazed_terracotta => BlockBehavior::default(), {
+ blue_glazed_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.4, 1.4), {
facing: FacingCardinal::North,
},
- brown_glazed_terracotta => BlockBehavior::default(), {
+ brown_glazed_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.4, 1.4), {
facing: FacingCardinal::North,
},
- green_glazed_terracotta => BlockBehavior::default(), {
+ green_glazed_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.4, 1.4), {
facing: FacingCardinal::North,
},
- red_glazed_terracotta => BlockBehavior::default(), {
+ red_glazed_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.4, 1.4), {
facing: FacingCardinal::North,
},
- black_glazed_terracotta => BlockBehavior::default(), {
+ black_glazed_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.4, 1.4), {
facing: FacingCardinal::North,
},
- white_concrete => BlockBehavior::default(), {},
- orange_concrete => BlockBehavior::default(), {},
- magenta_concrete => BlockBehavior::default(), {},
- light_blue_concrete => BlockBehavior::default(), {},
- yellow_concrete => BlockBehavior::default(), {},
- lime_concrete => BlockBehavior::default(), {},
- pink_concrete => BlockBehavior::default(), {},
- gray_concrete => BlockBehavior::default(), {},
- light_gray_concrete => BlockBehavior::default(), {},
- cyan_concrete => BlockBehavior::default(), {},
- purple_concrete => BlockBehavior::default(), {},
- blue_concrete => BlockBehavior::default(), {},
- brown_concrete => BlockBehavior::default(), {},
- green_concrete => BlockBehavior::default(), {},
- red_concrete => BlockBehavior::default(), {},
- black_concrete => BlockBehavior::default(), {},
- white_concrete_powder => BlockBehavior::default(), {},
- orange_concrete_powder => BlockBehavior::default(), {},
- magenta_concrete_powder => BlockBehavior::default(), {},
- light_blue_concrete_powder => BlockBehavior::default(), {},
- yellow_concrete_powder => BlockBehavior::default(), {},
- lime_concrete_powder => BlockBehavior::default(), {},
- pink_concrete_powder => BlockBehavior::default(), {},
- gray_concrete_powder => BlockBehavior::default(), {},
- light_gray_concrete_powder => BlockBehavior::default(), {},
- cyan_concrete_powder => BlockBehavior::default(), {},
- purple_concrete_powder => BlockBehavior::default(), {},
- blue_concrete_powder => BlockBehavior::default(), {},
- brown_concrete_powder => BlockBehavior::default(), {},
- green_concrete_powder => BlockBehavior::default(), {},
- red_concrete_powder => BlockBehavior::default(), {},
- black_concrete_powder => BlockBehavior::default(), {},
- kelp => BlockBehavior::default(), {
+ white_concrete => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.8, 1.8), {},
+ orange_concrete => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.8, 1.8), {},
+ magenta_concrete => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.8, 1.8), {},
+ light_blue_concrete => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.8, 1.8), {},
+ yellow_concrete => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.8, 1.8), {},
+ lime_concrete => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.8, 1.8), {},
+ pink_concrete => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.8, 1.8), {},
+ gray_concrete => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.8, 1.8), {},
+ light_gray_concrete => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.8, 1.8), {},
+ cyan_concrete => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.8, 1.8), {},
+ purple_concrete => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.8, 1.8), {},
+ blue_concrete => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.8, 1.8), {},
+ brown_concrete => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.8, 1.8), {},
+ green_concrete => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.8, 1.8), {},
+ red_concrete => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.8, 1.8), {},
+ black_concrete => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.8, 1.8), {},
+ white_concrete_powder => BlockBehavior::new().strength(0.5, 0.5), {},
+ orange_concrete_powder => BlockBehavior::new().strength(0.5, 0.5), {},
+ magenta_concrete_powder => BlockBehavior::new().strength(0.5, 0.5), {},
+ light_blue_concrete_powder => BlockBehavior::new().strength(0.5, 0.5), {},
+ yellow_concrete_powder => BlockBehavior::new().strength(0.5, 0.5), {},
+ lime_concrete_powder => BlockBehavior::new().strength(0.5, 0.5), {},
+ pink_concrete_powder => BlockBehavior::new().strength(0.5, 0.5), {},
+ gray_concrete_powder => BlockBehavior::new().strength(0.5, 0.5), {},
+ light_gray_concrete_powder => BlockBehavior::new().strength(0.5, 0.5), {},
+ cyan_concrete_powder => BlockBehavior::new().strength(0.5, 0.5), {},
+ purple_concrete_powder => BlockBehavior::new().strength(0.5, 0.5), {},
+ blue_concrete_powder => BlockBehavior::new().strength(0.5, 0.5), {},
+ brown_concrete_powder => BlockBehavior::new().strength(0.5, 0.5), {},
+ green_concrete_powder => BlockBehavior::new().strength(0.5, 0.5), {},
+ red_concrete_powder => BlockBehavior::new().strength(0.5, 0.5), {},
+ black_concrete_powder => BlockBehavior::new().strength(0.5, 0.5), {},
+ kelp => BlockBehavior::new(), {
age: KelpAge::_0,
},
- kelp_plant => BlockBehavior::default(), {},
- dried_kelp_block => BlockBehavior::default(), {},
- turtle_egg => BlockBehavior::default(), {
+ kelp_plant => BlockBehavior::new(), {},
+ dried_kelp_block => BlockBehavior::new().strength(0.5, 2.5), {},
+ turtle_egg => BlockBehavior::new().strength(0.5, 0.5), {
eggs: TurtleEggEggs::_1,
hatch: TurtleEggHatch::_0,
},
- sniffer_egg => BlockBehavior::default(), {
- age: SnifferEggAge::_0,
- },
- dead_tube_coral_block => BlockBehavior::default(), {},
- dead_brain_coral_block => BlockBehavior::default(), {},
- dead_bubble_coral_block => BlockBehavior::default(), {},
- dead_fire_coral_block => BlockBehavior::default(), {},
- dead_horn_coral_block => BlockBehavior::default(), {},
- tube_coral_block => BlockBehavior::default(), {},
- brain_coral_block => BlockBehavior::default(), {},
- bubble_coral_block => BlockBehavior::default(), {},
- fire_coral_block => BlockBehavior::default(), {},
- horn_coral_block => BlockBehavior::default(), {},
- dead_tube_coral => BlockBehavior::default(), {
+ sniffer_egg => BlockBehavior::new().strength(0.5, 0.5), {
+ hatch: SnifferEggHatch::_0,
+ },
+ dead_tube_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ dead_brain_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ dead_bubble_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ dead_fire_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ dead_horn_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ tube_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ brain_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ bubble_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ fire_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ horn_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ dead_tube_coral => BlockBehavior::new().requires_correct_tool_for_drops(), {
waterlogged: true,
},
- dead_brain_coral => BlockBehavior::default(), {
+ dead_brain_coral => BlockBehavior::new().requires_correct_tool_for_drops(), {
waterlogged: true,
},
- dead_bubble_coral => BlockBehavior::default(), {
+ dead_bubble_coral => BlockBehavior::new().requires_correct_tool_for_drops(), {
waterlogged: true,
},
- dead_fire_coral => BlockBehavior::default(), {
+ dead_fire_coral => BlockBehavior::new().requires_correct_tool_for_drops(), {
waterlogged: true,
},
- dead_horn_coral => BlockBehavior::default(), {
+ dead_horn_coral => BlockBehavior::new().requires_correct_tool_for_drops(), {
waterlogged: true,
},
- tube_coral => BlockBehavior::default(), {
+ tube_coral => BlockBehavior::new(), {
waterlogged: true,
},
- brain_coral => BlockBehavior::default(), {
+ brain_coral => BlockBehavior::new(), {
waterlogged: true,
},
- bubble_coral => BlockBehavior::default(), {
+ bubble_coral => BlockBehavior::new(), {
waterlogged: true,
},
- fire_coral => BlockBehavior::default(), {
+ fire_coral => BlockBehavior::new(), {
waterlogged: true,
},
- horn_coral => BlockBehavior::default(), {
+ horn_coral => BlockBehavior::new(), {
waterlogged: true,
},
- dead_tube_coral_fan => BlockBehavior::default(), {
+ dead_tube_coral_fan => BlockBehavior::new().requires_correct_tool_for_drops(), {
waterlogged: true,
},
- dead_brain_coral_fan => BlockBehavior::default(), {
+ dead_brain_coral_fan => BlockBehavior::new().requires_correct_tool_for_drops(), {
waterlogged: true,
},
- dead_bubble_coral_fan => BlockBehavior::default(), {
+ dead_bubble_coral_fan => BlockBehavior::new().requires_correct_tool_for_drops(), {
waterlogged: true,
},
- dead_fire_coral_fan => BlockBehavior::default(), {
+ dead_fire_coral_fan => BlockBehavior::new().requires_correct_tool_for_drops(), {
waterlogged: true,
},
- dead_horn_coral_fan => BlockBehavior::default(), {
+ dead_horn_coral_fan => BlockBehavior::new().requires_correct_tool_for_drops(), {
waterlogged: true,
},
- tube_coral_fan => BlockBehavior::default(), {
+ tube_coral_fan => BlockBehavior::new(), {
waterlogged: true,
},
- brain_coral_fan => BlockBehavior::default(), {
+ brain_coral_fan => BlockBehavior::new(), {
waterlogged: true,
},
- bubble_coral_fan => BlockBehavior::default(), {
+ bubble_coral_fan => BlockBehavior::new(), {
waterlogged: true,
},
- fire_coral_fan => BlockBehavior::default(), {
+ fire_coral_fan => BlockBehavior::new(), {
waterlogged: true,
},
- horn_coral_fan => BlockBehavior::default(), {
+ horn_coral_fan => BlockBehavior::new(), {
waterlogged: true,
},
- dead_tube_coral_wall_fan => BlockBehavior::default(), {
+ dead_tube_coral_wall_fan => BlockBehavior::new().requires_correct_tool_for_drops(), {
facing: FacingCardinal::North,
waterlogged: true,
},
- dead_brain_coral_wall_fan => BlockBehavior::default(), {
+ dead_brain_coral_wall_fan => BlockBehavior::new().requires_correct_tool_for_drops(), {
facing: FacingCardinal::North,
waterlogged: true,
},
- dead_bubble_coral_wall_fan => BlockBehavior::default(), {
+ dead_bubble_coral_wall_fan => BlockBehavior::new().requires_correct_tool_for_drops(), {
facing: FacingCardinal::North,
waterlogged: true,
},
- dead_fire_coral_wall_fan => BlockBehavior::default(), {
+ dead_fire_coral_wall_fan => BlockBehavior::new().requires_correct_tool_for_drops(), {
facing: FacingCardinal::North,
waterlogged: true,
},
- dead_horn_coral_wall_fan => BlockBehavior::default(), {
+ dead_horn_coral_wall_fan => BlockBehavior::new().requires_correct_tool_for_drops(), {
facing: FacingCardinal::North,
waterlogged: true,
},
- tube_coral_wall_fan => BlockBehavior::default(), {
+ tube_coral_wall_fan => BlockBehavior::new(), {
facing: FacingCardinal::North,
waterlogged: true,
},
- brain_coral_wall_fan => BlockBehavior::default(), {
+ brain_coral_wall_fan => BlockBehavior::new(), {
facing: FacingCardinal::North,
waterlogged: true,
},
- bubble_coral_wall_fan => BlockBehavior::default(), {
+ bubble_coral_wall_fan => BlockBehavior::new(), {
facing: FacingCardinal::North,
waterlogged: true,
},
- fire_coral_wall_fan => BlockBehavior::default(), {
+ fire_coral_wall_fan => BlockBehavior::new(), {
facing: FacingCardinal::North,
waterlogged: true,
},
- horn_coral_wall_fan => BlockBehavior::default(), {
+ horn_coral_wall_fan => BlockBehavior::new(), {
facing: FacingCardinal::North,
waterlogged: true,
},
- sea_pickle => BlockBehavior::default(), {
+ sea_pickle => BlockBehavior::new(), {
pickles: SeaPicklePickles::_1,
waterlogged: true,
},
- blue_ice => BlockBehavior::default(), {},
- conduit => BlockBehavior::default(), {
+ blue_ice => BlockBehavior::new().strength(2.8, 2.8).friction(0.989), {},
+ conduit => BlockBehavior::new().strength(3.0, 3.0), {
waterlogged: true,
},
- bamboo_sapling => BlockBehavior::default(), {},
- bamboo => BlockBehavior::default(), {
+ bamboo_sapling => BlockBehavior::new().strength(1.0, 1.0), {},
+ bamboo => BlockBehavior::new().strength(1.0, 1.0), {
age: BambooAge::_0,
leaves: Leaves::None,
stage: BambooStage::_0,
},
- potted_bamboo => BlockBehavior::default(), {},
- void_air => BlockBehavior::default(), {},
- cave_air => BlockBehavior::default(), {},
- bubble_column => BlockBehavior::default(), {
+ potted_bamboo => BlockBehavior::new(), {},
+ void_air => BlockBehavior::new(), {},
+ cave_air => BlockBehavior::new(), {},
+ bubble_column => BlockBehavior::new(), {
drag: true,
},
- polished_granite_stairs => BlockBehavior::default(), {
+ polished_granite_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- smooth_red_sandstone_stairs => BlockBehavior::default(), {
+ smooth_red_sandstone_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- mossy_stone_brick_stairs => BlockBehavior::default(), {
+ mossy_stone_brick_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- polished_diorite_stairs => BlockBehavior::default(), {
+ polished_diorite_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- mossy_cobblestone_stairs => BlockBehavior::default(), {
+ mossy_cobblestone_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- end_stone_brick_stairs => BlockBehavior::default(), {
+ end_stone_brick_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 9.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- stone_stairs => BlockBehavior::default(), {
+ stone_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- smooth_sandstone_stairs => BlockBehavior::default(), {
+ smooth_sandstone_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- smooth_quartz_stairs => BlockBehavior::default(), {
+ smooth_quartz_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- granite_stairs => BlockBehavior::default(), {
+ granite_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- andesite_stairs => BlockBehavior::default(), {
+ andesite_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- red_nether_brick_stairs => BlockBehavior::default(), {
+ red_nether_brick_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- polished_andesite_stairs => BlockBehavior::default(), {
+ polished_andesite_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- diorite_stairs => BlockBehavior::default(), {
+ diorite_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- polished_granite_slab => BlockBehavior::default(), {
+ polished_granite_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- smooth_red_sandstone_slab => BlockBehavior::default(), {
+ smooth_red_sandstone_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- mossy_stone_brick_slab => BlockBehavior::default(), {
+ mossy_stone_brick_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- polished_diorite_slab => BlockBehavior::default(), {
+ polished_diorite_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- mossy_cobblestone_slab => BlockBehavior::default(), {
+ mossy_cobblestone_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- end_stone_brick_slab => BlockBehavior::default(), {
+ end_stone_brick_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 9.0), {
kind: Type::Bottom,
waterlogged: false,
},
- smooth_sandstone_slab => BlockBehavior::default(), {
+ smooth_sandstone_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- smooth_quartz_slab => BlockBehavior::default(), {
+ smooth_quartz_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- granite_slab => BlockBehavior::default(), {
+ granite_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- andesite_slab => BlockBehavior::default(), {
+ andesite_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- red_nether_brick_slab => BlockBehavior::default(), {
+ red_nether_brick_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- polished_andesite_slab => BlockBehavior::default(), {
+ polished_andesite_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- diorite_slab => BlockBehavior::default(), {
+ diorite_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- brick_wall => BlockBehavior::default(), {
+ brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -4271,7 +4271,7 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- prismarine_wall => BlockBehavior::default(), {
+ prismarine_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -4279,7 +4279,7 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- red_sandstone_wall => BlockBehavior::default(), {
+ red_sandstone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -4287,7 +4287,7 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- mossy_stone_brick_wall => BlockBehavior::default(), {
+ mossy_stone_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -4295,7 +4295,7 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- granite_wall => BlockBehavior::default(), {
+ granite_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -4303,7 +4303,7 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- stone_brick_wall => BlockBehavior::default(), {
+ stone_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -4311,7 +4311,7 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- mud_brick_wall => BlockBehavior::default(), {
+ mud_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 3.0), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -4319,7 +4319,7 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- nether_brick_wall => BlockBehavior::default(), {
+ nether_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -4327,7 +4327,7 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- andesite_wall => BlockBehavior::default(), {
+ andesite_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -4335,7 +4335,7 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- red_nether_brick_wall => BlockBehavior::default(), {
+ red_nether_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -4343,7 +4343,7 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- sandstone_wall => BlockBehavior::default(), {
+ sandstone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -4351,7 +4351,7 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- end_stone_brick_wall => BlockBehavior::default(), {
+ end_stone_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 9.0), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -4359,7 +4359,7 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- diorite_wall => BlockBehavior::default(), {
+ diorite_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -4367,259 +4367,259 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- scaffolding => BlockBehavior::default(), {
+ scaffolding => BlockBehavior::new(), {
bottom: false,
distance: ScaffoldingDistance::_7,
waterlogged: false,
},
- loom => BlockBehavior::default(), {
+ loom => BlockBehavior::new().strength(2.5, 2.5), {
facing: FacingCardinal::North,
},
- barrel => BlockBehavior::default(), {
+ barrel => BlockBehavior::new().strength(2.5, 2.5), {
facing: FacingCubic::North,
open: false,
},
- smoker => BlockBehavior::default(), {
+ smoker => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 3.5), {
facing: FacingCardinal::North,
lit: false,
},
- blast_furnace => BlockBehavior::default(), {
+ blast_furnace => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 3.5), {
facing: FacingCardinal::North,
lit: false,
},
- cartography_table => BlockBehavior::default(), {},
- fletching_table => BlockBehavior::default(), {},
- grindstone => BlockBehavior::default(), {
+ cartography_table => BlockBehavior::new().strength(2.5, 2.5), {},
+ fletching_table => BlockBehavior::new().strength(2.5, 2.5), {},
+ grindstone => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
face: Face::Wall,
facing: FacingCardinal::North,
},
- lectern => BlockBehavior::default(), {
+ lectern => BlockBehavior::new().strength(2.5, 2.5), {
facing: FacingCardinal::North,
has_book: false,
powered: false,
},
- smithing_table => BlockBehavior::default(), {},
- stonecutter => BlockBehavior::default(), {
+ smithing_table => BlockBehavior::new().strength(2.5, 2.5), {},
+ stonecutter => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 3.5), {
facing: FacingCardinal::North,
},
- bell => BlockBehavior::default(), {
+ bell => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 5.0), {
attachment: Attachment::Floor,
facing: FacingCardinal::North,
powered: false,
},
- lantern => BlockBehavior::default(), {
+ lantern => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 3.5), {
hanging: false,
waterlogged: false,
},
- soul_lantern => BlockBehavior::default(), {
+ soul_lantern => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 3.5), {
hanging: false,
waterlogged: false,
},
- campfire => BlockBehavior::default(), {
+ campfire => BlockBehavior::new().strength(2.0, 2.0), {
facing: FacingCardinal::North,
lit: true,
signal_fire: false,
waterlogged: false,
},
- soul_campfire => BlockBehavior::default(), {
+ soul_campfire => BlockBehavior::new().strength(2.0, 2.0), {
facing: FacingCardinal::North,
lit: true,
signal_fire: false,
waterlogged: false,
},
- sweet_berry_bush => BlockBehavior::default(), {
+ sweet_berry_bush => BlockBehavior::new(), {
age: SweetBerryBushAge::_0,
},
- warped_stem => BlockBehavior::default(), {
+ warped_stem => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_warped_stem => BlockBehavior::default(), {
+ stripped_warped_stem => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- warped_hyphae => BlockBehavior::default(), {
+ warped_hyphae => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_warped_hyphae => BlockBehavior::default(), {
+ stripped_warped_hyphae => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- warped_nylium => BlockBehavior::default(), {},
- warped_fungus => BlockBehavior::default(), {},
- warped_wart_block => BlockBehavior::default(), {},
- warped_roots => BlockBehavior::default(), {},
- nether_sprouts => BlockBehavior::default(), {},
- crimson_stem => BlockBehavior::default(), {
+ warped_nylium => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.4, 0.4), {},
+ warped_fungus => BlockBehavior::new(), {},
+ warped_wart_block => BlockBehavior::new().strength(1.0, 1.0), {},
+ warped_roots => BlockBehavior::new(), {},
+ nether_sprouts => BlockBehavior::new(), {},
+ crimson_stem => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_crimson_stem => BlockBehavior::default(), {
+ stripped_crimson_stem => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- crimson_hyphae => BlockBehavior::default(), {
+ crimson_hyphae => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- stripped_crimson_hyphae => BlockBehavior::default(), {
+ stripped_crimson_hyphae => BlockBehavior::new().strength(2.0, 2.0), {
axis: Axis::Y,
},
- crimson_nylium => BlockBehavior::default(), {},
- crimson_fungus => BlockBehavior::default(), {},
- shroomlight => BlockBehavior::default(), {},
- weeping_vines => BlockBehavior::default(), {
+ crimson_nylium => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.4, 0.4), {},
+ crimson_fungus => BlockBehavior::new(), {},
+ shroomlight => BlockBehavior::new().strength(1.0, 1.0), {},
+ weeping_vines => BlockBehavior::new(), {
age: WeepingVinesAge::_0,
},
- weeping_vines_plant => BlockBehavior::default(), {},
- twisting_vines => BlockBehavior::default(), {
+ weeping_vines_plant => BlockBehavior::new(), {},
+ twisting_vines => BlockBehavior::new(), {
age: TwistingVinesAge::_0,
},
- twisting_vines_plant => BlockBehavior::default(), {},
- crimson_roots => BlockBehavior::default(), {},
- crimson_planks => BlockBehavior::default(), {},
- warped_planks => BlockBehavior::default(), {},
- crimson_slab => BlockBehavior::default(), {
+ twisting_vines_plant => BlockBehavior::new(), {},
+ crimson_roots => BlockBehavior::new(), {},
+ crimson_planks => BlockBehavior::new().strength(2.0, 3.0), {},
+ warped_planks => BlockBehavior::new().strength(2.0, 3.0), {},
+ crimson_slab => BlockBehavior::new().strength(2.0, 3.0), {
kind: Type::Bottom,
waterlogged: false,
},
- warped_slab => BlockBehavior::default(), {
+ warped_slab => BlockBehavior::new().strength(2.0, 3.0), {
kind: Type::Bottom,
waterlogged: false,
},
- crimson_pressure_plate => BlockBehavior::default(), {
+ crimson_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
powered: false,
},
- warped_pressure_plate => BlockBehavior::default(), {
+ warped_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
powered: false,
},
- crimson_fence => BlockBehavior::default(), {
+ crimson_fence => BlockBehavior::new().strength(2.0, 3.0), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- warped_fence => BlockBehavior::default(), {
+ warped_fence => BlockBehavior::new().strength(2.0, 3.0), {
east: false,
north: false,
south: false,
waterlogged: false,
west: false,
},
- crimson_trapdoor => BlockBehavior::default(), {
+ crimson_trapdoor => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
open: false,
powered: false,
waterlogged: false,
},
- warped_trapdoor => BlockBehavior::default(), {
+ warped_trapdoor => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
open: false,
powered: false,
waterlogged: false,
},
- crimson_fence_gate => BlockBehavior::default(), {
+ crimson_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
in_wall: false,
open: false,
powered: false,
},
- warped_fence_gate => BlockBehavior::default(), {
+ warped_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
in_wall: false,
open: false,
powered: false,
},
- crimson_stairs => BlockBehavior::default(), {
+ crimson_stairs => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- warped_stairs => BlockBehavior::default(), {
+ warped_stairs => BlockBehavior::new().strength(2.0, 3.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- crimson_button => BlockBehavior::default(), {
+ crimson_button => BlockBehavior::new().strength(0.5, 0.5), {
face: Face::Wall,
facing: FacingCardinal::North,
powered: false,
},
- warped_button => BlockBehavior::default(), {
+ warped_button => BlockBehavior::new().strength(0.5, 0.5), {
face: Face::Wall,
facing: FacingCardinal::North,
powered: false,
},
- crimson_door => BlockBehavior::default(), {
+ crimson_door => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: Half::Lower,
hinge: Hinge::Left,
open: false,
powered: false,
},
- warped_door => BlockBehavior::default(), {
+ warped_door => BlockBehavior::new().strength(3.0, 3.0), {
facing: FacingCardinal::North,
half: Half::Lower,
hinge: Hinge::Left,
open: false,
powered: false,
},
- crimson_sign => BlockBehavior::default(), {
+ crimson_sign => BlockBehavior::new().strength(1.0, 1.0), {
rotation: CrimsonSignRotation::_0,
waterlogged: false,
},
- warped_sign => BlockBehavior::default(), {
+ warped_sign => BlockBehavior::new().strength(1.0, 1.0), {
rotation: WarpedSignRotation::_0,
waterlogged: false,
},
- crimson_wall_sign => BlockBehavior::default(), {
+ crimson_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- warped_wall_sign => BlockBehavior::default(), {
+ warped_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
facing: FacingCardinal::North,
waterlogged: false,
},
- structure_block => BlockBehavior::default(), {
+ structure_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(-1.0, 3600000.0), {
mode: Mode::Load,
},
- jigsaw => BlockBehavior::default(), {
+ jigsaw => BlockBehavior::new().requires_correct_tool_for_drops().strength(-1.0, 3600000.0), {
orientation: Orientation::NorthUp,
},
- composter => BlockBehavior::default(), {
+ composter => BlockBehavior::new().strength(0.6, 0.6), {
level: ComposterLevel::_0,
},
- target => BlockBehavior::default(), {
+ target => BlockBehavior::new().strength(0.5, 0.5), {
power: TargetOutputPower::_0,
},
- bee_nest => BlockBehavior::default(), {
+ bee_nest => BlockBehavior::new().strength(0.3, 0.3), {
facing: FacingCardinal::North,
honey_level: BeeNestHoneyLevel::_0,
},
- beehive => BlockBehavior::default(), {
+ beehive => BlockBehavior::new().strength(0.6, 0.6), {
facing: FacingCardinal::North,
honey_level: BeehiveHoneyLevel::_0,
},
- honey_block => BlockBehavior::default(), {},
- honeycomb_block => BlockBehavior::default(), {},
- netherite_block => BlockBehavior::default(), {},
- ancient_debris => BlockBehavior::default(), {},
- crying_obsidian => BlockBehavior::default(), {},
- respawn_anchor => BlockBehavior::default(), {
+ honey_block => BlockBehavior::new(), {},
+ honeycomb_block => BlockBehavior::new().strength(0.6, 0.6), {},
+ netherite_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(50.0, 1200.0), {},
+ ancient_debris => BlockBehavior::new().requires_correct_tool_for_drops().strength(30.0, 1200.0), {},
+ crying_obsidian => BlockBehavior::new().requires_correct_tool_for_drops().strength(50.0, 1200.0), {},
+ respawn_anchor => BlockBehavior::new().requires_correct_tool_for_drops().strength(50.0, 1200.0), {
charges: RespawnAnchorCharge::_0,
},
- potted_crimson_fungus => BlockBehavior::default(), {},
- potted_warped_fungus => BlockBehavior::default(), {},
- potted_crimson_roots => BlockBehavior::default(), {},
- potted_warped_roots => BlockBehavior::default(), {},
- lodestone => BlockBehavior::default(), {},
- blackstone => BlockBehavior::default(), {},
- blackstone_stairs => BlockBehavior::default(), {
+ potted_crimson_fungus => BlockBehavior::new(), {},
+ potted_warped_fungus => BlockBehavior::new(), {},
+ potted_crimson_roots => BlockBehavior::new(), {},
+ potted_warped_roots => BlockBehavior::new(), {},
+ lodestone => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 3.5), {},
+ blackstone => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ blackstone_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- blackstone_wall => BlockBehavior::default(), {
+ blackstone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -4627,25 +4627,25 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- blackstone_slab => BlockBehavior::default(), {
+ blackstone_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- polished_blackstone => BlockBehavior::default(), {},
- polished_blackstone_bricks => BlockBehavior::default(), {},
- cracked_polished_blackstone_bricks => BlockBehavior::default(), {},
- chiseled_polished_blackstone => BlockBehavior::default(), {},
- polished_blackstone_brick_slab => BlockBehavior::default(), {
+ polished_blackstone => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {},
+ polished_blackstone_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ cracked_polished_blackstone_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ chiseled_polished_blackstone => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ polished_blackstone_brick_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- polished_blackstone_brick_stairs => BlockBehavior::default(), {
+ polished_blackstone_brick_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- polished_blackstone_brick_wall => BlockBehavior::default(), {
+ polished_blackstone_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -4653,26 +4653,26 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- gilded_blackstone => BlockBehavior::default(), {},
- polished_blackstone_stairs => BlockBehavior::default(), {
+ gilded_blackstone => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ polished_blackstone_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- polished_blackstone_slab => BlockBehavior::default(), {
+ polished_blackstone_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- polished_blackstone_pressure_plate => BlockBehavior::default(), {
+ polished_blackstone_pressure_plate => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.5, 0.5), {
powered: false,
},
- polished_blackstone_button => BlockBehavior::default(), {
+ polished_blackstone_button => BlockBehavior::new().strength(0.5, 0.5), {
face: Face::Wall,
facing: FacingCardinal::North,
powered: false,
},
- polished_blackstone_wall => BlockBehavior::default(), {
+ polished_blackstone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -4680,180 +4680,180 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- chiseled_nether_bricks => BlockBehavior::default(), {},
- cracked_nether_bricks => BlockBehavior::default(), {},
- quartz_bricks => BlockBehavior::default(), {},
- candle => BlockBehavior::default(), {
+ chiseled_nether_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {},
+ cracked_nether_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {},
+ quartz_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8), {},
+ candle => BlockBehavior::new().strength(0.1, 0.1), {
candles: CandleCandles::_1,
lit: false,
waterlogged: false,
},
- white_candle => BlockBehavior::default(), {
+ white_candle => BlockBehavior::new().strength(0.1, 0.1), {
candles: WhiteCandleCandles::_1,
lit: false,
waterlogged: false,
},
- orange_candle => BlockBehavior::default(), {
+ orange_candle => BlockBehavior::new().strength(0.1, 0.1), {
candles: OrangeCandleCandles::_1,
lit: false,
waterlogged: false,
},
- magenta_candle => BlockBehavior::default(), {
+ magenta_candle => BlockBehavior::new().strength(0.1, 0.1), {
candles: MagentaCandleCandles::_1,
lit: false,
waterlogged: false,
},
- light_blue_candle => BlockBehavior::default(), {
+ light_blue_candle => BlockBehavior::new().strength(0.1, 0.1), {
candles: LightBlueCandleCandles::_1,
lit: false,
waterlogged: false,
},
- yellow_candle => BlockBehavior::default(), {
+ yellow_candle => BlockBehavior::new().strength(0.1, 0.1), {
candles: YellowCandleCandles::_1,
lit: false,
waterlogged: false,
},
- lime_candle => BlockBehavior::default(), {
+ lime_candle => BlockBehavior::new().strength(0.1, 0.1), {
candles: LimeCandleCandles::_1,
lit: false,
waterlogged: false,
},
- pink_candle => BlockBehavior::default(), {
+ pink_candle => BlockBehavior::new().strength(0.1, 0.1), {
candles: PinkCandleCandles::_1,
lit: false,
waterlogged: false,
},
- gray_candle => BlockBehavior::default(), {
+ gray_candle => BlockBehavior::new().strength(0.1, 0.1), {
candles: GrayCandleCandles::_1,
lit: false,
waterlogged: false,
},
- light_gray_candle => BlockBehavior::default(), {
+ light_gray_candle => BlockBehavior::new().strength(0.1, 0.1), {
candles: LightGrayCandleCandles::_1,
lit: false,
waterlogged: false,
},
- cyan_candle => BlockBehavior::default(), {
+ cyan_candle => BlockBehavior::new().strength(0.1, 0.1), {
candles: CyanCandleCandles::_1,
lit: false,
waterlogged: false,
},
- purple_candle => BlockBehavior::default(), {
+ purple_candle => BlockBehavior::new().strength(0.1, 0.1), {
candles: PurpleCandleCandles::_1,
lit: false,
waterlogged: false,
},
- blue_candle => BlockBehavior::default(), {
+ blue_candle => BlockBehavior::new().strength(0.1, 0.1), {
candles: BlueCandleCandles::_1,
lit: false,
waterlogged: false,
},
- brown_candle => BlockBehavior::default(), {
+ brown_candle => BlockBehavior::new().strength(0.1, 0.1), {
candles: BrownCandleCandles::_1,
lit: false,
waterlogged: false,
},
- green_candle => BlockBehavior::default(), {
+ green_candle => BlockBehavior::new().strength(0.1, 0.1), {
candles: GreenCandleCandles::_1,
lit: false,
waterlogged: false,
},
- red_candle => BlockBehavior::default(), {
+ red_candle => BlockBehavior::new().strength(0.1, 0.1), {
candles: RedCandleCandles::_1,
lit: false,
waterlogged: false,
},
- black_candle => BlockBehavior::default(), {
+ black_candle => BlockBehavior::new().strength(0.1, 0.1), {
candles: BlackCandleCandles::_1,
lit: false,
waterlogged: false,
},
- candle_cake => BlockBehavior::default(), {
+ candle_cake => BlockBehavior::new().strength(0.5, 0.5), {
lit: false,
},
- white_candle_cake => BlockBehavior::default(), {
+ white_candle_cake => BlockBehavior::new().strength(0.5, 0.5), {
lit: false,
},
- orange_candle_cake => BlockBehavior::default(), {
+ orange_candle_cake => BlockBehavior::new().strength(0.5, 0.5), {
lit: false,
},
- magenta_candle_cake => BlockBehavior::default(), {
+ magenta_candle_cake => BlockBehavior::new().strength(0.5, 0.5), {
lit: false,
},
- light_blue_candle_cake => BlockBehavior::default(), {
+ light_blue_candle_cake => BlockBehavior::new().strength(0.5, 0.5), {
lit: false,
},
- yellow_candle_cake => BlockBehavior::default(), {
+ yellow_candle_cake => BlockBehavior::new().strength(0.5, 0.5), {
lit: false,
},
- lime_candle_cake => BlockBehavior::default(), {
+ lime_candle_cake => BlockBehavior::new().strength(0.5, 0.5), {
lit: false,
},
- pink_candle_cake => BlockBehavior::default(), {
+ pink_candle_cake => BlockBehavior::new().strength(0.5, 0.5), {
lit: false,
},
- gray_candle_cake => BlockBehavior::default(), {
+ gray_candle_cake => BlockBehavior::new().strength(0.5, 0.5), {
lit: false,
},
- light_gray_candle_cake => BlockBehavior::default(), {
+ light_gray_candle_cake => BlockBehavior::new().strength(0.5, 0.5), {
lit: false,
},
- cyan_candle_cake => BlockBehavior::default(), {
+ cyan_candle_cake => BlockBehavior::new().strength(0.5, 0.5), {
lit: false,
},
- purple_candle_cake => BlockBehavior::default(), {
+ purple_candle_cake => BlockBehavior::new().strength(0.5, 0.5), {
lit: false,
},
- blue_candle_cake => BlockBehavior::default(), {
+ blue_candle_cake => BlockBehavior::new().strength(0.5, 0.5), {
lit: false,
},
- brown_candle_cake => BlockBehavior::default(), {
+ brown_candle_cake => BlockBehavior::new().strength(0.5, 0.5), {
lit: false,
},
- green_candle_cake => BlockBehavior::default(), {
+ green_candle_cake => BlockBehavior::new().strength(0.5, 0.5), {
lit: false,
},
- red_candle_cake => BlockBehavior::default(), {
+ red_candle_cake => BlockBehavior::new().strength(0.5, 0.5), {
lit: false,
},
- black_candle_cake => BlockBehavior::default(), {
+ black_candle_cake => BlockBehavior::new().strength(0.5, 0.5), {
lit: false,
},
- amethyst_block => BlockBehavior::default(), {},
- budding_amethyst => BlockBehavior::default(), {},
- amethyst_cluster => BlockBehavior::default(), {
+ amethyst_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 1.5), {},
+ budding_amethyst => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 1.5), {},
+ amethyst_cluster => BlockBehavior::new().strength(1.5, 1.5), {
facing: FacingCubic::Up,
waterlogged: false,
},
- large_amethyst_bud => BlockBehavior::default(), {
+ large_amethyst_bud => BlockBehavior::new().strength(1.5, 1.5), {
facing: FacingCubic::Up,
waterlogged: false,
},
- medium_amethyst_bud => BlockBehavior::default(), {
+ medium_amethyst_bud => BlockBehavior::new().strength(1.5, 1.5), {
facing: FacingCubic::Up,
waterlogged: false,
},
- small_amethyst_bud => BlockBehavior::default(), {
+ small_amethyst_bud => BlockBehavior::new().strength(1.5, 1.5), {
facing: FacingCubic::Up,
waterlogged: false,
},
- tuff => BlockBehavior::default(), {},
- calcite => BlockBehavior::default(), {},
- tinted_glass => BlockBehavior::default(), {},
- powder_snow => BlockBehavior::default(), {},
- sculk_sensor => BlockBehavior::default(), {
+ tuff => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ calcite => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.75, 0.75), {},
+ tinted_glass => BlockBehavior::new().strength(0.3, 0.3), {},
+ powder_snow => BlockBehavior::new().strength(0.25, 0.25), {},
+ sculk_sensor => BlockBehavior::new().strength(1.5, 1.5), {
power: SculkSensorPower::_0,
sculk_sensor_phase: Phase::Inactive,
waterlogged: false,
},
- calibrated_sculk_sensor => BlockBehavior::default(), {
+ calibrated_sculk_sensor => BlockBehavior::new().strength(1.5, 1.5), {
facing: FacingCardinal::North,
power: CalibratedSculkSensorPower::_0,
sculk_sensor_phase: Phase::Inactive,
waterlogged: false,
},
- sculk => BlockBehavior::default(), {},
- sculk_vein => BlockBehavior::default(), {
+ sculk => BlockBehavior::new().strength(0.2, 0.2), {},
+ sculk_vein => BlockBehavior::new().strength(0.2, 0.2), {
down: false,
east: false,
north: false,
@@ -4862,173 +4862,173 @@ make_block_states! {
waterlogged: false,
west: false,
},
- sculk_catalyst => BlockBehavior::default(), {
+ sculk_catalyst => BlockBehavior::new().strength(3.0, 3.0), {
bloom: false,
},
- sculk_shrieker => BlockBehavior::default(), {
+ sculk_shrieker => BlockBehavior::new().strength(3.0, 3.0), {
can_summon: false,
shrieking: false,
waterlogged: false,
},
- oxidized_copper => BlockBehavior::default(), {},
- weathered_copper => BlockBehavior::default(), {},
- exposed_copper => BlockBehavior::default(), {},
- copper_block => BlockBehavior::default(), {},
- copper_ore => BlockBehavior::default(), {},
- deepslate_copper_ore => BlockBehavior::default(), {},
- oxidized_cut_copper => BlockBehavior::default(), {},
- weathered_cut_copper => BlockBehavior::default(), {},
- exposed_cut_copper => BlockBehavior::default(), {},
- cut_copper => BlockBehavior::default(), {},
- oxidized_cut_copper_stairs => BlockBehavior::default(), {
+ oxidized_copper => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {},
+ weathered_copper => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {},
+ exposed_copper => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {},
+ copper_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {},
+ copper_ore => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 3.0), {},
+ deepslate_copper_ore => BlockBehavior::new().requires_correct_tool_for_drops().strength(4.5, 3.0), {},
+ oxidized_cut_copper => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {},
+ weathered_cut_copper => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {},
+ exposed_cut_copper => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {},
+ cut_copper => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {},
+ oxidized_cut_copper_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- weathered_cut_copper_stairs => BlockBehavior::default(), {
+ weathered_cut_copper_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- exposed_cut_copper_stairs => BlockBehavior::default(), {
+ exposed_cut_copper_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- cut_copper_stairs => BlockBehavior::default(), {
+ cut_copper_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- oxidized_cut_copper_slab => BlockBehavior::default(), {
+ oxidized_cut_copper_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- weathered_cut_copper_slab => BlockBehavior::default(), {
+ weathered_cut_copper_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- exposed_cut_copper_slab => BlockBehavior::default(), {
+ exposed_cut_copper_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- cut_copper_slab => BlockBehavior::default(), {
+ cut_copper_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- waxed_copper_block => BlockBehavior::default(), {},
- waxed_weathered_copper => BlockBehavior::default(), {},
- waxed_exposed_copper => BlockBehavior::default(), {},
- waxed_oxidized_copper => BlockBehavior::default(), {},
- waxed_oxidized_cut_copper => BlockBehavior::default(), {},
- waxed_weathered_cut_copper => BlockBehavior::default(), {},
- waxed_exposed_cut_copper => BlockBehavior::default(), {},
- waxed_cut_copper => BlockBehavior::default(), {},
- waxed_oxidized_cut_copper_stairs => BlockBehavior::default(), {
+ waxed_copper_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {},
+ waxed_weathered_copper => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {},
+ waxed_exposed_copper => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {},
+ waxed_oxidized_copper => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {},
+ waxed_oxidized_cut_copper => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {},
+ waxed_weathered_cut_copper => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {},
+ waxed_exposed_cut_copper => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {},
+ waxed_cut_copper => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {},
+ waxed_oxidized_cut_copper_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- waxed_weathered_cut_copper_stairs => BlockBehavior::default(), {
+ waxed_weathered_cut_copper_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- waxed_exposed_cut_copper_stairs => BlockBehavior::default(), {
+ waxed_exposed_cut_copper_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- waxed_cut_copper_stairs => BlockBehavior::default(), {
+ waxed_cut_copper_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- waxed_oxidized_cut_copper_slab => BlockBehavior::default(), {
+ waxed_oxidized_cut_copper_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- waxed_weathered_cut_copper_slab => BlockBehavior::default(), {
+ waxed_weathered_cut_copper_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- waxed_exposed_cut_copper_slab => BlockBehavior::default(), {
+ waxed_exposed_cut_copper_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- waxed_cut_copper_slab => BlockBehavior::default(), {
+ waxed_cut_copper_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- lightning_rod => BlockBehavior::default(), {
+ lightning_rod => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {
facing: FacingCubic::Up,
powered: false,
waterlogged: false,
},
- pointed_dripstone => BlockBehavior::default(), {
+ pointed_dripstone => BlockBehavior::new().strength(1.5, 3.0), {
thickness: Thickness::Tip,
vertical_direction: TipDirection::Up,
waterlogged: false,
},
- dripstone_block => BlockBehavior::default(), {},
- cave_vines => BlockBehavior::default(), {
+ dripstone_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 1.0), {},
+ cave_vines => BlockBehavior::new(), {
age: CaveVinesAge::_0,
berries: false,
},
- cave_vines_plant => BlockBehavior::default(), {
+ cave_vines_plant => BlockBehavior::new(), {
berries: false,
},
- spore_blossom => BlockBehavior::default(), {},
- azalea => BlockBehavior::default(), {},
- flowering_azalea => BlockBehavior::default(), {},
- moss_carpet => BlockBehavior::default(), {},
- pink_petals => BlockBehavior::default(), {
+ spore_blossom => BlockBehavior::new(), {},
+ azalea => BlockBehavior::new(), {},
+ flowering_azalea => BlockBehavior::new(), {},
+ moss_carpet => BlockBehavior::new().strength(0.1, 0.1), {},
+ pink_petals => BlockBehavior::new(), {
facing: FacingCardinal::North,
flower_amount: PinkPetalsAmount::_1,
},
- moss_block => BlockBehavior::default(), {},
- big_dripleaf => BlockBehavior::default(), {
+ moss_block => BlockBehavior::new().strength(0.1, 0.1), {},
+ big_dripleaf => BlockBehavior::new().strength(0.1, 0.1), {
facing: FacingCardinal::North,
tilt: Tilt::None,
waterlogged: false,
},
- big_dripleaf_stem => BlockBehavior::default(), {
+ big_dripleaf_stem => BlockBehavior::new().strength(0.1, 0.1), {
facing: FacingCardinal::North,
waterlogged: false,
},
- small_dripleaf => BlockBehavior::default(), {
+ small_dripleaf => BlockBehavior::new(), {
facing: FacingCardinal::North,
half: Half::Lower,
waterlogged: false,
},
- hanging_roots => BlockBehavior::default(), {
+ hanging_roots => BlockBehavior::new(), {
waterlogged: false,
},
- rooted_dirt => BlockBehavior::default(), {},
- mud => BlockBehavior::default(), {},
- deepslate => BlockBehavior::default(), {
+ rooted_dirt => BlockBehavior::new().strength(0.5, 0.5), {},
+ mud => BlockBehavior::new().strength(0.5, 0.5), {},
+ deepslate => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {
axis: Axis::Y,
},
- cobbled_deepslate => BlockBehavior::default(), {},
- cobbled_deepslate_stairs => BlockBehavior::default(), {
+ cobbled_deepslate => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {},
+ cobbled_deepslate_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- cobbled_deepslate_slab => BlockBehavior::default(), {
+ cobbled_deepslate_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- cobbled_deepslate_wall => BlockBehavior::default(), {
+ cobbled_deepslate_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -5036,18 +5036,18 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- polished_deepslate => BlockBehavior::default(), {},
- polished_deepslate_stairs => BlockBehavior::default(), {
+ polished_deepslate => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {},
+ polished_deepslate_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- polished_deepslate_slab => BlockBehavior::default(), {
+ polished_deepslate_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- polished_deepslate_wall => BlockBehavior::default(), {
+ polished_deepslate_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -5055,18 +5055,18 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- deepslate_tiles => BlockBehavior::default(), {},
- deepslate_tile_stairs => BlockBehavior::default(), {
+ deepslate_tiles => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {},
+ deepslate_tile_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- deepslate_tile_slab => BlockBehavior::default(), {
+ deepslate_tile_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- deepslate_tile_wall => BlockBehavior::default(), {
+ deepslate_tile_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -5074,18 +5074,18 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- deepslate_bricks => BlockBehavior::default(), {},
- deepslate_brick_stairs => BlockBehavior::default(), {
+ deepslate_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {},
+ deepslate_brick_stairs => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {
facing: FacingCardinal::North,
half: TopBottom::Bottom,
shape: StairShape::Straight,
waterlogged: false,
},
- deepslate_brick_slab => BlockBehavior::default(), {
+ deepslate_brick_slab => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {
kind: Type::Bottom,
waterlogged: false,
},
- deepslate_brick_wall => BlockBehavior::default(), {
+ deepslate_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {
east: EastWall::None,
north: NorthWall::None,
south: SouthWall::None,
@@ -5093,30 +5093,30 @@ make_block_states! {
waterlogged: false,
west: WestWall::None,
},
- chiseled_deepslate => BlockBehavior::default(), {},
- cracked_deepslate_bricks => BlockBehavior::default(), {},
- cracked_deepslate_tiles => BlockBehavior::default(), {},
- infested_deepslate => BlockBehavior::default(), {
+ chiseled_deepslate => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {},
+ cracked_deepslate_bricks => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {},
+ cracked_deepslate_tiles => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {},
+ infested_deepslate => BlockBehavior::new().strength(1.5, 0.75), {
axis: CacheSize::Y,
},
- smooth_basalt => BlockBehavior::default(), {},
- raw_iron_block => BlockBehavior::default(), {},
- raw_copper_block => BlockBehavior::default(), {},
- raw_gold_block => BlockBehavior::default(), {},
- potted_azalea_bush => BlockBehavior::default(), {},
- potted_flowering_azalea_bush => BlockBehavior::default(), {},
- ochre_froglight => BlockBehavior::default(), {
+ smooth_basalt => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.25, 4.2), {},
+ raw_iron_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 6.0), {},
+ raw_copper_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 6.0), {},
+ raw_gold_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 6.0), {},
+ potted_azalea_bush => BlockBehavior::new(), {},
+ potted_flowering_azalea_bush => BlockBehavior::new(), {},
+ ochre_froglight => BlockBehavior::new().strength(0.3, 0.3), {
axis: Axis::Y,
},
- verdant_froglight => BlockBehavior::default(), {
+ verdant_froglight => BlockBehavior::new().strength(0.3, 0.3), {
axis: Axis::Y,
},
- pearlescent_froglight => BlockBehavior::default(), {
+ pearlescent_froglight => BlockBehavior::new().strength(0.3, 0.3), {
axis: Axis::Y,
},
- frogspawn => BlockBehavior::default(), {},
- reinforced_deepslate => BlockBehavior::default(), {},
- decorated_pot => BlockBehavior::default(), {
+ frogspawn => BlockBehavior::new(), {},
+ reinforced_deepslate => BlockBehavior::new().strength(55.0, 1200.0), {},
+ decorated_pot => BlockBehavior::new(), {
cracked: false,
facing: FacingCardinal::North,
waterlogged: false,
diff --git a/azalea-block/src/lib.rs b/azalea-block/src/lib.rs
index 43099db5..ef0041f1 100755
--- a/azalea-block/src/lib.rs
+++ b/azalea-block/src/lib.rs
@@ -24,6 +24,9 @@ pub trait Block: Debug + Any {
/// Convert the block to a block state. This is lossless, as the block
/// contains all the state data.
fn as_block_state(&self) -> BlockState;
+ /// Convert the block to an [`azalea_registry::Block`]. This is lossy, as
+ /// `azalea_registry::Block` doesn't contain any state data.
+ fn as_registry_block(&self) -> azalea_registry::Block;
}
impl dyn Block {
pub fn downcast_ref<T: Block>(&self) -> Option<&T> {
@@ -45,19 +48,14 @@ pub struct BlockState {
impl BlockState {
pub const AIR: BlockState = BlockState { id: 0 };
- /// Transmutes a u32 to a block state.
- ///
- /// # Safety
- /// The `state_id` should be a valid block state.
- #[inline]
- pub unsafe fn from_u32_unchecked(state_id: u32) -> Self {
- BlockState { id: state_id }
- }
-
#[inline]
pub fn is_valid_state(state_id: u32) -> bool {
state_id <= Self::max_state()
}
+
+ pub fn is_air(&self) -> bool {
+ self == &Self::AIR
+ }
}
impl TryFrom<u32> for BlockState {
@@ -66,7 +64,7 @@ impl TryFrom<u32> for BlockState {
/// Safely converts a state id to a block state.
fn try_from(state_id: u32) -> Result<Self, Self::Error> {
if Self::is_valid_state(state_id) {
- Ok(unsafe { Self::from_u32_unchecked(state_id) })
+ Ok(BlockState { id: state_id })
} else {
Err(())
}
@@ -98,6 +96,68 @@ impl std::fmt::Debug for BlockState {
}
}
+#[derive(Clone, Debug)]
+pub struct FluidState {
+ pub fluid: azalea_registry::Fluid,
+ pub height: u8,
+}
+
+impl Default for FluidState {
+ fn default() -> Self {
+ Self {
+ fluid: azalea_registry::Fluid::Empty,
+ height: 0,
+ }
+ }
+}
+
+impl From<BlockState> for FluidState {
+ fn from(state: BlockState) -> Self {
+ if state.waterlogged() {
+ Self {
+ fluid: azalea_registry::Fluid::Water,
+ height: 15,
+ }
+ } else {
+ let block = Box::<dyn Block>::from(state);
+ if let Some(water) = block.downcast_ref::<crate::blocks::Water>() {
+ Self {
+ fluid: azalea_registry::Fluid::Water,
+ height: water.level as u8,
+ }
+ } else if let Some(lava) = block.downcast_ref::<crate::blocks::Lava>() {
+ Self {
+ fluid: azalea_registry::Fluid::Lava,
+ height: lava.level as u8,
+ }
+ } else {
+ Self {
+ fluid: azalea_registry::Fluid::Empty,
+ height: 0,
+ }
+ }
+ }
+ }
+}
+
+impl From<FluidState> for BlockState {
+ fn from(state: FluidState) -> Self {
+ match state.fluid {
+ azalea_registry::Fluid::Empty => BlockState::AIR,
+ azalea_registry::Fluid::Water | azalea_registry::Fluid::FlowingWater => {
+ BlockState::from(crate::blocks::Water {
+ level: crate::properties::WaterLevel::from(state.height as u32),
+ })
+ }
+ azalea_registry::Fluid::Lava | azalea_registry::Fluid::FlowingLava => {
+ BlockState::from(crate::blocks::Lava {
+ level: crate::properties::LavaLevel::from(state.height as u32),
+ })
+ }
+ }
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;
diff --git a/azalea-buf/src/read.rs b/azalea-buf/src/read.rs
index 00693384..7c996f20 100755
--- a/azalea-buf/src/read.rs
+++ b/azalea-buf/src/read.rs
@@ -96,17 +96,10 @@ fn read_utf_with_len(buf: &mut Cursor<&[u8]>, max_length: u32) -> Result<String,
/// number of bytes read
// pub async fn read_varint_async(
// reader: &mut (dyn AsyncRead + Unpin + Send),
-// ) -> Result<i32, BufReadError> {
-// let mut buffer = [0];
-// let mut ans = 0;
-// for i in 0..5 {
-// reader.read_exact(&mut buffer).await?;
-// ans |= ((buffer[0] & 0b0111_1111) as i32) << (7 * i);
-// if buffer[0] & 0b1000_0000 == 0 {
-// break;
-// }
-// }
-// Ok(ans)
+// ) -> Result<i32, BufReadError> { let mut buffer = [0]; let mut ans = 0; for i
+// in 0..5 { reader.read_exact(&mut buffer).await?; ans |= ((buffer[0] &
+// 0b0111_1111) as i32) << (7 * i); if buffer[0] & 0b1000_0000 == 0 { break; }
+// } Ok(ans)
// }
pub trait McBufReadable
diff --git a/azalea-client/Cargo.toml b/azalea-client/Cargo.toml
index fb96fccb..9c4bcac6 100644
--- a/azalea-client/Cargo.toml
+++ b/azalea-client/Cargo.toml
@@ -38,6 +38,7 @@ regex = "1.9.1"
thiserror = "^1.0.43"
tokio = { version = "^1.29.1", features = ["sync"] }
uuid = "^1.4.0"
+azalea-entity = { version = "0.1.0", path = "../azalea-entity" }
[features]
default = ["log"]
diff --git a/azalea-client/src/account.rs b/azalea-client/src/account.rs
index 2d1b766c..0e67a79a 100755
--- a/azalea-client/src/account.rs
+++ b/azalea-client/src/account.rs
@@ -187,7 +187,10 @@ impl Account {
*access_token_mutex.lock() = new_access_token;
let AccountOpts::MicrosoftWithAccessToken { msa: new_msa } =
- new_account.account_opts else { unreachable!() };
+ new_account.account_opts
+ else {
+ unreachable!()
+ };
*msa.lock() = new_msa.lock().clone();
Ok(())
diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs
index 725cd9f3..0b1fccc1 100644
--- a/azalea-client/src/client.rs
+++ b/azalea-client/src/client.rs
@@ -8,6 +8,7 @@ use crate::{
death_event, handle_send_packet_event, update_in_loaded_chunk, GameProfileComponent,
LocalPlayer, PhysicsState, SendPacketEvent,
},
+ mining::{self, MinePlugin},
movement::{LastSentLookDirection, PlayerMovePlugin},
packet_handling::{self, PacketHandlerPlugin, PacketReceiver},
player::retroactively_add_game_profile_component,
@@ -19,6 +20,7 @@ use crate::{
use azalea_auth::{game_profile::GameProfile, sessionserver::ClientSessionServerError};
use azalea_chat::FormattedText;
use azalea_core::Vec3;
+use azalea_entity::{EntityPlugin, EntityUpdateSet, Local, Position};
use azalea_physics::{PhysicsPlugin, PhysicsSet};
use azalea_protocol::{
connect::{Connection, ConnectionError},
@@ -41,10 +43,7 @@ use azalea_protocol::{
},
resolver, ServerAddress,
};
-use azalea_world::{
- entity::{EntityPlugin, EntityUpdateSet, Local, Position, WorldName},
- Instance, InstanceContainer, PartialInstance,
-};
+use azalea_world::{Instance, InstanceContainer, InstanceName, PartialInstance};
use bevy_app::{App, FixedUpdate, Main, Plugin, PluginGroup, PluginGroupBuilder, Update};
use bevy_ecs::{
bundle::Bundle,
@@ -132,6 +131,10 @@ impl From<ClientboundPlayerAbilitiesPacket> for PlayerAbilities {
}
}
+/// Level must be 0..=4
+#[derive(Component, Clone, Default, Deref, DerefMut)]
+pub struct PermissionLevel(pub u8);
+
/// A component that contains a map of player UUIDs to their information in the
/// tab list.
///
@@ -301,6 +304,8 @@ impl Client {
current_sequence_number: CurrentSequenceNumber::default(),
last_sent_direction: LastSentLookDirection::default(),
abilities: PlayerAbilities::default(),
+ permission_level: PermissionLevel::default(),
+ mining: mining::MineBundle::default(),
_local: Local,
});
@@ -466,9 +471,9 @@ impl Client {
/// # Examples
///
/// ```
- /// # use azalea_world::entity::WorldName;
+ /// # use azalea_world::InstanceName;
/// # fn example(client: &azalea_client::Client) {
- /// let world_name = client.component::<WorldName>();
+ /// let world_name = client.component::<InstanceName>();
/// # }
pub fn component<T: Component + Clone>(&self) -> T {
self.query::<&T>(&mut self.ecs.lock()).clone()
@@ -486,7 +491,7 @@ impl Client {
/// If the client using a shared world, then the shared world will be a
/// superset of the client's world.
pub fn world(&self) -> Arc<RwLock<Instance>> {
- let world_name = self.component::<WorldName>();
+ let world_name = self.component::<InstanceName>();
let ecs = self.ecs.lock();
let instance_container = ecs.resource::<InstanceContainer>();
instance_container.get(&world_name).unwrap()
@@ -495,7 +500,7 @@ impl Client {
/// Returns whether we have a received the login packet yet.
pub fn logged_in(&self) -> bool {
// the login packet tells us the world name
- self.query::<Option<&WorldName>>(&mut self.ecs.lock())
+ self.query::<Option<&InstanceName>>(&mut self.ecs.lock())
.is_some()
}
@@ -560,6 +565,10 @@ pub struct JoinedClientBundle {
pub current_sequence_number: CurrentSequenceNumber,
pub last_sent_direction: LastSentLookDirection,
pub abilities: PlayerAbilities,
+ pub permission_level: PermissionLevel,
+
+ pub mining: mining::MineBundle,
+
pub _local: Local,
}
@@ -660,7 +669,7 @@ pub async fn tick_run_schedule_loop(run_schedule_sender: mpsc::UnboundedSender<(
#[derive(Resource, Deref)]
pub struct TickBroadcast(broadcast::Sender<()>);
-fn send_tick_broadcast(tick_broadcast: ResMut<TickBroadcast>) {
+pub fn send_tick_broadcast(tick_broadcast: ResMut<TickBroadcast>) {
let _ = tick_broadcast.0.send(());
}
/// A plugin that makes the [`RanScheduleBroadcast`] resource available.
@@ -706,6 +715,7 @@ impl PluginGroup for DefaultPlugins {
.add(PlayerMovePlugin)
.add(InteractPlugin)
.add(RespawnPlugin)
+ .add(MinePlugin)
.add(TickBroadcastPlugin);
#[cfg(feature = "log")]
{
diff --git a/azalea-client/src/entity_query.rs b/azalea-client/src/entity_query.rs
index 8fe94659..0320457f 100644
--- a/azalea-client/src/entity_query.rs
+++ b/azalea-client/src/entity_query.rs
@@ -15,10 +15,10 @@ impl Client {
///
/// # Examples
/// ```
- /// # use azalea_world::entity::WorldName;
+ /// # use azalea_world::InstanceName;
/// # fn example(mut client: azalea_client::Client) {
/// let is_logged_in = client
- /// .query::<Option<&WorldName>>(&mut client.ecs.lock())
+ /// .query::<Option<&InstanceName>>(&mut client.ecs.lock())
/// .is_some();
/// # }
/// ```
@@ -39,7 +39,7 @@ impl Client {
/// ```
/// use azalea_client::{Client, GameProfileComponent};
/// use bevy_ecs::query::With;
- /// use azalea_world::entity::{Position, metadata::Player};
+ /// use azalea_entity::{Position, metadata::Player};
///
/// # fn example(mut bot: Client, sender_name: String) {
/// let entity = bot.entity_by::<With<Player>, (&GameProfileComponent,)>(
diff --git a/azalea-client/src/events.rs b/azalea-client/src/events.rs
index e97f3477..900f559f 100644
--- a/azalea-client/src/events.rs
+++ b/azalea-client/src/events.rs
@@ -6,7 +6,7 @@ use std::sync::Arc;
use azalea_protocol::packets::game::{
clientbound_player_combat_kill_packet::ClientboundPlayerCombatKillPacket, ClientboundGamePacket,
};
-use azalea_world::entity::MinecraftEntityId;
+use azalea_world::MinecraftEntityId;
use bevy_app::{App, FixedUpdate, Plugin, Update};
use bevy_ecs::{component::Component, event::EventReader, query::Added, system::Query};
use derive_more::{Deref, DerefMut};
diff --git a/azalea-client/src/interact.rs b/azalea-client/src/interact.rs
index 45b845f9..dc0213b0 100644
--- a/azalea-client/src/interact.rs
+++ b/azalea-client/src/interact.rs
@@ -1,22 +1,22 @@
+use std::ops::AddAssign;
+
use azalea_block::BlockState;
use azalea_core::{BlockHitResult, BlockPos, Direction, GameMode, Vec3};
+use azalea_entity::{clamp_look_direction, view_vector, EyeHeight, LookDirection, Position};
use azalea_inventory::{ItemSlot, ItemSlotData};
use azalea_nbt::NbtList;
use azalea_physics::clip::{BlockShapeType, ClipContext, FluidPickType};
use azalea_protocol::packets::game::{
serverbound_interact_packet::InteractionHand,
+ serverbound_swing_packet::ServerboundSwingPacket,
serverbound_use_item_on_packet::{BlockHit, ServerboundUseItemOnPacket},
};
-use azalea_world::{
- entity::{clamp_look_direction, view_vector, EyeHeight, LookDirection, Position, WorldName},
- Instance, InstanceContainer,
-};
+use azalea_world::{Instance, InstanceContainer, InstanceName};
use bevy_app::{App, Plugin, Update};
use bevy_ecs::{
component::Component,
entity::Entity,
- event::EventReader,
- prelude::Event,
+ event::{Event, EventReader, EventWriter},
schedule::IntoSystemConfigs,
system::{Commands, Query, Res},
};
@@ -24,8 +24,9 @@ use derive_more::{Deref, DerefMut};
use log::warn;
use crate::{
+ client::{PermissionLevel, PlayerAbilities},
inventory::InventoryComponent,
- local_player::{handle_send_packet_event, LocalGameMode},
+ local_player::{handle_send_packet_event, LocalGameMode, SendPacketEvent},
Client, LocalPlayer,
};
@@ -33,15 +34,18 @@ use crate::{
pub struct InteractPlugin;
impl Plugin for InteractPlugin {
fn build(&self, app: &mut App) {
- app.add_event::<BlockInteractEvent>().add_systems(
- Update,
- (
- update_hit_result_component.after(clamp_look_direction),
- handle_block_interact_event,
- )
- .before(handle_send_packet_event)
- .chain(),
- );
+ app.add_event::<BlockInteractEvent>()
+ .add_event::<SwingArmEvent>()
+ .add_systems(
+ Update,
+ (
+ update_hit_result_component.after(clamp_look_direction),
+ handle_block_interact_event,
+ handle_swing_arm_event,
+ )
+ .before(handle_send_packet_event)
+ .chain(),
+ );
}
}
@@ -73,9 +77,15 @@ pub struct BlockInteractEvent {
/// A component that contains the number of changes this client has made to
/// blocks.
-#[derive(Component, Copy, Clone, Debug, Default, Deref, DerefMut)]
+#[derive(Component, Copy, Clone, Debug, Default, Deref)]
pub struct CurrentSequenceNumber(u32);
+impl AddAssign<u32> for CurrentSequenceNumber {
+ fn add_assign(&mut self, rhs: u32) {
+ self.0 += rhs;
+ }
+}
+
/// A component that contains the block that the player is currently looking at.
#[derive(Component, Clone, Debug, Deref, DerefMut)]
pub struct HitResultComponent(BlockHitResult);
@@ -89,14 +99,15 @@ pub fn handle_block_interact_event(
)>,
) {
for event in events.iter() {
- let Ok((local_player, mut sequence_number, hit_result)) = query.get_mut(event.entity) else {
+ let Ok((local_player, mut sequence_number, hit_result)) = query.get_mut(event.entity)
+ else {
warn!("Sent BlockInteractEvent for entity that isn't LocalPlayer");
continue;
};
// TODO: check to make sure we're within the world border
- **sequence_number += 1;
+ *sequence_number += 1;
// minecraft also does the interaction client-side (so it looks like clicking a
// button is instant) but we don't really need that
@@ -143,7 +154,7 @@ fn update_hit_result_component(
&Position,
&EyeHeight,
&LookDirection,
- &WorldName,
+ &InstanceName,
)>,
instance_container: Res<InstanceContainer>,
) {
@@ -246,10 +257,11 @@ pub fn check_block_can_be_broken_by_item_in_adventure_mode(
.nbt
.as_compound()
.and_then(|nbt| nbt.get("tag").and_then(|nbt| nbt.as_compound()))
- .and_then(|nbt| nbt.get("CanDestroy").and_then(|nbt| nbt.as_list())) else {
- // no CanDestroy tag
- return false;
- };
+ .and_then(|nbt| nbt.get("CanDestroy").and_then(|nbt| nbt.as_list()))
+ else {
+ // no CanDestroy tag
+ return false;
+ };
let NbtList::String(_can_destroy) = can_destroy else {
// CanDestroy tag must be a list of strings
@@ -265,3 +277,31 @@ pub fn check_block_can_be_broken_by_item_in_adventure_mode(
// true
}
+
+pub fn can_use_game_master_blocks(
+ abilities: &PlayerAbilities,
+ permission_level: &PermissionLevel,
+) -> bool {
+ abilities.instant_break && **permission_level >= 2
+}
+
+/// Swing your arm. This is purely a visual effect and won't interact with
+/// anything in the world.
+#[derive(Event)]
+pub struct SwingArmEvent {
+ pub entity: Entity,
+}
+fn handle_swing_arm_event(
+ mut events: EventReader<SwingArmEvent>,
+ mut send_packet_events: EventWriter<SendPacketEvent>,
+) {
+ for event in events.iter() {
+ send_packet_events.send(SendPacketEvent {
+ entity: event.entity,
+ packet: ServerboundSwingPacket {
+ hand: InteractionHand::MainHand,
+ }
+ .get(),
+ });
+ }
+}
diff --git a/azalea-client/src/inventory.rs b/azalea-client/src/inventory.rs
index 25ce157e..6f7829de 100644
--- a/azalea-client/src/inventory.rs
+++ b/azalea-client/src/inventory.rs
@@ -101,6 +101,7 @@ pub struct InventoryComponent {
/// the scroll wheel.
pub selected_hotbar_slot: u8,
}
+
impl InventoryComponent {
/// Returns a reference to the currently active menu. If a container is open
/// it'll return [`Self::container_menu`], otherwise
@@ -220,10 +221,10 @@ impl InventoryComponent {
loop {
let Some(&next_slot) = quick_craft_slots_iter.next() else {
- carried.count = carried_count;
- self.carried = ItemSlot::Present(carried);
- return self.reset_quick_craft();
- };
+ carried.count = carried_count;
+ self.carried = ItemSlot::Present(carried);
+ return self.reset_quick_craft();
+ };
slot = self.menu().slot(next_slot as usize).unwrap();
slot_index = next_slot;
@@ -244,8 +245,8 @@ impl InventoryComponent {
// get the ItemSlotData for the slot
let ItemSlot::Present(slot) = slot else {
- unreachable!("the loop above requires the slot to be present to break")
- };
+ unreachable!("the loop above requires the slot to be present to break")
+ };
// if self.can_drag_to(slot) {
let mut new_carried = carried.clone();
@@ -480,8 +481,8 @@ impl InventoryComponent {
// now extend the carried item
let target_slot = &mut self.carried;
let ItemSlot::Present(target_slot_item) = target_slot else {
- unreachable!("target slot is not empty but is not present");
- };
+ unreachable!("target slot is not empty but is not present");
+ };
target_slot_item.count += taken_item.count();
}
}
@@ -512,13 +513,13 @@ fn can_item_quick_replace(
ignore_item_count: bool,
) -> bool {
let ItemSlot::Present(target_slot) = target_slot else {
- return false;
- };
+ return false;
+ };
let ItemSlot::Present(item) = item else {
// i *think* this is what vanilla does
// not 100% sure lol probably doesn't matter though
- return false;
- };
+ return false;
+ };
if !item.is_same_item_and_nbt(target_slot) {
return false;
diff --git a/azalea-client/src/lib.rs b/azalea-client/src/lib.rs
index c47c5e29..e36cb846 100644
--- a/azalea-client/src/lib.rs
+++ b/azalea-client/src/lib.rs
@@ -21,7 +21,7 @@ mod get_mc_dir;
pub mod interact;
pub mod inventory;
mod local_player;
-mod mining;
+pub mod mining;
mod movement;
pub mod packet_handling;
pub mod ping;
diff --git a/azalea-client/src/local_player.rs b/azalea-client/src/local_player.rs
index 4368c47c..594513db 100644
--- a/azalea-client/src/local_player.rs
+++ b/azalea-client/src/local_player.rs
@@ -2,11 +2,9 @@ use std::{io, sync::Arc};
use azalea_auth::game_profile::GameProfile;
use azalea_core::{ChunkPos, GameMode};
+use azalea_entity::{Dead, Position};
use azalea_protocol::packets::game::ServerboundGamePacket;
-use azalea_world::{
- entity::{self, Dead, WorldName},
- Instance, InstanceContainer, PartialInstance,
-};
+use azalea_world::{Instance, InstanceContainer, InstanceName, PartialInstance};
use bevy_ecs::{
component::Component,
entity::Entity,
@@ -32,7 +30,7 @@ use crate::{
/// You can also use the [`Local`] marker component for queries if you're only
/// checking for a local player and don't need the contents of this component.
///
-/// [`Local`]: azalea_world::entity::Local
+/// [`Local`]: azalea_entity::Local
/// [`Client`]: crate::Client
#[derive(Component)]
pub struct LocalPlayer {
@@ -135,7 +133,7 @@ impl Drop for LocalPlayer {
/// Update the [`LocalPlayerInLoadedChunk`] component for all [`LocalPlayer`]s.
pub fn update_in_loaded_chunk(
mut commands: bevy_ecs::system::Commands,
- query: Query<(Entity, &WorldName, &entity::Position)>,
+ query: Query<(Entity, &InstanceName, &Position)>,
instance_container: Res<InstanceContainer>,
) {
for (entity, local_player, position) in &query {
diff --git a/azalea-client/src/mining.rs b/azalea-client/src/mining.rs
index 241c4fde..049bc859 100644
--- a/azalea-client/src/mining.rs
+++ b/azalea-client/src/mining.rs
@@ -1,36 +1,543 @@
-use azalea_core::BlockPos;
-use bevy_app::{App, Plugin, Update};
+use azalea_block::{Block, BlockState, FluidState};
+use azalea_core::{BlockPos, Direction, GameMode};
+use azalea_entity::{mining::get_mine_progress, FluidOnEyes, Physics};
+use azalea_inventory::ItemSlot;
+use azalea_protocol::packets::game::serverbound_player_action_packet::{
+ self, ServerboundPlayerActionPacket,
+};
+use azalea_world::{InstanceContainer, InstanceName};
+use bevy_app::{App, FixedUpdate, Plugin, Update};
use bevy_ecs::prelude::*;
+use derive_more::{Deref, DerefMut};
-use crate::Client;
+use crate::{
+ client::{PermissionLevel, PlayerAbilities},
+ interact::{
+ can_use_game_master_blocks, check_is_interaction_restricted, CurrentSequenceNumber,
+ HitResultComponent, SwingArmEvent,
+ },
+ inventory::InventoryComponent,
+ local_player::{LocalGameMode, SendPacketEvent},
+};
/// A plugin that allows clients to break blocks in the world.
pub struct MinePlugin;
impl Plugin for MinePlugin {
fn build(&self, app: &mut App) {
app.add_event::<StartMiningBlockEvent>()
- .add_systems(Update, handle_start_mining_block_event);
+ .add_event::<StartMiningBlockWithDirectionEvent>()
+ .add_event::<FinishMiningBlockEvent>()
+ .add_event::<StopMiningBlockEvent>()
+ .add_event::<MineBlockProgressEvent>()
+ .add_event::<AttackBlockEvent>()
+ .add_systems(FixedUpdate, continue_mining_block)
+ .add_systems(
+ Update,
+ (
+ handle_start_mining_block_event,
+ handle_start_mining_block_with_direction_event,
+ handle_finish_mining_block_event,
+ handle_stop_mining_block_event,
+ )
+ .chain(),
+ );
}
}
-impl Client {
- /// Start mining a block.
- pub fn start_mining_block(&self, position: BlockPos) {
- self.ecs.lock().send_event(StartMiningBlockEvent {
- entity: self.entity,
- position,
+/// Information about the block we're currently mining. This is only present if
+/// we're currently mining a block.
+#[derive(Component)]
+pub struct Mining {
+ pub pos: BlockPos,
+ pub dir: Direction,
+}
+
+/// Start mining the block at the given position.
+///
+/// If we're looking at the block then the correct direction will be used,
+/// otherwise it'll be [`Direction::Down`].
+#[derive(Event)]
+pub struct StartMiningBlockEvent {
+ pub entity: Entity,
+ pub position: BlockPos,
+}
+fn handle_start_mining_block_event(
+ mut events: EventReader<StartMiningBlockEvent>,
+ mut start_mining_events: EventWriter<StartMiningBlockWithDirectionEvent>,
+ mut query: Query<&HitResultComponent>,
+) {
+ for event in events.iter() {
+ let hit_result = query.get_mut(event.entity).unwrap();
+ let direction = if hit_result.block_pos == event.position {
+ // we're looking at the block
+ hit_result.direction
+ } else {
+ // we're not looking at the block, arbitrary direction
+ Direction::Down
+ };
+ start_mining_events.send(StartMiningBlockWithDirectionEvent {
+ entity: event.entity,
+ position: event.position,
+ direction,
});
}
}
#[derive(Event)]
-pub struct StartMiningBlockEvent {
+pub struct StartMiningBlockWithDirectionEvent {
+ pub entity: Entity,
+ pub position: BlockPos,
+ pub direction: Direction,
+}
+#[allow(clippy::too_many_arguments, clippy::type_complexity)]
+fn handle_start_mining_block_with_direction_event(
+ mut events: EventReader<StartMiningBlockWithDirectionEvent>,
+ mut finish_mining_events: EventWriter<FinishMiningBlockEvent>,
+ mut send_packet_events: EventWriter<SendPacketEvent>,
+ mut attack_block_events: EventWriter<AttackBlockEvent>,
+ mut mine_block_progress_events: EventWriter<MineBlockProgressEvent>,
+ mut query: Query<(
+ &InstanceName,
+ &LocalGameMode,
+ &InventoryComponent,
+ &FluidOnEyes,
+ &Physics,
+ Option<&Mining>,
+ &mut CurrentSequenceNumber,
+ &mut MineDelay,
+ &mut MineProgress,
+ &mut MineTicks,
+ &mut MineItem,
+ &mut MineBlockPos,
+ )>,
+ instances: Res<InstanceContainer>,
+ mut commands: Commands,
+) {
+ for event in events.iter() {
+ let (
+ instance_name,
+ game_mode,
+ inventory,
+ fluid_on_eyes,
+ physics,
+ mining,
+ mut sequence_number,
+ mut mine_delay,
+ mut mine_progress,
+ mut mine_ticks,
+ mut current_mining_item,
+ mut current_mining_pos,
+ ) = query.get_mut(event.entity).unwrap();
+
+ let instance_lock = instances.get(instance_name).unwrap();
+ let instance = instance_lock.read();
+ if check_is_interaction_restricted(
+ &instance,
+ &event.position,
+ &game_mode.current,
+ inventory,
+ ) {
+ continue;
+ }
+ // TODO (when world border is implemented): vanilla ignores if the block
+ // is outside of the worldborder
+
+ if game_mode.current == GameMode::Creative {
+ *sequence_number += 1;
+ finish_mining_events.send(FinishMiningBlockEvent {
+ entity: event.entity,
+ position: event.position,
+ });
+ **mine_delay = 5;
+ } else if mining.is_none()
+ || !is_same_mining_target(
+ event.position,
+ inventory,
+ &current_mining_pos,
+ &current_mining_item,
+ )
+ {
+ if mining.is_some() {
+ // send a packet to stop mining since we just changed target
+ send_packet_events.send(SendPacketEvent {
+ entity: event.entity,
+ packet: ServerboundPlayerActionPacket {
+ action: serverbound_player_action_packet::Action::AbortDestroyBlock,
+ pos: current_mining_pos
+ .expect("IsMining is true so MineBlockPos must be present"),
+ direction: event.direction,
+ sequence: 0,
+ }
+ .get(),
+ });
+ }
+
+ let target_block_state = instance
+ .get_block_state(&event.position)
+ .unwrap_or_default();
+ *sequence_number += 1;
+ let block_is_solid = !target_block_state.is_air();
+ if block_is_solid && **mine_progress == 0. {
+ // interact with the block (like note block left click) here
+ attack_block_events.send(AttackBlockEvent {
+ entity: event.entity,
+ position: event.position,
+ });
+ }
+
+ let block = Box::<dyn Block>::from(target_block_state);
+
+ let held_item = inventory.held_item();
+
+ if block_is_solid
+ && get_mine_progress(
+ block.as_ref(),
+ held_item.kind(),
+ &inventory.inventory_menu,
+ fluid_on_eyes,
+ physics,
+ ) >= 1.
+ {
+ // block was broken instantly
+ finish_mining_events.send(FinishMiningBlockEvent {
+ entity: event.entity,
+ position: event.position,
+ });
+ } else {
+ commands.entity(event.entity).insert(Mining {
+ pos: event.position,
+ dir: event.direction,
+ });
+ **current_mining_pos = Some(event.position);
+ **current_mining_item = held_item;
+ **mine_progress = 0.;
+ **mine_ticks = 0.;
+ mine_block_progress_events.send(MineBlockProgressEvent {
+ entity: event.entity,
+ position: event.position,
+ destroy_stage: mine_progress.destroy_stage(),
+ })
+ }
+
+ send_packet_events.send(SendPacketEvent {
+ entity: event.entity,
+ packet: ServerboundPlayerActionPacket {
+ action: serverbound_player_action_packet::Action::StartDestroyBlock,
+ pos: event.position,
+ direction: event.direction,
+ sequence: **sequence_number,
+ }
+ .get(),
+ });
+ }
+ }
+}
+
+#[derive(Event)]
+pub struct MineBlockProgressEvent {
pub entity: Entity,
pub position: BlockPos,
+ pub destroy_stage: Option<u32>,
}
-fn handle_start_mining_block_event(mut _events: EventReader<StartMiningBlockEvent>) {
- // for event in events.iter() {
- // //
- // }
+/// A player left clicked on a block, used for stuff like interacting with note
+/// blocks.
+#[derive(Event)]
+pub struct AttackBlockEvent {
+ pub entity: Entity,
+ pub position: BlockPos,
+}
+
+/// Returns whether the block and item are still the same as when we started
+/// mining.
+fn is_same_mining_target(
+ target_block: BlockPos,
+ inventory: &InventoryComponent,
+ current_mining_pos: &MineBlockPos,
+ current_mining_item: &MineItem,
+) -> bool {
+ let held_item = inventory.held_item();
+ Some(target_block) == current_mining_pos.0 && held_item == current_mining_item.0
+}
+
+/// A component bundle for players that can mine blocks.
+#[derive(Bundle, Default)]
+pub struct MineBundle {
+ pub delay: MineDelay,
+ pub progress: MineProgress,
+ pub ticks: MineTicks,
+ pub mining_pos: MineBlockPos,
+ pub mine_item: MineItem,
+}
+
+/// A component that counts down until we start mining the next block.
+#[derive(Component, Debug, Default, Deref, DerefMut)]
+pub struct MineDelay(pub u32);
+
+/// A component that stores the progress of the current mining operation. This
+/// is a value between 0 and 1.
+#[derive(Component, Debug, Default, Deref, DerefMut)]
+pub struct MineProgress(pub f32);
+
+impl MineProgress {
+ pub fn destroy_stage(&self) -> Option<u32> {
+ if self.0 > 0. {
+ Some((self.0 * 10.) as u32)
+ } else {
+ None
+ }
+ }
+}
+
+/// A component that stores the number of ticks that we've been mining the same
+/// block for. This is a float even though it should only ever be a round
+/// number.
+#[derive(Component, Debug, Default, Deref, DerefMut)]
+pub struct MineTicks(pub f32);
+
+/// A component that stores the position of the block we're currently mining.
+#[derive(Component, Debug, Default, Deref, DerefMut)]
+pub struct MineBlockPos(pub Option<BlockPos>);
+
+/// A component that contains the item we're currently using to mine. If we're
+/// not mining anything, it'll be [`ItemSlot::Empty`].
+#[derive(Component, Debug, Default, Deref, DerefMut)]
+pub struct MineItem(pub ItemSlot);
+
+/// Sent when we completed mining a block.
+#[derive(Event)]
+pub struct FinishMiningBlockEvent {
+ pub entity: Entity,
+ pub position: BlockPos,
+}
+
+fn handle_finish_mining_block_event(
+ mut events: EventReader<FinishMiningBlockEvent>,
+ mut query: Query<(
+ &InstanceName,
+ &LocalGameMode,
+ &InventoryComponent,
+ &PlayerAbilities,
+ &PermissionLevel,
+ &mut CurrentSequenceNumber,
+ )>,
+ instances: Res<InstanceContainer>,
+) {
+ for event in events.iter() {
+ let (instance_name, game_mode, inventory, abilities, permission_level, _sequence_number) =
+ query.get_mut(event.entity).unwrap();
+ let instance_lock = instances.get(instance_name).unwrap();
+ let instance = instance_lock.read();
+ if check_is_interaction_restricted(
+ &instance,
+ &event.position,
+ &game_mode.current,
+ inventory,
+ ) {
+ continue;
+ }
+
+ if game_mode.current == GameMode::Creative {
+ let held_item = inventory.held_item().kind();
+ if matches!(
+ held_item,
+ azalea_registry::Item::Trident | azalea_registry::Item::DebugStick
+ ) || azalea_registry::tags::items::SWORDS.contains(&held_item)
+ {
+ continue;
+ }
+ }
+
+ let Some(block_state) = instance.get_block_state(&event.position) else {
+ continue;
+ };
+
+ let registry_block = Box::<dyn Block>::from(block_state).as_registry_block();
+ if !can_use_game_master_blocks(abilities, permission_level)
+ && matches!(
+ registry_block,
+ azalea_registry::Block::CommandBlock | azalea_registry::Block::StructureBlock
+ )
+ {
+ continue;
+ }
+ if block_state == BlockState::AIR {
+ continue;
+ }
+
+ // when we break a waterlogged block we want to keep the water there
+ let fluid_state = FluidState::from(block_state);
+ let block_state_for_fluid = BlockState::from(fluid_state);
+ instance.set_block_state(&event.position, block_state_for_fluid);
+ }
+}
+
+/// Abort mining a block.
+#[derive(Event)]
+pub struct StopMiningBlockEvent {
+ pub entity: Entity,
+}
+fn handle_stop_mining_block_event(
+ mut events: EventReader<StopMiningBlockEvent>,
+ mut send_packet_events: EventWriter<SendPacketEvent>,
+ mut mine_block_progress_events: EventWriter<MineBlockProgressEvent>,
+ mut query: Query<(&mut Mining, &MineBlockPos, &mut MineProgress)>,
+ mut commands: Commands,
+) {
+ for event in events.iter() {
+ let (mut _mining, mine_block_pos, mut mine_progress) = query.get_mut(event.entity).unwrap();
+
+ let mine_block_pos =
+ mine_block_pos.expect("IsMining is true so MineBlockPos must be present");
+ send_packet_events.send(SendPacketEvent {
+ entity: event.entity,
+ packet: ServerboundPlayerActionPacket {
+ action: serverbound_player_action_packet::Action::AbortDestroyBlock,
+ pos: mine_block_pos,
+ direction: Direction::Down,
+ sequence: 0,
+ }
+ .get(),
+ });
+ commands.entity(event.entity).remove::<Mining>();
+ **mine_progress = 0.;
+ mine_block_progress_events.send(MineBlockProgressEvent {
+ entity: event.entity,
+ position: mine_block_pos,
+ destroy_stage: None,
+ });
+ }
+}
+
+#[allow(clippy::too_many_arguments, clippy::type_complexity)]
+fn continue_mining_block(
+ mut query: Query<(
+ Entity,
+ &InstanceName,
+ &LocalGameMode,
+ &InventoryComponent,
+ &MineBlockPos,
+ &MineItem,
+ &FluidOnEyes,
+ &Physics,
+ &Mining,
+ &mut MineDelay,
+ &mut MineProgress,
+ &mut MineTicks,
+ &mut CurrentSequenceNumber,
+ )>,
+ mut send_packet_events: EventWriter<SendPacketEvent>,
+ mut mine_block_progress_events: EventWriter<MineBlockProgressEvent>,
+ mut finish_mining_events: EventWriter<FinishMiningBlockEvent>,
+ mut start_mining_events: EventWriter<StartMiningBlockWithDirectionEvent>,
+ mut swing_arm_events: EventWriter<SwingArmEvent>,
+ instances: Res<InstanceContainer>,
+ mut commands: Commands,
+) {
+ for (
+ entity,
+ instance_name,
+ game_mode,
+ inventory,
+ current_mining_pos,
+ current_mining_item,
+ fluid_on_eyes,
+ physics,
+ mining,
+ mut mine_delay,
+ mut mine_progress,
+ mut mine_ticks,
+ mut sequence_number,
+ ) in query.iter_mut()
+ {
+ if **mine_delay > 0 {
+ **mine_delay -= 1;
+ continue;
+ }
+
+ if game_mode.current == GameMode::Creative {
+ // TODO: worldborder check
+ **mine_delay = 5;
+ finish_mining_events.send(FinishMiningBlockEvent {
+ entity,
+ position: mining.pos,
+ });
+ *sequence_number += 1;
+ send_packet_events.send(SendPacketEvent {
+ entity,
+ packet: ServerboundPlayerActionPacket {
+ action: serverbound_player_action_packet::Action::StartDestroyBlock,
+ pos: mining.pos,
+ direction: mining.dir,
+ sequence: **sequence_number,
+ }
+ .get(),
+ });
+ swing_arm_events.send(SwingArmEvent { entity });
+ } else if is_same_mining_target(
+ mining.pos,
+ inventory,
+ current_mining_pos,
+ current_mining_item,
+ ) {
+ let instance_lock = instances.get(instance_name).unwrap();
+ let instance = instance_lock.read();
+ let target_block_state = instance.get_block_state(&mining.pos).unwrap_or_default();
+
+ if target_block_state.is_air() {
+ commands.entity(entity).remove::<Mining>();
+ continue;
+ }
+ let block = Box::<dyn Block>::from(target_block_state);
+ **mine_progress += get_mine_progress(
+ block.as_ref(),
+ current_mining_item.kind(),
+ &inventory.inventory_menu,
+ fluid_on_eyes,
+ physics,
+ );
+
+ if **mine_ticks % 4. == 0. {
+ // vanilla makes a mining sound here
+ }
+ **mine_ticks += 1.;
+
+ if **mine_progress >= 1. {
+ commands.entity(entity).remove::<Mining>();
+ *sequence_number += 1;
+ finish_mining_events.send(FinishMiningBlockEvent {
+ entity,
+ position: mining.pos,
+ });
+ send_packet_events.send(SendPacketEvent {
+ entity,
+ packet: ServerboundPlayerActionPacket {
+ action: serverbound_player_action_packet::Action::StopDestroyBlock,
+ pos: mining.pos,
+ direction: mining.dir,
+ sequence: **sequence_number,
+ }
+ .get(),
+ });
+ **mine_progress = 0.;
+ **mine_ticks = 0.;
+ **mine_delay = 0;
+ }
+
+ mine_block_progress_events.send(MineBlockProgressEvent {
+ entity,
+ position: mining.pos,
+ destroy_stage: mine_progress.destroy_stage(),
+ });
+ swing_arm_events.send(SwingArmEvent { entity });
+ } else {
+ start_mining_events.send(StartMiningBlockWithDirectionEvent {
+ entity,
+ position: mining.pos,
+ direction: mining.dir,
+ })
+ }
+
+ swing_arm_events.send(SwingArmEvent { entity });
+ }
}
diff --git a/azalea-client/src/movement.rs b/azalea-client/src/movement.rs
index 2db392b4..0bda9b15 100644
--- a/azalea-client/src/movement.rs
+++ b/azalea-client/src/movement.rs
@@ -2,6 +2,8 @@ use crate::client::Client;
use crate::local_player::{
update_in_loaded_chunk, LocalPlayer, LocalPlayerInLoadedChunk, PhysicsState,
};
+use azalea_entity::{metadata::Sprinting, Attributes, Jumping};
+use azalea_entity::{LastSentPosition, LookDirection, Physics, Position};
use azalea_physics::{force_jump_listener, PhysicsSet};
use azalea_protocol::packets::game::serverbound_player_command_packet::ServerboundPlayerCommandPacket;
use azalea_protocol::packets::game::{
@@ -10,10 +12,7 @@ use azalea_protocol::packets::game::{
serverbound_move_player_rot_packet::ServerboundMovePlayerRotPacket,
serverbound_move_player_status_only_packet::ServerboundMovePlayerStatusOnlyPacket,
};
-use azalea_world::{
- entity::{self, metadata::Sprinting, Attributes, Jumping, MinecraftEntityId},
- MoveEntityError,
-};
+use azalea_world::{MinecraftEntityId, MoveEntityError};
use bevy_app::{App, FixedUpdate, Plugin, Update};
use bevy_ecs::prelude::Event;
use bevy_ecs::{
@@ -89,7 +88,7 @@ impl Client {
/// `y_rot` goes from -180 to 180, and `x_rot` goes from -90 to 90.
pub fn set_direction(&mut self, y_rot: f32, x_rot: f32) {
let mut ecs = self.ecs.lock();
- let mut look_direction = self.query::<&mut entity::LookDirection>(&mut ecs);
+ let mut look_direction = self.query::<&mut LookDirection>(&mut ecs);
(look_direction.y_rot, look_direction.x_rot) = (y_rot, x_rot);
}
@@ -110,12 +109,12 @@ pub(crate) fn send_position(
&MinecraftEntityId,
&mut LocalPlayer,
&mut PhysicsState,
- &entity::Position,
- &mut entity::LastSentPosition,
- &mut entity::Physics,
- &entity::LookDirection,
+ &Position,
+ &mut LastSentPosition,
+ &mut Physics,
+ &LookDirection,
&mut LastSentLookDirection,
- &entity::metadata::Sprinting,
+ &Sprinting,
),
&LocalPlayerInLoadedChunk,
>,
@@ -223,7 +222,7 @@ impl LocalPlayer {
fn send_sprinting_if_needed(
&mut self,
id: &MinecraftEntityId,
- sprinting: &entity::metadata::Sprinting,
+ sprinting: &Sprinting,
physics_state: &mut PhysicsState,
) {
let was_sprinting = physics_state.was_sprinting;
@@ -287,9 +286,9 @@ pub fn local_player_ai_step(
mut query: Query<
(
&mut PhysicsState,
- &mut entity::Physics,
- &mut entity::metadata::Sprinting,
- &mut entity::Attributes,
+ &mut Physics,
+ &mut Sprinting,
+ &mut Attributes,
),
With<LocalPlayerInLoadedChunk>,
>,
@@ -431,12 +430,12 @@ fn set_sprinting(
if sprinting {
attributes
.speed
- .insert(entity::attributes::sprinting_modifier())
+ .insert(azalea_entity::attributes::sprinting_modifier())
.is_ok()
} else {
attributes
.speed
- .remove(&entity::attributes::sprinting_modifier().uuid)
+ .remove(&azalea_entity::attributes::sprinting_modifier().uuid)
.is_none()
}
}
diff --git a/azalea-client/src/packet_handling.rs b/azalea-client/src/packet_handling.rs
index 2371d834..fd8d77e5 100644
--- a/azalea-client/src/packet_handling.rs
+++ b/azalea-client/src/packet_handling.rs
@@ -1,6 +1,11 @@
use std::{collections::HashSet, io::Cursor, sync::Arc};
use azalea_core::{ChunkPos, GameMode, ResourceLocation, Vec3};
+use azalea_entity::{
+ metadata::{apply_metadata, Health, PlayerMetadataBundle},
+ Dead, EntityBundle, EntityKind, EntityUpdateSet, LastSentPosition, LoadedBy, LookDirection,
+ Physics, PlayerBundle, Position, RelativeEntityUpdate,
+};
use azalea_protocol::{
connect::{ReadConnection, WriteConnection},
packets::game::{
@@ -15,15 +20,7 @@ use azalea_protocol::{
},
read::ReadPacketError,
};
-use azalea_world::{
- entity::{
- metadata::{apply_metadata, Health, PlayerMetadataBundle},
- Dead, EntityBundle, EntityKind, EntityUpdateSet, LastSentPosition, LookDirection,
- MinecraftEntityId, Physics, PlayerBundle, Position, WorldName,
- },
- entity::{LoadedBy, RelativeEntityUpdate},
- InstanceContainer, PartialInstance,
-};
+use azalea_world::{InstanceContainer, InstanceName, MinecraftEntityId, PartialInstance};
use bevy_app::{App, First, Plugin, PreUpdate};
use bevy_ecs::{
component::Component,
@@ -195,7 +192,7 @@ fn process_packet_events(ecs: &mut World) {
Commands,
Query<(
&mut LocalPlayer,
- Option<&mut WorldName>,
+ Option<&mut InstanceName>,
&GameProfileComponent,
&ClientInformation,
)>,
@@ -225,7 +222,7 @@ fn process_packet_events(ecs: &mut World) {
} else {
commands
.entity(player_entity)
- .insert(WorldName(new_world_name.clone()));
+ .insert(InstanceName(new_world_name.clone()));
}
// add this world to the instance_container (or don't if it's already
// there)
@@ -348,10 +345,16 @@ fn process_packet_events(ecs: &mut World) {
)>,
> = SystemState::new(ecs);
let mut query = system_state.get_mut(ecs);
- let Ok((local_player, mut physics, mut direction, mut position, mut last_sent_position)) =
- query.get_mut(player_entity) else {
- continue;
- };
+ let Ok((
+ local_player,
+ mut physics,
+ mut direction,
+ mut position,
+ mut last_sent_position,
+ )) = query.get_mut(player_entity)
+ else {
+ continue;
+ };
let delta_movement = physics.delta;
@@ -555,12 +558,12 @@ fn process_packet_events(ecs: &mut World) {
ClientboundGamePacket::AddEntity(p) => {
debug!("Got add entity packet {:?}", p);
- let mut system_state: SystemState<(Commands, Query<Option<&WorldName>>)> =
+ let mut system_state: SystemState<(Commands, Query<Option<&InstanceName>>)> =
SystemState::new(ecs);
let (mut commands, mut query) = system_state.get_mut(ecs);
let world_name = query.get_mut(player_entity).unwrap();
- if let Some(WorldName(world_name)) = world_name {
+ if let Some(InstanceName(world_name)) = world_name {
let bundle = p.as_entity_bundle(world_name.clone());
let mut entity_commands = commands.spawn((
MinecraftEntityId(p.id),
@@ -622,12 +625,12 @@ fn process_packet_events(ecs: &mut World) {
#[allow(clippy::type_complexity)]
let mut system_state: SystemState<(
Commands,
- Query<(&TabList, Option<&WorldName>)>,
+ Query<(&TabList, Option<&InstanceName>)>,
)> = SystemState::new(ecs);
let (mut commands, mut query) = system_state.get_mut(ecs);
let (tab_list, world_name) = query.get_mut(player_entity).unwrap();
- if let Some(WorldName(world_name)) = world_name {
+ if let Some(InstanceName(world_name)) = world_name {
let bundle = p.as_player_bundle(world_name.clone());
let mut spawned = commands.spawn((
MinecraftEntityId(p.id),
diff --git a/azalea-client/src/player.rs b/azalea-client/src/player.rs
index 999f2490..25ba0d8c 100755
--- a/azalea-client/src/player.rs
+++ b/azalea-client/src/player.rs
@@ -1,7 +1,7 @@
use azalea_auth::game_profile::GameProfile;
use azalea_chat::FormattedText;
use azalea_core::GameMode;
-use azalea_world::entity::EntityInfos;
+use azalea_entity::EntityInfos;
use bevy_ecs::{
event::EventReader,
system::{Commands, Res},
diff --git a/azalea-core/src/lib.rs b/azalea-core/src/lib.rs
index 7bf4a12c..8ed62b06 100755
--- a/azalea-core/src/lib.rs
+++ b/azalea-core/src/lib.rs
@@ -22,8 +22,7 @@ pub use direction::*;
mod delta;
pub use delta::*;
-mod particle;
-pub use particle::*;
+pub mod particle;
mod cursor3d;
pub use cursor3d::*;
@@ -37,61 +36,5 @@ pub use aabb::*;
mod block_hit_result;
pub use block_hit_result::*;
-// some random math things used in minecraft are defined down here
-
-// TODO: make this generic
-pub fn binary_search(mut min: i32, max: i32, predicate: &dyn Fn(i32) -> bool) -> i32 {
- let mut diff = max - min;
- while diff > 0 {
- let diff_mid = diff / 2;
- let mid = min + diff_mid;
- if predicate(mid) {
- diff = diff_mid;
- } else {
- min = mid + 1;
- diff -= diff_mid + 1;
- }
- }
-
- min
-}
-
-pub fn lcm(a: u32, b: u32) -> u64 {
- let gcd = gcd(a, b);
- (a as u64) * (b / gcd) as u64
-}
-pub fn gcd(mut a: u32, mut b: u32) -> u32 {
- while b != 0 {
- let t = b;
- b = a % b;
- a = t;
- }
- a
-}
-
-pub fn lerp<T: num_traits::Float>(amount: T, a: T, b: T) -> T {
- a + amount * (b - a)
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn test_gcd() {
- assert_eq!(gcd(0, 0), 0);
- assert_eq!(gcd(1, 1), 1);
-
- assert_eq!(gcd(0, 1), 1);
- assert_eq!(gcd(1, 0), 1);
-
- assert_eq!(gcd(12, 8), 4);
- assert_eq!(gcd(8, 12), 4);
-
- assert_eq!(gcd(12, 9), 3);
- assert_eq!(gcd(9, 12), 3);
-
- assert_eq!(gcd(12, 7), 1);
- assert_eq!(gcd(7, 12), 1);
- }
-}
+pub mod math;
+pub mod tier;
diff --git a/azalea-core/src/math.rs b/azalea-core/src/math.rs
new file mode 100644
index 00000000..2e5e78f6
--- /dev/null
+++ b/azalea-core/src/math.rs
@@ -0,0 +1,56 @@
+// TODO: make this generic
+pub fn binary_search(mut min: i32, max: i32, predicate: &dyn Fn(i32) -> bool) -> i32 {
+ let mut diff = max - min;
+ while diff > 0 {
+ let diff_mid = diff / 2;
+ let mid = min + diff_mid;
+ if predicate(mid) {
+ diff = diff_mid;
+ } else {
+ min = mid + 1;
+ diff -= diff_mid + 1;
+ }
+ }
+
+ min
+}
+
+pub fn lcm(a: u32, b: u32) -> u64 {
+ let gcd = gcd(a, b);
+ (a as u64) * (b / gcd) as u64
+}
+pub fn gcd(mut a: u32, mut b: u32) -> u32 {
+ while b != 0 {
+ let t = b;
+ b = a % b;
+ a = t;
+ }
+ a
+}
+
+pub fn lerp<T: num_traits::Float>(amount: T, a: T, b: T) -> T {
+ a + amount * (b - a)
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_gcd() {
+ assert_eq!(gcd(0, 0), 0);
+ assert_eq!(gcd(1, 1), 1);
+
+ assert_eq!(gcd(0, 1), 1);
+ assert_eq!(gcd(1, 0), 1);
+
+ assert_eq!(gcd(12, 8), 4);
+ assert_eq!(gcd(8, 12), 4);
+
+ assert_eq!(gcd(12, 9), 3);
+ assert_eq!(gcd(9, 12), 3);
+
+ assert_eq!(gcd(12, 7), 1);
+ assert_eq!(gcd(7, 12), 1);
+ }
+}
diff --git a/azalea-core/src/particle/mod.rs b/azalea-core/src/particle.rs
index 60128f3f..60128f3f 100755
--- a/azalea-core/src/particle/mod.rs
+++ b/azalea-core/src/particle.rs
diff --git a/azalea-core/src/tier.rs b/azalea-core/src/tier.rs
new file mode 100644
index 00000000..e921899f
--- /dev/null
+++ b/azalea-core/src/tier.rs
@@ -0,0 +1,46 @@
+pub fn get_item_tier(item: azalea_registry::Item) -> Option<Tier> {
+ use azalea_registry::Item::*;
+ Some(match item {
+ WoodenPickaxe | WoodenShovel | WoodenAxe | WoodenHoe | WoodenSword => Tier::Wood,
+ StonePickaxe | StoneShovel | StoneAxe | StoneHoe | StoneSword => Tier::Stone,
+ IronPickaxe | IronShovel | IronAxe | IronHoe | IronSword => Tier::Iron,
+ DiamondPickaxe | DiamondShovel | DiamondAxe | DiamondHoe | DiamondSword => Tier::Diamond,
+ GoldenPickaxe | GoldenShovel | GoldenAxe | GoldenHoe | GoldenSword => Tier::Gold,
+ NetheritePickaxe | NetheriteShovel | NetheriteAxe | NetheriteHoe | NetheriteSword => {
+ Tier::Netherite
+ }
+ _ => return None,
+ })
+}
+
+pub enum Tier {
+ Wood,
+ Stone,
+ Iron,
+ Diamond,
+ Gold,
+ Netherite,
+}
+
+impl Tier {
+ pub fn level(&self) -> u8 {
+ match self {
+ Tier::Wood => 0,
+ Tier::Stone => 1,
+ Tier::Iron => 2,
+ Tier::Diamond => 3,
+ Tier::Gold => 0, // gold is the same tier as wood
+ Tier::Netherite => 4,
+ }
+ }
+ pub fn speed(&self) -> f32 {
+ match self {
+ Tier::Wood => 2.,
+ Tier::Stone => 4.,
+ Tier::Iron => 6.,
+ Tier::Diamond => 8.,
+ Tier::Gold => 12.,
+ Tier::Netherite => 9.,
+ }
+ }
+}
diff --git a/azalea-entity/Cargo.toml b/azalea-entity/Cargo.toml
new file mode 100644
index 00000000..c2a405fe
--- /dev/null
+++ b/azalea-entity/Cargo.toml
@@ -0,0 +1,25 @@
+[package]
+name = "azalea-entity"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+azalea-block = { version = "0.7.0", path = "../azalea-block" }
+azalea-buf = { version = "0.7.0", path = "../azalea-buf" }
+azalea-chat = { version = "0.7.0", path = "../azalea-chat" }
+azalea-core = { version = "0.7.0", path = "../azalea-core" }
+azalea-inventory = { version = "0.7.0", path = "../azalea-inventory" }
+azalea-nbt = { version = "0.7.0", path = "../azalea-nbt" }
+azalea-registry = { version = "0.7.0", path = "../azalea-registry" }
+azalea-world = { version = "0.7.0", path = "../azalea-world" }
+bevy_app = "0.11.0"
+bevy_ecs = "0.11.0"
+derive_more = "0.99.17"
+enum-as-inner = "0.6.0"
+log = "0.4.19"
+nohash-hasher = "0.2.0"
+parking_lot = "0.12.1"
+thiserror = "1.0.43"
+uuid = "1.4.0"
diff --git a/azalea-world/src/entity/attributes.rs b/azalea-entity/src/attributes.rs
index 97b890dc..97b890dc 100644
--- a/azalea-world/src/entity/attributes.rs
+++ b/azalea-entity/src/attributes.rs
diff --git a/azalea-world/src/entity/data.rs b/azalea-entity/src/data.rs
index 31d4ca2f..4f6d8492 100755
--- a/azalea-world/src/entity/data.rs
+++ b/azalea-entity/src/data.rs
@@ -4,7 +4,7 @@ use azalea_buf::{
BufReadError, McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable,
};
use azalea_chat::FormattedText;
-use azalea_core::{BlockPos, Direction, GlobalPos, Particle, Vec3};
+use azalea_core::{particle::Particle, BlockPos, Direction, GlobalPos, Vec3};
use azalea_inventory::ItemSlot;
use bevy_ecs::component::Component;
use derive_more::Deref;
diff --git a/azalea-world/src/entity/dimensions.rs b/azalea-entity/src/dimensions.rs
index 5e716307..5e716307 100755
--- a/azalea-world/src/entity/dimensions.rs
+++ b/azalea-entity/src/dimensions.rs
diff --git a/azalea-entity/src/effects.rs b/azalea-entity/src/effects.rs
new file mode 100644
index 00000000..9cc750e5
--- /dev/null
+++ b/azalea-entity/src/effects.rs
@@ -0,0 +1,26 @@
+// TODO
+
+// pub struct ActiveEffects(HashMap<azalea_registry::MobEffect, MobEffectData>);
+
+/// Returns the level of the given effect, or `None` if the effect is not
+/// active. The lowest level is 0.
+pub fn get_effect(_effect: azalea_registry::MobEffect) -> Option<u32> {
+ // TODO
+ None
+}
+
+pub fn get_dig_speed_amplifier() -> Option<u32> {
+ let effect_plus_one = u32::max(
+ get_effect(azalea_registry::MobEffect::Haste)
+ .map(|x| x + 1)
+ .unwrap_or_default(),
+ get_effect(azalea_registry::MobEffect::ConduitPower)
+ .map(|x| x + 1)
+ .unwrap_or_default(),
+ );
+ if effect_plus_one > 0 {
+ Some(effect_plus_one - 1)
+ } else {
+ None
+ }
+}
diff --git a/azalea-entity/src/enchantments.rs b/azalea-entity/src/enchantments.rs
new file mode 100644
index 00000000..fd238bf2
--- /dev/null
+++ b/azalea-entity/src/enchantments.rs
@@ -0,0 +1,8 @@
+pub fn get_enchant_level(
+ _enchantment: azalea_registry::Enchantment,
+ _player_inventory: &azalea_inventory::Menu,
+) -> u32 {
+ // TODO
+
+ 0
+}
diff --git a/azalea-world/src/entity/info.rs b/azalea-entity/src/info.rs
index 03b72f94..18021d36 100644
--- a/azalea-world/src/entity/info.rs
+++ b/azalea-entity/src/info.rs
@@ -1,14 +1,8 @@
//! Implement things relating to entity datas, like an index of uuids to
//! entities.
-use crate::{
- deduplicate_entities, deduplicate_local_entities,
- entity::{
- self, add_dead, update_bounding_box, EntityUuid, MinecraftEntityId, Position, WorldName,
- },
- update_entity_by_id_index, update_uuid_index, InstanceContainer, PartialInstance,
-};
use azalea_core::ChunkPos;
+use azalea_world::{InstanceContainer, InstanceName, MinecraftEntityId, PartialInstance};
use bevy_app::{App, Plugin, PostUpdate, PreUpdate, Update};
use bevy_ecs::{
component::Component,
@@ -20,7 +14,6 @@ use bevy_ecs::{
};
use derive_more::{Deref, DerefMut};
use log::{debug, warn};
-use nohash_hasher::IntMap;
use parking_lot::RwLock;
use std::{
collections::{HashMap, HashSet},
@@ -29,6 +22,15 @@ use std::{
};
use uuid::Uuid;
+use crate::{
+ add_dead,
+ systems::{
+ deduplicate_entities, deduplicate_local_entities, update_entity_by_id_index,
+ update_fluid_on_eyes, update_uuid_index,
+ },
+ update_bounding_box, EntityUuid, LastSentPosition, Position,
+};
+
use super::{Local, LookDirection};
/// A Bevy [`SystemSet`] for various types of entity updates.
@@ -75,6 +77,7 @@ impl Plugin for EntityPlugin {
add_dead,
update_bounding_box,
clamp_look_direction,
+ update_fluid_on_eyes,
),
),
)
@@ -109,33 +112,6 @@ fn debug_new_entity(query: Query<(Entity, Option<&Local>), Added<MinecraftEntity
// "updates received" if not, then we simply increment our local "updates
// received" and do nothing else
-/// Keep track of certain metadatas that are only relevant for this partial
-/// world.
-#[derive(Debug, Default)]
-pub struct PartialEntityInfos {
- // note: using MinecraftEntityId for entity ids is acceptable here since
- // there's no chance of collisions here
- /// The entity id of the player that owns this partial world. This will
- /// make [`RelativeEntityUpdate`] pretend the entity doesn't exist so
- /// it doesn't get modified from outside sources.
- pub owner_entity: Option<Entity>,
- /// A counter for each entity that tracks how many updates we've observed
- /// for it.
- ///
- /// This is used for shared worlds (i.e. swarms), to make sure we don't
- /// update entities twice on accident.
- pub updates_received: IntMap<MinecraftEntityId, u32>,
-}
-
-impl PartialEntityInfos {
- pub fn new(owner_entity: Option<Entity>) -> Self {
- Self {
- owner_entity,
- updates_received: IntMap::default(),
- }
- }
-}
-
/// An [`EntityCommand`] that applies a "relative update" to an entity, which
/// means this update won't be run multiple times by different clients in the
/// same world.
@@ -211,15 +187,7 @@ impl EntityInfos {
/// Update the chunk position indexes in [`EntityInfos`].
fn update_entity_chunk_positions(
- mut query: Query<
- (
- Entity,
- &entity::Position,
- &mut entity::LastSentPosition,
- &entity::WorldName,
- ),
- Changed<entity::Position>,
- >,
+ mut query: Query<(Entity, &Position, &mut LastSentPosition, &InstanceName), Changed<Position>>,
instance_container: Res<InstanceContainer>,
) {
for (entity, pos, last_pos, world_name) in query.iter_mut() {
@@ -288,7 +256,7 @@ fn remove_despawned_entities_from_indexes(
mut commands: Commands,
mut entity_infos: ResMut<EntityInfos>,
instance_container: Res<InstanceContainer>,
- query: Query<(Entity, &EntityUuid, &Position, &WorldName, &LoadedBy), Changed<LoadedBy>>,
+ query: Query<(Entity, &EntityUuid, &Position, &InstanceName, &LoadedBy), Changed<LoadedBy>>,
) {
for (entity, uuid, position, world_name, loaded_by) in &query {
let world_lock = instance_container.get(world_name).unwrap();
diff --git a/azalea-world/src/entity/mod.rs b/azalea-entity/src/lib.rs
index d1d29a5a..53e8bfdb 100644
--- a/azalea-world/src/entity/mod.rs
+++ b/azalea-entity/src/lib.rs
@@ -3,15 +3,18 @@
pub mod attributes;
mod data;
mod dimensions;
+mod effects;
+mod enchantments;
mod info;
pub mod metadata;
-
-use crate::ChunkStorage;
+pub mod mining;
+mod systems;
use self::{attributes::AttributeInstance, metadata::Health};
pub use attributes::Attributes;
use azalea_block::BlockState;
use azalea_core::{BlockPos, ChunkPos, ResourceLocation, Vec3, AABB};
+use azalea_world::{ChunkStorage, InstanceName};
use bevy_ecs::{
bundle::Bundle,
component::Component,
@@ -23,23 +26,12 @@ pub use data::*;
use derive_more::{Deref, DerefMut};
pub use dimensions::{update_bounding_box, EntityDimensions};
pub use info::{
- clamp_look_direction, EntityInfos, EntityPlugin, EntityUpdateSet, LoadedBy, PartialEntityInfos,
+ clamp_look_direction, EntityInfos, EntityPlugin, EntityUpdateSet, LoadedBy,
RelativeEntityUpdate,
};
use std::fmt::Debug;
use uuid::Uuid;
-/// An entity ID used by Minecraft. These are not guaranteed to be unique in
-/// shared worlds, that's what [`Entity`] is for.
-#[derive(Component, Copy, Clone, Debug, PartialEq, Eq, Deref, DerefMut)]
-pub struct MinecraftEntityId(pub u32);
-impl std::hash::Hash for MinecraftEntityId {
- fn hash<H: std::hash::Hasher>(&self, hasher: &mut H) {
- hasher.write_u32(self.0);
- }
-}
-impl nohash_hasher::IsEnabled for MinecraftEntityId {}
-
pub fn move_relative(
physics: &mut Physics,
direction: &LookDirection,
@@ -197,11 +189,6 @@ impl From<&LastSentPosition> for BlockPos {
}
}
-/// The name of the world the entity is in. If two entities share the same world
-/// name, we assume they're in the same world.
-#[derive(Component, Clone, Debug, PartialEq, Deref, DerefMut)]
-pub struct WorldName(pub ResourceLocation);
-
/// A component for entities that can jump.
///
/// If this is true, the entity will try to jump every tick. (It's equivalent to
@@ -303,7 +290,7 @@ pub struct EntityKind(pub azalea_registry::EntityKind);
pub struct EntityBundle {
pub kind: EntityKind,
pub uuid: EntityUuid,
- pub world_name: WorldName,
+ pub world_name: InstanceName,
pub position: Position,
pub last_sent_position: LastSentPosition,
pub physics: Physics,
@@ -311,6 +298,7 @@ pub struct EntityBundle {
pub eye_height: EyeHeight,
pub attributes: Attributes,
pub jumping: Jumping,
+ pub fluid_on_eyes: FluidOnEyes,
}
impl EntityBundle {
@@ -330,7 +318,7 @@ impl EntityBundle {
Self {
kind: EntityKind(kind),
uuid: EntityUuid(uuid),
- world_name: WorldName(world_name),
+ world_name: InstanceName(world_name),
position: Position(pos),
last_sent_position: LastSentPosition(pos),
physics: Physics {
@@ -359,6 +347,7 @@ impl EntityBundle {
},
jumping: Jumping(false),
+ fluid_on_eyes: FluidOnEyes(azalea_registry::Fluid::Empty),
}
}
}
@@ -375,6 +364,9 @@ pub struct PlayerBundle {
#[derive(Component)]
pub struct Local;
+#[derive(Component, Clone, Debug, PartialEq, Deref, DerefMut)]
+pub struct FluidOnEyes(azalea_registry::Fluid);
+
// #[cfg(test)]
// mod tests {
// use super::*;
diff --git a/azalea-world/src/entity/metadata.rs b/azalea-entity/src/metadata.rs
index ed7aa40c..2f6a4870 100644
--- a/azalea-world/src/entity/metadata.rs
+++ b/azalea-entity/src/metadata.rs
@@ -8,7 +8,7 @@ use super::{
SnifferState, VillagerData,
};
use azalea_chat::FormattedText;
-use azalea_core::{BlockPos, Direction, Particle, Vec3};
+use azalea_core::{particle::Particle, BlockPos, Direction, Vec3};
use azalea_inventory::ItemSlot;
use bevy_ecs::{bundle::Bundle, component::Component};
use derive_more::{Deref, DerefMut};
diff --git a/azalea-entity/src/mining.rs b/azalea-entity/src/mining.rs
new file mode 100644
index 00000000..a2f869cf
--- /dev/null
+++ b/azalea-entity/src/mining.rs
@@ -0,0 +1,170 @@
+use azalea_block::{Block, BlockBehavior};
+use azalea_core::tier::get_item_tier;
+use azalea_registry as registry;
+
+use crate::{effects, enchantments, FluidOnEyes, Physics};
+
+pub fn get_mine_progress(
+ block: &dyn Block,
+ held_item: registry::Item,
+ player_inventory: &azalea_inventory::Menu,
+ fluid_on_eyes: &FluidOnEyes,
+ physics: &Physics,
+) -> f32 {
+ // public float getDestroyProgress(BlockState blockState, Player player,
+ // BlockGetter world, BlockPos blockPos) { float destroySpeed =
+ // blockState.getDestroySpeed(world, blockPos); if (destroySpeed ==
+ // -1.0F) { return 0.0F;
+ // } else {
+ // int divider = player.hasCorrectToolForDrops(blockState) ? 30 : 100;
+ // return player.getDestroySpeed(blockState) / destroySpeed /
+ // (float)divider; }
+ // }
+
+ let block_behavior: BlockBehavior = block.behavior();
+
+ let destroy_time = block_behavior.destroy_time;
+ if destroy_time == -1. {
+ return 0.;
+ }
+ let divider = if has_correct_tool_for_drops(block, held_item) {
+ 30
+ } else {
+ 100
+ };
+
+ (destroy_speed(
+ block.as_registry_block(),
+ held_item,
+ player_inventory,
+ fluid_on_eyes,
+ physics,
+ ) / destroy_time)
+ / divider as f32
+}
+
+fn has_correct_tool_for_drops(block: &dyn Block, tool: registry::Item) -> bool {
+ if !block.behavior().requires_correct_tool_for_drops {
+ return true;
+ }
+ let registry_block = block.as_registry_block();
+ if tool == registry::Item::Shears {
+ matches!(
+ registry_block,
+ registry::Block::Cobweb | registry::Block::RedstoneWire | registry::Block::Tripwire
+ )
+ } else if registry::tags::items::SWORDS.contains(&tool) {
+ registry_block == registry::Block::Cobweb
+ } else if registry::tags::items::PICKAXES.contains(&tool)
+ || registry::tags::items::SHOVELS.contains(&tool)
+ || registry::tags::items::HOES.contains(&tool)
+ || registry::tags::items::AXES.contains(&tool)
+ {
+ let tier = get_item_tier(tool).expect("all pickaxes and shovels should be matched");
+ let tier_level = tier.level();
+ !((tier_level < 3 && registry::tags::blocks::NEEDS_DIAMOND_TOOL.contains(&registry_block))
+ || (tier_level < 2
+ && registry::tags::blocks::NEEDS_IRON_TOOL.contains(&registry_block))
+ || (tier_level < 1
+ && registry::tags::blocks::NEEDS_STONE_TOOL.contains(&registry_block)))
+ } else {
+ false
+ }
+}
+
+/// Returns the destroy speed of the given block with the given tool, taking
+/// into account enchantments and effects. If the player is not holding anything
+/// then `tool` should be `Item::Air`.
+fn destroy_speed(
+ block: registry::Block,
+ tool: registry::Item,
+ player_inventory: &azalea_inventory::Menu,
+ fluid_on_eyes: &FluidOnEyes,
+ physics: &Physics,
+) -> f32 {
+ let mut base_destroy_speed = base_destroy_speed(block, tool);
+
+ // add efficiency enchantment
+ if base_destroy_speed > 1. {
+ let efficiency_level =
+ enchantments::get_enchant_level(registry::Enchantment::Efficiency, player_inventory);
+ if efficiency_level > 0 && tool != registry::Item::Air {
+ base_destroy_speed += (efficiency_level * efficiency_level + 1) as f32;
+ }
+ }
+
+ if let Some(dig_speed_amplifier) = effects::get_dig_speed_amplifier() {
+ base_destroy_speed *= 1. + (dig_speed_amplifier + 1) as f32 * 0.2;
+ }
+
+ if let Some(dig_slowdown) = effects::get_effect(registry::MobEffect::MiningFatigue) {
+ let multiplier = match dig_slowdown {
+ 0 => 0.3,
+ 1 => 0.09,
+ 2 => 0.0027,
+ _ => 8.1E-4,
+ };
+ base_destroy_speed *= multiplier;
+ }
+
+ if registry::tags::fluids::WATER.contains(fluid_on_eyes)
+ && enchantments::get_enchant_level(registry::Enchantment::AquaAffinity, player_inventory)
+ == 0
+ {
+ base_destroy_speed /= 5.;
+ }
+
+ if !physics.on_ground {
+ base_destroy_speed /= 5.;
+ }
+
+ base_destroy_speed
+}
+
+fn base_destroy_speed(block: registry::Block, tool: registry::Item) -> f32 {
+ if tool == registry::Item::Shears {
+ if block == registry::Block::Cobweb || registry::tags::blocks::LEAVES.contains(&block) {
+ 15.
+ } else if registry::tags::blocks::WOOL.contains(&block) {
+ 5.
+ } else if matches!(block, registry::Block::Vine | registry::Block::GlowLichen) {
+ 2.
+ } else {
+ 1.
+ }
+ } else if registry::tags::items::SWORDS.contains(&tool) {
+ if block == registry::Block::Cobweb {
+ 15.
+ } else if registry::tags::blocks::SWORD_EFFICIENT.contains(&block) {
+ 1.5
+ } else {
+ 1.
+ }
+ } else if registry::tags::items::PICKAXES.contains(&tool) {
+ if registry::tags::blocks::MINEABLE_PICKAXE.contains(&block) {
+ get_item_tier(tool).unwrap().speed()
+ } else {
+ 1.
+ }
+ } else if registry::tags::items::SHOVELS.contains(&tool) {
+ if registry::tags::blocks::MINEABLE_SHOVEL.contains(&block) {
+ get_item_tier(tool).unwrap().speed()
+ } else {
+ 1.
+ }
+ } else if registry::tags::items::HOES.contains(&tool) {
+ if registry::tags::blocks::MINEABLE_HOE.contains(&block) {
+ get_item_tier(tool).unwrap().speed()
+ } else {
+ 1.
+ }
+ } else if registry::tags::items::AXES.contains(&tool) {
+ if registry::tags::blocks::MINEABLE_AXE.contains(&block) {
+ get_item_tier(tool).unwrap().speed()
+ } else {
+ 1.
+ }
+ } else {
+ 1.
+ }
+}
diff --git a/azalea-entity/src/systems.rs b/azalea-entity/src/systems.rs
new file mode 100644
index 00000000..3fa8c4d5
--- /dev/null
+++ b/azalea-entity/src/systems.rs
@@ -0,0 +1,181 @@
+use azalea_core::{BlockPos, Vec3};
+use azalea_world::{InstanceContainer, InstanceName, MinecraftEntityId};
+use bevy_ecs::prelude::*;
+use log::{debug, error, info};
+
+use crate::{EntityInfos, EntityUuid, EyeHeight, FluidOnEyes, LoadedBy, Local, Position};
+
+/// Remove new entities that have the same id as an existing entity, and
+/// increase the reference counts.
+///
+/// This is the reason why spawning entities into the ECS when you get a spawn
+/// entity packet is okay. This system will make sure the new entity gets
+/// combined into the old one.
+#[allow(clippy::type_complexity)]
+pub fn deduplicate_entities(
+ mut commands: Commands,
+ mut query: Query<
+ (Entity, &MinecraftEntityId, &InstanceName),
+ (Changed<MinecraftEntityId>, Without<Local>),
+ >,
+ mut loaded_by_query: Query<&mut LoadedBy>,
+ instance_container: Res<InstanceContainer>,
+) {
+ // if this entity already exists, remove it
+ for (new_entity, id, world_name) in query.iter_mut() {
+ if let Some(world_lock) = instance_container.get(world_name) {
+ let world = world_lock.write();
+ if let Some(old_entity) = world.entity_by_id.get(id) {
+ if old_entity == &new_entity {
+ continue;
+ }
+
+ // this entity already exists!!! remove the one we just added but increase
+ // the reference count
+ let new_loaded_by = loaded_by_query
+ .get(new_entity)
+ .unwrap_or_else(|_| panic!(
+ "Entities should always have the LoadedBy component ({new_entity:?} did not)"
+ ))
+ .clone();
+ let old_loaded_by = loaded_by_query.get_mut(*old_entity);
+ // merge them if possible
+ if let Ok(mut old_loaded_by) = old_loaded_by {
+ old_loaded_by.extend(new_loaded_by.iter());
+ }
+ commands.entity(new_entity).despawn();
+ info!(
+ "Entity with id {id:?} / {new_entity:?} already existed in the world, merging it with {old_entity:?}"
+ );
+ break;
+ }
+ } else {
+ error!("Entity was inserted into a world that doesn't exist.");
+ }
+ }
+}
+
+// when a local entity is added, if there was already an entity with the same id
+// then delete the old entity
+#[allow(clippy::type_complexity)]
+pub fn deduplicate_local_entities(
+ mut commands: Commands,
+ mut query: Query<
+ (Entity, &MinecraftEntityId, &InstanceName),
+ (Changed<MinecraftEntityId>, With<Local>),
+ >,
+ instance_container: Res<InstanceContainer>,
+) {
+ // if this entity already exists, remove the old one
+ for (new_entity, id, world_name) in query.iter_mut() {
+ if let Some(world_lock) = instance_container.get(world_name) {
+ let world = world_lock.write();
+ if let Some(old_entity) = world.entity_by_id.get(id) {
+ if old_entity == &new_entity {
+ // lol
+ continue;
+ }
+
+ commands.entity(*old_entity).despawn();
+ debug!(
+ "Added local entity {id:?} / {new_entity:?} but already existed in world as {old_entity:?}, despawning {old_entity:?}"
+ );
+ break;
+ }
+ } else {
+ error!("Entity was inserted into a world that doesn't exist.");
+ }
+ }
+}
+
+pub fn update_uuid_index(
+ mut entity_infos: ResMut<EntityInfos>,
+ query: Query<(Entity, &EntityUuid, Option<&Local>), Changed<EntityUuid>>,
+) {
+ for (entity, &uuid, local) in query.iter() {
+ // only add it if it doesn't already exist in
+ // entity_infos.entity_by_uuid
+ if local.is_none() {
+ if let Some(old_entity) = entity_infos.entity_by_uuid.get(&uuid) {
+ debug!(
+ "Entity with UUID {uuid:?} already existed in the world, not adding to
+ index (old ecs id: {old_entity:?} / new ecs id: {entity:?})"
+ );
+ continue;
+ }
+ }
+ entity_infos.entity_by_uuid.insert(*uuid, entity);
+ }
+}
+
+// /// Clear all entities in a chunk. This will not clear them from the
+// /// shared storage unless there are no other references to them.
+// pub fn clear_entities_in_chunk(
+// mut commands: Commands,
+// partial_entity_infos: &mut PartialEntityInfos,
+// chunk: &ChunkPos,
+// instance_container: &WorldContainer,
+// world_name: &InstanceName,
+// mut query: Query<(&MinecraftEntityId, &mut ReferenceCount)>,
+// ) { let world_lock = instance_container.get(world_name).unwrap(); let world =
+// world_lock.read();
+
+// if let Some(entities) = world.entities_by_chunk.get(chunk).cloned() {
+// for &entity in &entities {
+// let (id, mut reference_count) = query.get_mut(entity).unwrap();
+// if partial_entity_infos.loaded_entity_ids.remove(id) {
+// // decrease the reference count
+// **reference_count -= 1;
+// }
+// }
+// }
+// }
+
+/// System to keep the entity_by_id index up-to-date.
+pub fn update_entity_by_id_index(
+ mut query: Query<
+ (Entity, &MinecraftEntityId, &InstanceName, Option<&Local>),
+ Changed<MinecraftEntityId>,
+ >,
+ instance_container: Res<InstanceContainer>,
+) {
+ for (entity, id, world_name, local) in query.iter_mut() {
+ let world_lock = instance_container.get(world_name).unwrap();
+ let mut world = world_lock.write();
+ if local.is_none() {
+ if let Some(old_entity) = world.entity_by_id.get(id) {
+ debug!(
+ "Entity with ID {id:?} already existed in the world, not adding to
+ index (old ecs id: {old_entity:?} / new ecs id: {entity:?})"
+ );
+ continue;
+ }
+ }
+ world.entity_by_id.insert(*id, entity);
+ debug!("Added {entity:?} to {world_name:?} with {id:?}.");
+ }
+}
+
+pub fn update_fluid_on_eyes(
+ mut query: Query<(&mut FluidOnEyes, &Position, &EyeHeight, &InstanceName)>,
+ instance_container: Res<InstanceContainer>,
+) {
+ for (mut fluid_on_eyes, position, eye_height, instance_name) in query.iter_mut() {
+ let Some(instance) = instance_container.get(instance_name) else {
+ continue;
+ };
+
+ let adjusted_eye_y = position.y + (**eye_height as f64) - 0.1111111119389534;
+ let eye_block_pos = BlockPos::from(Vec3::new(position.x, adjusted_eye_y, position.z));
+ let fluid_at_eye = instance
+ .read()
+ .get_fluid_state(&eye_block_pos)
+ .unwrap_or_default();
+ let fluid_cutoff_y = eye_block_pos.y as f64 + (fluid_at_eye.height as f64 / 16f64);
+ if fluid_cutoff_y > adjusted_eye_y {
+ **fluid_on_eyes = fluid_at_eye.fluid;
+ } else {
+ **fluid_on_eyes = azalea_registry::Fluid::Empty;
+ }
+ }
+}
diff --git a/azalea-inventory/src/lib.rs b/azalea-inventory/src/lib.rs
index 29d06fd9..dbbf1f5c 100644
--- a/azalea-inventory/src/lib.rs
+++ b/azalea-inventory/src/lib.rs
@@ -10,8 +10,8 @@ use azalea_inventory_macros::declare_menus;
pub use slot::{ItemSlot, ItemSlotData};
// TODO: remove this here and in azalea-inventory-macros when rust makes
-// Default be implemented for all array sizes (since right now it's only up to
-// 32)
+// Default be implemented for all array sizes
+// https://github.com/rust-lang/rust/issues/61415
/// A fixed-size list of [`ItemSlot`]s.
#[derive(Debug, Clone)]
diff --git a/azalea-physics/Cargo.toml b/azalea-physics/Cargo.toml
index 7209420c..135681cc 100644
--- a/azalea-physics/Cargo.toml
+++ b/azalea-physics/Cargo.toml
@@ -11,6 +11,7 @@ version = "0.7.0"
[dependencies]
azalea-block = { path = "../azalea-block", version = "^0.7.0" }
azalea-core = { path = "../azalea-core", version = "^0.7.0" }
+azalea-entity = { version = "0.1.0", path = "../azalea-entity" }
azalea-inventory = { version = "0.7.0", path = "../azalea-inventory" }
azalea-registry = { path = "../azalea-registry", version = "^0.7.0" }
azalea-world = { path = "../azalea-world", version = "^0.7.0" }
diff --git a/azalea-physics/src/clip.rs b/azalea-physics/src/clip.rs
index ca85c32a..d6e0f6bb 100644
--- a/azalea-physics/src/clip.rs
+++ b/azalea-physics/src/clip.rs
@@ -1,5 +1,5 @@
use azalea_block::BlockState;
-use azalea_core::{lerp, BlockHitResult, BlockPos, Direction, Vec3, EPSILON};
+use azalea_core::{math::lerp, BlockHitResult, BlockPos, Direction, Vec3, EPSILON};
use azalea_inventory::ItemSlot;
use azalea_world::ChunkStorage;
use bevy_ecs::entity::Entity;
diff --git a/azalea-physics/src/collision/mergers.rs b/azalea-physics/src/collision/mergers.rs
index 483cb55f..e2381c49 100755
--- a/azalea-physics/src/collision/mergers.rs
+++ b/azalea-physics/src/collision/mergers.rs
@@ -1,7 +1,10 @@
use std::{cmp::Ordering, convert::TryInto};
use super::CubePointRange;
-use azalea_core::{gcd, lcm, EPSILON};
+use azalea_core::{
+ math::{gcd, lcm},
+ EPSILON,
+};
#[derive(Debug)]
pub enum IndexMerger {
diff --git a/azalea-physics/src/collision/mod.rs b/azalea-physics/src/collision/mod.rs
index a99b5710..e24df378 100644
--- a/azalea-physics/src/collision/mod.rs
+++ b/azalea-physics/src/collision/mod.rs
@@ -5,7 +5,7 @@ mod shape;
mod world_collisions;
use azalea_core::{Axis, Vec3, AABB, EPSILON};
-use azalea_world::{entity, Instance, MoveEntityError};
+use azalea_world::{Instance, MoveEntityError};
pub use blocks::BlockWithShape;
pub use discrete_voxel_shape::*;
pub use shape::*;
@@ -49,7 +49,7 @@ pub enum MoverType {
// return var4;
// }
-fn collide(movement: &Vec3, world: &Instance, physics: &entity::Physics) -> Vec3 {
+fn collide(movement: &Vec3, world: &Instance, physics: &azalea_entity::Physics) -> Vec3 {
let entity_bounding_box = physics.bounding_box;
// TODO: get_entity_collisions
// let entity_collisions = world.get_entity_collisions(self,
@@ -71,8 +71,8 @@ pub fn move_colliding(
_mover_type: &MoverType,
movement: &Vec3,
world: &Instance,
- position: &mut entity::Position,
- physics: &mut entity::Physics,
+ position: &mut azalea_entity::Position,
+ physics: &mut azalea_entity::Physics,
) -> Result<(), MoveEntityError> {
// TODO: do all these
@@ -122,7 +122,7 @@ pub fn move_colliding(
// TODO: minecraft checks for a "minor" horizontal collision here
- let _block_pos_below = entity::on_pos_legacy(&world.chunks, position);
+ let _block_pos_below = azalea_entity::on_pos_legacy(&world.chunks, position);
// let _block_state_below = self
// .world
// .get_block_state(&block_pos_below)
diff --git a/azalea-physics/src/collision/shape.rs b/azalea-physics/src/collision/shape.rs
index 29c1b440..a39a86cf 100755
--- a/azalea-physics/src/collision/shape.rs
+++ b/azalea-physics/src/collision/shape.rs
@@ -1,7 +1,7 @@
use super::mergers::IndexMerger;
use crate::collision::{BitSetDiscreteVoxelShape, DiscreteVoxelShape, AABB};
use azalea_core::{
- binary_search, Axis, AxisCycle, BlockHitResult, BlockPos, Direction, Vec3, EPSILON,
+ math::binary_search, Axis, AxisCycle, BlockHitResult, BlockPos, Direction, Vec3, EPSILON,
};
use std::{cmp, num::NonZeroU32};
diff --git a/azalea-physics/src/collision/world_collisions.rs b/azalea-physics/src/collision/world_collisions.rs
index aa55150e..e640f0ce 100644
--- a/azalea-physics/src/collision/world_collisions.rs
+++ b/azalea-physics/src/collision/world_collisions.rs
@@ -71,9 +71,7 @@ impl<'a> Iterator for BlockCollisions<'a> {
}
let chunk = self.get_chunk(item.pos.x, item.pos.z);
- let Some(chunk) = chunk else {
- continue
- };
+ let Some(chunk) = chunk else { continue };
let pos = item.pos;
let block_state: BlockState = chunk
diff --git a/azalea-physics/src/lib.rs b/azalea-physics/src/lib.rs
index 0d9f3be4..6b451dd6 100644
--- a/azalea-physics/src/lib.rs
+++ b/azalea-physics/src/lib.rs
@@ -6,13 +6,12 @@ pub mod collision;
use azalea_block::{Block, BlockState};
use azalea_core::{BlockPos, Vec3};
-use azalea_world::{
- entity::{
- clamp_look_direction, metadata::Sprinting, move_relative, Attributes, Jumping, Local,
- LookDirection, Physics, Position, WorldName,
- },
- Instance, InstanceContainer,
+use azalea_entity::update_bounding_box;
+use azalea_entity::{
+ clamp_look_direction, metadata::Sprinting, move_relative, Attributes, Jumping, Local,
+ LookDirection, Physics, Position,
};
+use azalea_world::{Instance, InstanceContainer, InstanceName};
use bevy_app::{App, FixedUpdate, Plugin, Update};
use bevy_ecs::{
entity::Entity,
@@ -35,7 +34,7 @@ impl Plugin for PhysicsPlugin {
.add_systems(
Update,
force_jump_listener
- .before(azalea_world::entity::update_bounding_box)
+ .before(update_bounding_box)
.after(clamp_look_direction),
)
.add_systems(FixedUpdate, (ai_step, travel).chain().in_set(PhysicsSet));
@@ -51,7 +50,7 @@ fn travel(
&mut LookDirection,
&mut Position,
&Attributes,
- &WorldName,
+ &InstanceName,
),
With<Local>,
>,
@@ -176,7 +175,7 @@ pub fn force_jump_listener(
&Position,
&LookDirection,
&Sprinting,
- &WorldName,
+ &InstanceName,
)>,
instance_container: Res<InstanceContainer>,
mut events: EventReader<ForceJumpEvent>,
@@ -327,10 +326,8 @@ mod tests {
use super::*;
use azalea_core::{ChunkPos, ResourceLocation};
- use azalea_world::{
- entity::{EntityBundle, EntityPlugin, MinecraftEntityId},
- Chunk, PartialInstance,
- };
+ use azalea_entity::{EntityBundle, EntityPlugin};
+ use azalea_world::{Chunk, MinecraftEntityId, PartialInstance};
use bevy_app::App;
use bevy_time::fixed_timestep::FixedTime;
use uuid::Uuid;
diff --git a/azalea-protocol/Cargo.toml b/azalea-protocol/Cargo.toml
index ebe49e64..50e6bbae 100644
--- a/azalea-protocol/Cargo.toml
+++ b/azalea-protocol/Cargo.toml
@@ -25,6 +25,7 @@ azalea-core = { path = "../azalea-core", optional = true, version = "^0.7.0", fe
"serde",
] }
azalea-crypto = { path = "../azalea-crypto", version = "^0.7.0" }
+azalea-entity = { version = "0.1.0", path = "../azalea-entity" }
azalea-inventory = { version = "0.7.0", path = "../azalea-inventory" }
azalea-nbt = { path = "../azalea-nbt", version = "^0.7.0", features = [
"serde",
diff --git a/azalea-protocol/src/packets/game/clientbound_add_entity_packet.rs b/azalea-protocol/src/packets/game/clientbound_add_entity_packet.rs
index 75f3f4dc..0f2686e6 100755
--- a/azalea-protocol/src/packets/game/clientbound_add_entity_packet.rs
+++ b/azalea-protocol/src/packets/game/clientbound_add_entity_packet.rs
@@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use azalea_core::{ResourceLocation, Vec3};
+use azalea_entity::{metadata::apply_default_metadata, EntityBundle};
use azalea_protocol_macros::ClientboundGamePacket;
-use azalea_world::entity::{metadata::apply_default_metadata, EntityBundle};
use uuid::Uuid;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
diff --git a/azalea-protocol/src/packets/game/clientbound_add_player_packet.rs b/azalea-protocol/src/packets/game/clientbound_add_player_packet.rs
index 4cbeb1b9..45ab4584 100755
--- a/azalea-protocol/src/packets/game/clientbound_add_player_packet.rs
+++ b/azalea-protocol/src/packets/game/clientbound_add_player_packet.rs
@@ -1,8 +1,8 @@
use azalea_buf::McBuf;
use azalea_core::{ResourceLocation, Vec3};
+use azalea_entity::{metadata::PlayerMetadataBundle, EntityBundle, PlayerBundle};
use azalea_protocol_macros::ClientboundGamePacket;
use azalea_registry::EntityKind;
-use azalea_world::entity::{metadata::PlayerMetadataBundle, EntityBundle, PlayerBundle};
use uuid::Uuid;
/// This packet is sent by the server when a player comes into visible range,
diff --git a/azalea-protocol/src/packets/game/clientbound_level_particles_packet.rs b/azalea-protocol/src/packets/game/clientbound_level_particles_packet.rs
index 6efe1f97..7cae607e 100755
--- a/azalea-protocol/src/packets/game/clientbound_level_particles_packet.rs
+++ b/azalea-protocol/src/packets/game/clientbound_level_particles_packet.rs
@@ -1,5 +1,5 @@
use azalea_buf::{BufReadError, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable};
-use azalea_core::ParticleData;
+use azalea_core::particle::ParticleData;
use azalea_protocol_macros::ClientboundGamePacket;
use std::io::{Cursor, Write};
diff --git a/azalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs
index d133eeea..7d869650 100755
--- a/azalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs
+++ b/azalea-protocol/src/packets/game/clientbound_set_entity_data_packet.rs
@@ -1,6 +1,6 @@
use azalea_buf::McBuf;
+use azalea_entity::EntityMetadataItems;
use azalea_protocol_macros::ClientboundGamePacket;
-use azalea_world::entity::EntityMetadataItems;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSetEntityDataPacket {
diff --git a/azalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs
index 4c24ba64..1468a77f 100755
--- a/azalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs
+++ b/azalea-protocol/src/packets/game/clientbound_update_attributes_packet.rs
@@ -1,7 +1,7 @@
use azalea_buf::McBuf;
use azalea_core::ResourceLocation;
+use azalea_entity::attributes::AttributeModifier;
use azalea_protocol_macros::ClientboundGamePacket;
-use azalea_world::entity::attributes::AttributeModifier;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundUpdateAttributesPacket {
diff --git a/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs
index 8c24bdbe..7acffb7a 100755
--- a/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs
+++ b/azalea-protocol/src/packets/game/clientbound_update_recipes_packet.rs
@@ -221,10 +221,12 @@ impl McBufWritable for Recipe {
impl McBufReadable for Recipe {
fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let recipe_serializer_name = ResourceLocation::read_from(buf)?;
- let Ok(recipe_serializer) =
- RecipeSerializer::from_str(&recipe_serializer_name.to_string()) else {
- return Err(BufReadError::UnexpectedStringEnumVariant { id: recipe_serializer_name.to_string() });
- };
+ let Ok(recipe_serializer) = RecipeSerializer::from_str(&recipe_serializer_name.to_string())
+ else {
+ return Err(BufReadError::UnexpectedStringEnumVariant {
+ id: recipe_serializer_name.to_string(),
+ });
+ };
let identifier = ResourceLocation::read_from(buf)?;
// rust doesn't let us match ResourceLocation so we have to do a big
diff --git a/azalea-registry/Cargo.toml b/azalea-registry/Cargo.toml
index af36946f..8046894b 100644
--- a/azalea-registry/Cargo.toml
+++ b/azalea-registry/Cargo.toml
@@ -11,6 +11,7 @@ version = "0.7.0"
[dependencies]
azalea-buf = { path = "../azalea-buf", version = "^0.7.0" }
azalea-registry-macros = { path = "./azalea-registry-macros", version = "^0.7.0" }
+once_cell = "1.18.0"
serde = { version = "^1.0", optional = true }
[features]
diff --git a/azalea-registry/src/lib.rs b/azalea-registry/src/lib.rs
index 081b3c3e..c1edcd3f 100755
--- a/azalea-registry/src/lib.rs
+++ b/azalea-registry/src/lib.rs
@@ -5,6 +5,8 @@
// auto-generated (so you can add doc comments to the registry enums if you
// want)
+pub mod tags;
+
use std::io::{Cursor, Write};
use azalea_buf::{BufReadError, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable};
diff --git a/azalea-registry/src/tags/blocks.rs b/azalea-registry/src/tags/blocks.rs
new file mode 100644
index 00000000..aae39c07
--- /dev/null
+++ b/azalea-registry/src/tags/blocks.rs
@@ -0,0 +1,3374 @@
+// This file was generated by codegen/lib/code/tags.py, don't edit it manually!
+
+use std::collections::HashSet;
+
+use once_cell::sync::Lazy;
+
+use crate::Block;
+
+pub static MINEABLE_SHOVEL: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Clay,
+ Block::Dirt,
+ Block::CoarseDirt,
+ Block::Podzol,
+ Block::Farmland,
+ Block::GrassBlock,
+ Block::Gravel,
+ Block::Mycelium,
+ Block::Sand,
+ Block::RedSand,
+ Block::SnowBlock,
+ Block::Snow,
+ Block::SoulSand,
+ Block::DirtPath,
+ Block::WhiteConcretePowder,
+ Block::OrangeConcretePowder,
+ Block::MagentaConcretePowder,
+ Block::LightBlueConcretePowder,
+ Block::YellowConcretePowder,
+ Block::LimeConcretePowder,
+ Block::PinkConcretePowder,
+ Block::GrayConcretePowder,
+ Block::LightGrayConcretePowder,
+ Block::CyanConcretePowder,
+ Block::PurpleConcretePowder,
+ Block::BlueConcretePowder,
+ Block::BrownConcretePowder,
+ Block::GreenConcretePowder,
+ Block::RedConcretePowder,
+ Block::BlackConcretePowder,
+ Block::SoulSoil,
+ Block::RootedDirt,
+ Block::MuddyMangroveRoots,
+ Block::Mud,
+ Block::SuspiciousSand,
+ Block::SuspiciousGravel,
+ ])
+});
+pub static MINEABLE_AXE: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::NoteBlock,
+ Block::AttachedMelonStem,
+ Block::AttachedPumpkinStem,
+ Block::Azalea,
+ Block::Bamboo,
+ Block::Barrel,
+ Block::BeeNest,
+ Block::Beehive,
+ Block::Beetroots,
+ Block::BigDripleafStem,
+ Block::BigDripleaf,
+ Block::Bookshelf,
+ Block::BrownMushroomBlock,
+ Block::BrownMushroom,
+ Block::Campfire,
+ Block::Carrots,
+ Block::CartographyTable,
+ Block::CarvedPumpkin,
+ Block::CaveVinesPlant,
+ Block::CaveVines,
+ Block::Chest,
+ Block::ChorusFlower,
+ Block::ChorusPlant,
+ Block::Cocoa,
+ Block::Composter,
+ Block::CraftingTable,
+ Block::CrimsonFungus,
+ Block::DaylightDetector,
+ Block::DeadBush,
+ Block::Fern,
+ Block::FletchingTable,
+ Block::GlowLichen,
+ Block::Grass,
+ Block::HangingRoots,
+ Block::JackOLantern,
+ Block::Jukebox,
+ Block::Ladder,
+ Block::LargeFern,
+ Block::Lectern,
+ Block::LilyPad,
+ Block::Loom,
+ Block::MelonStem,
+ Block::Melon,
+ Block::MushroomStem,
+ Block::NetherWart,
+ Block::Potatoes,
+ Block::PumpkinStem,
+ Block::Pumpkin,
+ Block::RedMushroomBlock,
+ Block::RedMushroom,
+ Block::Scaffolding,
+ Block::SmallDripleaf,
+ Block::SmithingTable,
+ Block::SoulCampfire,
+ Block::SporeBlossom,
+ Block::SugarCane,
+ Block::SweetBerryBush,
+ Block::TallGrass,
+ Block::TrappedChest,
+ Block::TwistingVinesPlant,
+ Block::TwistingVines,
+ Block::Vine,
+ Block::WarpedFungus,
+ Block::WeepingVinesPlant,
+ Block::WeepingVines,
+ Block::Wheat,
+ Block::MangroveRoots,
+ Block::BambooMosaic,
+ Block::BambooMosaicSlab,
+ Block::BambooMosaicStairs,
+ Block::ChiseledBookshelf,
+ Block::WhiteBanner,
+ Block::OrangeBanner,
+ Block::MagentaBanner,
+ Block::LightBlueBanner,
+ Block::YellowBanner,
+ Block::LimeBanner,
+ Block::PinkBanner,
+ Block::GrayBanner,
+ Block::LightGrayBanner,
+ Block::CyanBanner,
+ Block::PurpleBanner,
+ Block::BlueBanner,
+ Block::BrownBanner,
+ Block::GreenBanner,
+ Block::RedBanner,
+ Block::BlackBanner,
+ Block::WhiteWallBanner,
+ Block::OrangeWallBanner,
+ Block::MagentaWallBanner,
+ Block::LightBlueWallBanner,
+ Block::YellowWallBanner,
+ Block::LimeWallBanner,
+ Block::PinkWallBanner,
+ Block::GrayWallBanner,
+ Block::LightGrayWallBanner,
+ Block::CyanWallBanner,
+ Block::PurpleWallBanner,
+ Block::BlueWallBanner,
+ Block::BrownWallBanner,
+ Block::GreenWallBanner,
+ Block::RedWallBanner,
+ Block::BlackWallBanner,
+ Block::AcaciaFenceGate,
+ Block::BirchFenceGate,
+ Block::DarkOakFenceGate,
+ Block::JungleFenceGate,
+ Block::OakFenceGate,
+ Block::SpruceFenceGate,
+ Block::CrimsonFenceGate,
+ Block::WarpedFenceGate,
+ Block::MangroveFenceGate,
+ Block::BambooFenceGate,
+ Block::CherryFenceGate,
+ Block::OakPlanks,
+ Block::SprucePlanks,
+ Block::BirchPlanks,
+ Block::JunglePlanks,
+ Block::AcaciaPlanks,
+ Block::DarkOakPlanks,
+ Block::CrimsonPlanks,
+ Block::WarpedPlanks,
+ Block::MangrovePlanks,
+ Block::BambooPlanks,
+ Block::CherryPlanks,
+ Block::OakSapling,
+ Block::SpruceSapling,
+ Block::BirchSapling,
+ Block::JungleSapling,
+ Block::AcaciaSapling,
+ Block::DarkOakSapling,
+ Block::Azalea,
+ Block::FloweringAzalea,
+ Block::MangrovePropagule,
+ Block::CherrySapling,
+ Block::OakButton,
+ Block::SpruceButton,
+ Block::BirchButton,
+ Block::JungleButton,
+ Block::AcaciaButton,
+ Block::DarkOakButton,
+ Block::CrimsonButton,
+ Block::WarpedButton,
+ Block::MangroveButton,
+ Block::BambooButton,
+ Block::CherryButton,
+ Block::OakDoor,
+ Block::SpruceDoor,
+ Block::BirchDoor,
+ Block::JungleDoor,
+ Block::AcaciaDoor,
+ Block::DarkOakDoor,
+ Block::CrimsonDoor,
+ Block::WarpedDoor,
+ Block::MangroveDoor,
+ Block::BambooDoor,
+ Block::CherryDoor,
+ Block::OakFence,
+ Block::AcaciaFence,
+ Block::DarkOakFence,
+ Block::SpruceFence,
+ Block::BirchFence,
+ Block::JungleFence,
+ Block::CrimsonFence,
+ Block::WarpedFence,
+ Block::MangroveFence,
+ Block::BambooFence,
+ Block::CherryFence,
+ Block::OakPressurePlate,
+ Block::SprucePressurePlate,
+ Block::BirchPressurePlate,
+ Block::JunglePressurePlate,
+ Block::AcaciaPressurePlate,
+ Block::DarkOakPressurePlate,
+ Block::CrimsonPressurePlate,
+ Block::WarpedPressurePlate,
+ Block::MangrovePressurePlate,
+ Block::BambooPressurePlate,
+ Block::CherryPressurePlate,
+ Block::OakSlab,
+ Block::SpruceSlab,
+ Block::BirchSlab,
+ Block::JungleSlab,
+ Block::AcaciaSlab,
+ Block::DarkOakSlab,
+ Block::CrimsonSlab,
+ Block::WarpedSlab,
+ Block::MangroveSlab,
+ Block::BambooSlab,
+ Block::CherrySlab,
+ Block::OakStairs,
+ Block::SpruceStairs,
+ Block::BirchStairs,
+ Block::JungleStairs,
+ Block::AcaciaStairs,
+ Block::DarkOakStairs,
+ Block::CrimsonStairs,
+ Block::WarpedStairs,
+ Block::MangroveStairs,
+ Block::BambooStairs,
+ Block::CherryStairs,
+ Block::AcaciaTrapdoor,
+ Block::BirchTrapdoor,
+ Block::DarkOakTrapdoor,
+ Block::JungleTrapdoor,
+ Block::OakTrapdoor,
+ Block::SpruceTrapdoor,
+ Block::CrimsonTrapdoor,
+ Block::WarpedTrapdoor,
+ Block::MangroveTrapdoor,
+ Block::BambooTrapdoor,
+ Block::CherryTrapdoor,
+ Block::BambooBlock,
+ Block::StrippedBambooBlock,
+ Block::CrimsonStem,
+ Block::StrippedCrimsonStem,
+ Block::CrimsonHyphae,
+ Block::StrippedCrimsonHyphae,
+ Block::WarpedStem,
+ Block::StrippedWarpedStem,
+ Block::WarpedHyphae,
+ Block::StrippedWarpedHyphae,
+ Block::OakSign,
+ Block::SpruceSign,
+ Block::BirchSign,
+ Block::AcaciaSign,
+ Block::JungleSign,
+ Block::DarkOakSign,
+ Block::CrimsonSign,
+ Block::WarpedSign,
+ Block::MangroveSign,
+ Block::BambooSign,
+ Block::CherrySign,
+ Block::OakWallSign,
+ Block::SpruceWallSign,
+ Block::BirchWallSign,
+ Block::AcaciaWallSign,
+ Block::JungleWallSign,
+ Block::DarkOakWallSign,
+ Block::CrimsonWallSign,
+ Block::WarpedWallSign,
+ Block::MangroveWallSign,
+ Block::BambooWallSign,
+ Block::CherryWallSign,
+ Block::OakHangingSign,
+ Block::SpruceHangingSign,
+ Block::BirchHangingSign,
+ Block::AcaciaHangingSign,
+ Block::CherryHangingSign,
+ Block::JungleHangingSign,
+ Block::DarkOakHangingSign,
+ Block::CrimsonHangingSign,
+ Block::WarpedHangingSign,
+ Block::MangroveHangingSign,
+ Block::BambooHangingSign,
+ Block::OakWallHangingSign,
+ Block::SpruceWallHangingSign,
+ Block::BirchWallHangingSign,
+ Block::AcaciaWallHangingSign,
+ Block::CherryWallHangingSign,
+ Block::JungleWallHangingSign,
+ Block::DarkOakWallHangingSign,
+ Block::CrimsonWallHangingSign,
+ Block::WarpedWallHangingSign,
+ Block::MangroveWallHangingSign,
+ Block::BambooWallHangingSign,
+ Block::DarkOakLog,
+ Block::DarkOakWood,
+ Block::StrippedDarkOakLog,
+ Block::StrippedDarkOakWood,
+ Block::OakLog,
+ Block::OakWood,
+ Block::StrippedOakLog,
+ Block::StrippedOakWood,
+ Block::AcaciaLog,
+ Block::AcaciaWood,
+ Block::StrippedAcaciaLog,
+ Block::StrippedAcaciaWood,
+ Block::BirchLog,
+ Block::BirchWood,
+ Block::StrippedBirchLog,
+ Block::StrippedBirchWood,
+ Block::JungleLog,
+ Block::JungleWood,
+ Block::StrippedJungleLog,
+ Block::StrippedJungleWood,
+ Block::SpruceLog,
+ Block::SpruceWood,
+ Block::StrippedSpruceLog,
+ Block::StrippedSpruceWood,
+ Block::MangroveLog,
+ Block::MangroveWood,
+ Block::StrippedMangroveLog,
+ Block::StrippedMangroveWood,
+ Block::CherryLog,
+ Block::CherryWood,
+ Block::StrippedCherryLog,
+ Block::StrippedCherryWood,
+ ])
+});
+pub static MINEABLE_HOE: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::NetherWartBlock,
+ Block::WarpedWartBlock,
+ Block::HayBlock,
+ Block::DriedKelpBlock,
+ Block::Target,
+ Block::Shroomlight,
+ Block::Sponge,
+ Block::WetSponge,
+ Block::JungleLeaves,
+ Block::OakLeaves,
+ Block::SpruceLeaves,
+ Block::DarkOakLeaves,
+ Block::AcaciaLeaves,
+ Block::BirchLeaves,
+ Block::AzaleaLeaves,
+ Block::FloweringAzaleaLeaves,
+ Block::MangroveLeaves,
+ Block::SculkSensor,
+ Block::CalibratedSculkSensor,
+ Block::MossBlock,
+ Block::MossCarpet,
+ Block::Sculk,
+ Block::SculkCatalyst,
+ Block::SculkVein,
+ Block::SculkShrieker,
+ Block::PinkPetals,
+ Block::CherryLeaves,
+ ])
+});
+pub static MINEABLE_PICKAXE: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Stone,
+ Block::Granite,
+ Block::PolishedGranite,
+ Block::Diorite,
+ Block::PolishedDiorite,
+ Block::Andesite,
+ Block::PolishedAndesite,
+ Block::Cobblestone,
+ Block::GoldOre,
+ Block::DeepslateGoldOre,
+ Block::IronOre,
+ Block::DeepslateIronOre,
+ Block::CoalOre,
+ Block::DeepslateCoalOre,
+ Block::NetherGoldOre,
+ Block::LapisOre,
+ Block::DeepslateLapisOre,
+ Block::LapisBlock,
+ Block::Dispenser,
+ Block::Sandstone,
+ Block::ChiseledSandstone,
+ Block::CutSandstone,
+ Block::GoldBlock,
+ Block::IronBlock,
+ Block::Bricks,
+ Block::MossyCobblestone,
+ Block::Obsidian,
+ Block::Spawner,
+ Block::DiamondOre,
+ Block::DeepslateDiamondOre,
+ Block::DiamondBlock,
+ Block::Furnace,
+ Block::CobblestoneStairs,
+ Block::StonePressurePlate,
+ Block::IronDoor,
+ Block::RedstoneOre,
+ Block::DeepslateRedstoneOre,
+ Block::Netherrack,
+ Block::Basalt,
+ Block::PolishedBasalt,
+ Block::StoneBricks,
+ Block::MossyStoneBricks,
+ Block::CrackedStoneBricks,
+ Block::ChiseledStoneBricks,
+ Block::IronBars,
+ Block::Chain,
+ Block::BrickStairs,
+ Block::StoneBrickStairs,
+ Block::NetherBricks,
+ Block::NetherBrickFence,
+ Block::NetherBrickStairs,
+ Block::EnchantingTable,
+ Block::BrewingStand,
+ Block::EndStone,
+ Block::SandstoneStairs,
+ Block::EmeraldOre,
+ Block::DeepslateEmeraldOre,
+ Block::EnderChest,
+ Block::EmeraldBlock,
+ Block::LightWeightedPressurePlate,
+ Block::HeavyWeightedPressurePlate,
+ Block::RedstoneBlock,
+ Block::NetherQuartzOre,
+ Block::Hopper,
+ Block::QuartzBlock,
+ Block::ChiseledQuartzBlock,
+ Block::QuartzPillar,
+ Block::QuartzStairs,
+ Block::Dropper,
+ Block::WhiteTerracotta,
+ Block::OrangeTerracotta,
+ Block::MagentaTerracotta,
+ Block::LightBlueTerracotta,
+ Block::YellowTerracotta,
+ Block::LimeTerracotta,
+ Block::PinkTerracotta,
+ Block::GrayTerracotta,
+ Block::LightGrayTerracotta,
+ Block::CyanTerracotta,
+ Block::PurpleTerracotta,
+ Block::BlueTerracotta,
+ Block::BrownTerracotta,
+ Block::GreenTerracotta,
+ Block::RedTerracotta,
+ Block::BlackTerracotta,
+ Block::IronTrapdoor,
+ Block::Prismarine,
+ Block::PrismarineBricks,
+ Block::DarkPrismarine,
+ Block::PrismarineStairs,
+ Block::PrismarineBrickStairs,
+ Block::DarkPrismarineStairs,
+ Block::PrismarineSlab,
+ Block::PrismarineBrickSlab,
+ Block::DarkPrismarineSlab,
+ Block::Terracotta,
+ Block::CoalBlock,
+ Block::RedSandstone,
+ Block::ChiseledRedSandstone,
+ Block::CutRedSandstone,
+ Block::RedSandstoneStairs,
+ Block::StoneSlab,
+ Block::SmoothStoneSlab,
+ Block::SandstoneSlab,
+ Block::CutSandstoneSlab,
+ Block::PetrifiedOakSlab,
+ Block::CobblestoneSlab,
+ Block::BrickSlab,
+ Block::StoneBrickSlab,
+ Block::NetherBrickSlab,
+ Block::QuartzSlab,
+ Block::RedSandstoneSlab,
+ Block::CutRedSandstoneSlab,
+ Block::PurpurSlab,
+ Block::SmoothStone,
+ Block::SmoothSandstone,
+ Block::SmoothQuartz,
+ Block::SmoothRedSandstone,
+ Block::PurpurBlock,
+ Block::PurpurPillar,
+ Block::PurpurStairs,
+ Block::EndStoneBricks,
+ Block::MagmaBlock,
+ Block::RedNetherBricks,
+ Block::BoneBlock,
+ Block::Observer,
+ Block::WhiteGlazedTerracotta,
+ Block::OrangeGlazedTerracotta,
+ Block::MagentaGlazedTerracotta,
+ Block::LightBlueGlazedTerracotta,
+ Block::YellowGlazedTerracotta,
+ Block::LimeGlazedTerracotta,
+ Block::PinkGlazedTerracotta,
+ Block::GrayGlazedTerracotta,
+ Block::LightGrayGlazedTerracotta,
+ Block::CyanGlazedTerracotta,
+ Block::PurpleGlazedTerracotta,
+ Block::BlueGlazedTerracotta,
+ Block::BrownGlazedTerracotta,
+ Block::GreenGlazedTerracotta,
+ Block::RedGlazedTerracotta,
+ Block::BlackGlazedTerracotta,
+ Block::WhiteConcrete,
+ Block::OrangeConcrete,
+ Block::MagentaConcrete,
+ Block::LightBlueConcrete,
+ Block::YellowConcrete,
+ Block::LimeConcrete,
+ Block::PinkConcrete,
+ Block::GrayConcrete,
+ Block::LightGrayConcrete,
+ Block::CyanConcrete,
+ Block::PurpleConcrete,
+ Block::BlueConcrete,
+ Block::BrownConcrete,
+ Block::GreenConcrete,
+ Block::RedConcrete,
+ Block::BlackConcrete,
+ Block::DeadTubeCoralBlock,
+ Block::DeadBrainCoralBlock,
+ Block::DeadBubbleCoralBlock,
+ Block::DeadFireCoralBlock,
+ Block::DeadHornCoralBlock,
+ Block::TubeCoralBlock,
+ Block::BrainCoralBlock,
+ Block::BubbleCoralBlock,
+ Block::FireCoralBlock,
+ Block::HornCoralBlock,
+ Block::DeadTubeCoral,
+ Block::DeadBrainCoral,
+ Block::DeadBubbleCoral,
+ Block::DeadFireCoral,
+ Block::DeadHornCoral,
+ Block::DeadTubeCoralFan,
+ Block::DeadBrainCoralFan,
+ Block::DeadBubbleCoralFan,
+ Block::DeadFireCoralFan,
+ Block::DeadHornCoralFan,
+ Block::DeadTubeCoralWallFan,
+ Block::DeadBrainCoralWallFan,
+ Block::DeadBubbleCoralWallFan,
+ Block::DeadFireCoralWallFan,
+ Block::DeadHornCoralWallFan,
+ Block::PolishedGraniteStairs,
+ Block::SmoothRedSandstoneStairs,
+ Block::MossyStoneBrickStairs,
+ Block::PolishedDioriteStairs,
+ Block::MossyCobblestoneStairs,
+ Block::EndStoneBrickStairs,
+ Block::StoneStairs,
+ Block::SmoothSandstoneStairs,
+ Block::SmoothQuartzStairs,
+ Block::GraniteStairs,
+ Block::AndesiteStairs,
+ Block::RedNetherBrickStairs,
+ Block::PolishedAndesiteStairs,
+ Block::DioriteStairs,
+ Block::PolishedGraniteSlab,
+ Block::SmoothRedSandstoneSlab,
+ Block::MossyStoneBrickSlab,
+ Block::PolishedDioriteSlab,
+ Block::MossyCobblestoneSlab,
+ Block::EndStoneBrickSlab,
+ Block::SmoothSandstoneSlab,
+ Block::SmoothQuartzSlab,
+ Block::GraniteSlab,
+ Block::AndesiteSlab,
+ Block::RedNetherBrickSlab,
+ Block::PolishedAndesiteSlab,
+ Block::DioriteSlab,
+ Block::Smoker,
+ Block::BlastFurnace,
+ Block::Grindstone,
+ Block::Stonecutter,
+ Block::Bell,
+ Block::Lantern,
+ Block::SoulLantern,
+ Block::WarpedNylium,
+ Block::CrimsonNylium,
+ Block::NetheriteBlock,
+ Block::AncientDebris,
+ Block::CryingObsidian,
+ Block::RespawnAnchor,
+ Block::Lodestone,
+ Block::Blackstone,
+ Block::BlackstoneStairs,
+ Block::BlackstoneSlab,
+ Block::PolishedBlackstone,
+ Block::PolishedBlackstoneBricks,
+ Block::CrackedPolishedBlackstoneBricks,
+ Block::ChiseledPolishedBlackstone,
+ Block::PolishedBlackstoneBrickSlab,
+ Block::PolishedBlackstoneBrickStairs,
+ Block::GildedBlackstone,
+ Block::PolishedBlackstoneStairs,
+ Block::PolishedBlackstoneSlab,
+ Block::PolishedBlackstonePressurePlate,
+ Block::ChiseledNetherBricks,
+ Block::CrackedNetherBricks,
+ Block::QuartzBricks,
+ Block::Tuff,
+ Block::Calcite,
+ Block::OxidizedCopper,
+ Block::WeatheredCopper,
+ Block::ExposedCopper,
+ Block::CopperBlock,
+ Block::CopperOre,
+ Block::DeepslateCopperOre,
+ Block::OxidizedCutCopper,
+ Block::WeatheredCutCopper,
+ Block::ExposedCutCopper,
+ Block::CutCopper,
+ Block::OxidizedCutCopperStairs,
+ Block::WeatheredCutCopperStairs,
+ Block::ExposedCutCopperStairs,
+ Block::CutCopperStairs,
+ Block::OxidizedCutCopperSlab,
+ Block::WeatheredCutCopperSlab,
+ Block::ExposedCutCopperSlab,
+ Block::CutCopperSlab,
+ Block::WaxedCopperBlock,
+ Block::WaxedWeatheredCopper,
+ Block::WaxedExposedCopper,
+ Block::WaxedOxidizedCopper,
+ Block::WaxedOxidizedCutCopper,
+ Block::WaxedWeatheredCutCopper,
+ Block::WaxedExposedCutCopper,
+ Block::WaxedCutCopper,
+ Block::WaxedOxidizedCutCopperStairs,
+ Block::WaxedWeatheredCutCopperStairs,
+ Block::WaxedExposedCutCopperStairs,
+ Block::WaxedCutCopperStairs,
+ Block::WaxedOxidizedCutCopperSlab,
+ Block::WaxedWeatheredCutCopperSlab,
+ Block::WaxedExposedCutCopperSlab,
+ Block::WaxedCutCopperSlab,
+ Block::LightningRod,
+ Block::PointedDripstone,
+ Block::DripstoneBlock,
+ Block::Deepslate,
+ Block::CobbledDeepslate,
+ Block::CobbledDeepslateStairs,
+ Block::CobbledDeepslateSlab,
+ Block::PolishedDeepslate,
+ Block::PolishedDeepslateStairs,
+ Block::PolishedDeepslateSlab,
+ Block::DeepslateTiles,
+ Block::DeepslateTileStairs,
+ Block::DeepslateTileSlab,
+ Block::DeepslateBricks,
+ Block::DeepslateBrickStairs,
+ Block::DeepslateBrickSlab,
+ Block::ChiseledDeepslate,
+ Block::CrackedDeepslateBricks,
+ Block::CrackedDeepslateTiles,
+ Block::SmoothBasalt,
+ Block::RawIronBlock,
+ Block::RawCopperBlock,
+ Block::RawGoldBlock,
+ Block::Ice,
+ Block::PackedIce,
+ Block::BlueIce,
+ Block::Piston,
+ Block::StickyPiston,
+ Block::PistonHead,
+ Block::AmethystCluster,
+ Block::SmallAmethystBud,
+ Block::MediumAmethystBud,
+ Block::LargeAmethystBud,
+ Block::AmethystBlock,
+ Block::BuddingAmethyst,
+ Block::InfestedCobblestone,
+ Block::InfestedChiseledStoneBricks,
+ Block::InfestedCrackedStoneBricks,
+ Block::InfestedDeepslate,
+ Block::InfestedStone,
+ Block::InfestedMossyStoneBricks,
+ Block::InfestedStoneBricks,
+ Block::Conduit,
+ Block::MudBricks,
+ Block::MudBrickStairs,
+ Block::MudBrickSlab,
+ Block::PackedMud,
+ Block::StoneButton,
+ Block::PolishedBlackstoneButton,
+ Block::CobblestoneWall,
+ Block::MossyCobblestoneWall,
+ Block::BrickWall,
+ Block::PrismarineWall,
+ Block::RedSandstoneWall,
+ Block::MossyStoneBrickWall,
+ Block::GraniteWall,
+ Block::StoneBrickWall,
+ Block::NetherBrickWall,
+ Block::AndesiteWall,
+ Block::RedNetherBrickWall,
+ Block::SandstoneWall,
+ Block::EndStoneBrickWall,
+ Block::DioriteWall,
+ Block::BlackstoneWall,
+ Block::PolishedBlackstoneBrickWall,
+ Block::PolishedBlackstoneWall,
+ Block::CobbledDeepslateWall,
+ Block::PolishedDeepslateWall,
+ Block::DeepslateTileWall,
+ Block::DeepslateBrickWall,
+ Block::MudBrickWall,
+ Block::ShulkerBox,
+ Block::BlackShulkerBox,
+ Block::BlueShulkerBox,
+ Block::BrownShulkerBox,
+ Block::CyanShulkerBox,
+ Block::GrayShulkerBox,
+ Block::GreenShulkerBox,
+ Block::LightBlueShulkerBox,
+ Block::LightGrayShulkerBox,
+ Block::LimeShulkerBox,
+ Block::MagentaShulkerBox,
+ Block::OrangeShulkerBox,
+ Block::PinkShulkerBox,
+ Block::PurpleShulkerBox,
+ Block::RedShulkerBox,
+ Block::WhiteShulkerBox,
+ Block::YellowShulkerBox,
+ Block::Anvil,
+ Block::ChippedAnvil,
+ Block::DamagedAnvil,
+ Block::Cauldron,
+ Block::WaterCauldron,
+ Block::LavaCauldron,
+ Block::PowderSnowCauldron,
+ Block::Rail,
+ Block::PoweredRail,
+ Block::DetectorRail,
+ Block::ActivatorRail,
+ ])
+});
+pub static WOODEN_FENCES: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::OakFence,
+ Block::AcaciaFence,
+ Block::DarkOakFence,
+ Block::SpruceFence,
+ Block::BirchFence,
+ Block::JungleFence,
+ Block::CrimsonFence,
+ Block::WarpedFence,
+ Block::MangroveFence,
+ Block::BambooFence,
+ Block::CherryFence,
+ ])
+});
+pub static UNDERWATER_BONEMEALS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Seagrass,
+ Block::TubeCoralFan,
+ Block::BrainCoralFan,
+ Block::BubbleCoralFan,
+ Block::FireCoralFan,
+ Block::HornCoralFan,
+ Block::TubeCoralWallFan,
+ Block::BrainCoralWallFan,
+ Block::BubbleCoralWallFan,
+ Block::FireCoralWallFan,
+ Block::HornCoralWallFan,
+ Block::TubeCoral,
+ Block::BrainCoral,
+ Block::BubbleCoral,
+ Block::FireCoral,
+ Block::HornCoral,
+ ])
+});
+pub static INSIDE_STEP_SOUND_BLOCKS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::PowderSnow,
+ Block::SculkVein,
+ Block::GlowLichen,
+ Block::LilyPad,
+ Block::SmallAmethystBud,
+ Block::PinkPetals,
+ ])
+});
+pub static ACACIA_LOGS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::AcaciaLog,
+ Block::AcaciaWood,
+ Block::StrippedAcaciaLog,
+ Block::StrippedAcaciaWood,
+ ])
+});
+pub static SMALL_DRIPLEAF_PLACEABLE: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::Clay, Block::MossBlock]));
+pub static WALL_CORALS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::TubeCoralWallFan,
+ Block::BrainCoralWallFan,
+ Block::BubbleCoralWallFan,
+ Block::FireCoralWallFan,
+ Block::HornCoralWallFan,
+ ])
+});
+pub static BAMBOO_PLANTABLE_ON: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Bamboo,
+ Block::BambooSapling,
+ Block::Gravel,
+ Block::SuspiciousGravel,
+ Block::Sand,
+ Block::RedSand,
+ Block::SuspiciousSand,
+ Block::SuspiciousSand,
+ Block::Dirt,
+ Block::GrassBlock,
+ Block::Podzol,
+ Block::CoarseDirt,
+ Block::Mycelium,
+ Block::RootedDirt,
+ Block::MossBlock,
+ Block::Mud,
+ Block::MuddyMangroveRoots,
+ ])
+});
+pub static SWORD_EFFICIENT: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Grass,
+ Block::Fern,
+ Block::DeadBush,
+ Block::Vine,
+ Block::GlowLichen,
+ Block::Sunflower,
+ Block::Lilac,
+ Block::RoseBush,
+ Block::Peony,
+ Block::TallGrass,
+ Block::LargeFern,
+ Block::HangingRoots,
+ Block::PitcherPlant,
+ Block::BrownMushroom,
+ Block::RedMushroom,
+ Block::SugarCane,
+ Block::Pumpkin,
+ Block::CarvedPumpkin,
+ Block::JackOLantern,
+ Block::Melon,
+ Block::AttachedPumpkinStem,
+ Block::AttachedMelonStem,
+ Block::LilyPad,
+ Block::Cocoa,
+ Block::PitcherCrop,
+ Block::SweetBerryBush,
+ Block::CaveVines,
+ Block::CaveVinesPlant,
+ Block::SporeBlossom,
+ Block::MossCarpet,
+ Block::PinkPetals,
+ Block::BigDripleaf,
+ Block::BigDripleafStem,
+ Block::SmallDripleaf,
+ Block::NetherWart,
+ Block::WarpedFungus,
+ Block::WarpedRoots,
+ Block::NetherSprouts,
+ Block::CrimsonFungus,
+ Block::WeepingVines,
+ Block::WeepingVinesPlant,
+ Block::TwistingVines,
+ Block::TwistingVinesPlant,
+ Block::CrimsonRoots,
+ Block::ChorusPlant,
+ Block::ChorusFlower,
+ Block::JungleLeaves,
+ Block::OakLeaves,
+ Block::SpruceLeaves,
+ Block::DarkOakLeaves,
+ Block::AcaciaLeaves,
+ Block::BirchLeaves,
+ Block::AzaleaLeaves,
+ Block::FloweringAzaleaLeaves,
+ Block::MangroveLeaves,
+ Block::CherryLeaves,
+ Block::OakSapling,
+ Block::SpruceSapling,
+ Block::BirchSapling,
+ Block::JungleSapling,
+ Block::AcaciaSapling,
+ Block::DarkOakSapling,
+ Block::Azalea,
+ Block::FloweringAzalea,
+ Block::MangrovePropagule,
+ Block::CherrySapling,
+ Block::Dandelion,
+ Block::Poppy,
+ Block::BlueOrchid,
+ Block::Allium,
+ Block::AzureBluet,
+ Block::RedTulip,
+ Block::OrangeTulip,
+ Block::WhiteTulip,
+ Block::PinkTulip,
+ Block::OxeyeDaisy,
+ Block::Cornflower,
+ Block::LilyOfTheValley,
+ Block::WitherRose,
+ Block::Torchflower,
+ Block::Beetroots,
+ Block::Carrots,
+ Block::Potatoes,
+ Block::Wheat,
+ Block::MelonStem,
+ Block::PumpkinStem,
+ Block::TorchflowerCrop,
+ Block::PitcherCrop,
+ ])
+});
+pub static SNOW_LAYER_CANNOT_SURVIVE_ON: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::Ice, Block::PackedIce, Block::Barrier]));
+pub static MUSHROOM_GROW_BLOCK: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Mycelium,
+ Block::Podzol,
+ Block::CrimsonNylium,
+ Block::WarpedNylium,
+ ])
+});
+pub static DEAD_BUSH_MAY_PLACE_ON: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Sand,
+ Block::RedSand,
+ Block::SuspiciousSand,
+ Block::SuspiciousSand,
+ Block::Terracotta,
+ Block::WhiteTerracotta,
+ Block::OrangeTerracotta,
+ Block::MagentaTerracotta,
+ Block::LightBlueTerracotta,
+ Block::YellowTerracotta,
+ Block::LimeTerracotta,
+ Block::PinkTerracotta,
+ Block::GrayTerracotta,
+ Block::LightGrayTerracotta,
+ Block::CyanTerracotta,
+ Block::PurpleTerracotta,
+ Block::BlueTerracotta,
+ Block::BrownTerracotta,
+ Block::GreenTerracotta,
+ Block::RedTerracotta,
+ Block::BlackTerracotta,
+ Block::Dirt,
+ Block::GrassBlock,
+ Block::Podzol,
+ Block::CoarseDirt,
+ Block::Mycelium,
+ Block::RootedDirt,
+ Block::MossBlock,
+ Block::Mud,
+ Block::MuddyMangroveRoots,
+ ])
+});
+pub static WOLVES_SPAWNABLE_ON: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::GrassBlock, Block::Snow, Block::SnowBlock]));
+pub static LUSH_GROUND_REPLACEABLE: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Clay,
+ Block::Gravel,
+ Block::Sand,
+ Block::Stone,
+ Block::Granite,
+ Block::Diorite,
+ Block::Andesite,
+ Block::Tuff,
+ Block::Deepslate,
+ Block::CaveVinesPlant,
+ Block::CaveVines,
+ Block::Dirt,
+ Block::GrassBlock,
+ Block::Podzol,
+ Block::CoarseDirt,
+ Block::Mycelium,
+ Block::RootedDirt,
+ Block::MossBlock,
+ Block::Mud,
+ Block::MuddyMangroveRoots,
+ ])
+});
+pub static PARROTS_SPAWNABLE_ON: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::GrassBlock,
+ Block::Air,
+ Block::JungleLeaves,
+ Block::OakLeaves,
+ Block::SpruceLeaves,
+ Block::DarkOakLeaves,
+ Block::AcaciaLeaves,
+ Block::BirchLeaves,
+ Block::AzaleaLeaves,
+ Block::FloweringAzaleaLeaves,
+ Block::MangroveLeaves,
+ Block::CherryLeaves,
+ Block::CrimsonStem,
+ Block::StrippedCrimsonStem,
+ Block::CrimsonHyphae,
+ Block::StrippedCrimsonHyphae,
+ Block::WarpedStem,
+ Block::StrippedWarpedStem,
+ Block::WarpedHyphae,
+ Block::StrippedWarpedHyphae,
+ Block::DarkOakLog,
+ Block::DarkOakWood,
+ Block::StrippedDarkOakLog,
+ Block::StrippedDarkOakWood,
+ Block::OakLog,
+ Block::OakWood,
+ Block::StrippedOakLog,
+ Block::StrippedOakWood,
+ Block::AcaciaLog,
+ Block::AcaciaWood,
+ Block::StrippedAcaciaLog,
+ Block::StrippedAcaciaWood,
+ Block::BirchLog,
+ Block::BirchWood,
+ Block::StrippedBirchLog,
+ Block::StrippedBirchWood,
+ Block::JungleLog,
+ Block::JungleWood,
+ Block::StrippedJungleLog,
+ Block::StrippedJungleWood,
+ Block::SpruceLog,
+ Block::SpruceWood,
+ Block::StrippedSpruceLog,
+ Block::StrippedSpruceWood,
+ Block::MangroveLog,
+ Block::MangroveWood,
+ Block::StrippedMangroveLog,
+ Block::StrippedMangroveWood,
+ Block::CherryLog,
+ Block::CherryWood,
+ Block::StrippedCherryLog,
+ Block::StrippedCherryWood,
+ ])
+});
+pub static WOODEN_SLABS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::OakSlab,
+ Block::SpruceSlab,
+ Block::BirchSlab,
+ Block::JungleSlab,
+ Block::AcaciaSlab,
+ Block::DarkOakSlab,
+ Block::CrimsonSlab,
+ Block::WarpedSlab,
+ Block::MangroveSlab,
+ Block::BambooSlab,
+ Block::CherrySlab,
+ ])
+});
+pub static WOODEN_STAIRS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::OakStairs,
+ Block::SpruceStairs,
+ Block::BirchStairs,
+ Block::JungleStairs,
+ Block::AcaciaStairs,
+ Block::DarkOakStairs,
+ Block::CrimsonStairs,
+ Block::WarpedStairs,
+ Block::MangroveStairs,
+ Block::BambooStairs,
+ Block::CherryStairs,
+ ])
+});
+pub static WALL_SIGNS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::OakWallSign,
+ Block::SpruceWallSign,
+ Block::BirchWallSign,
+ Block::AcaciaWallSign,
+ Block::JungleWallSign,
+ Block::DarkOakWallSign,
+ Block::CrimsonWallSign,
+ Block::WarpedWallSign,
+ Block::MangroveWallSign,
+ Block::BambooWallSign,
+ Block::CherryWallSign,
+ ])
+});
+pub static MANGROVE_LOGS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::MangroveLog,
+ Block::MangroveWood,
+ Block::StrippedMangroveLog,
+ Block::StrippedMangroveWood,
+ ])
+});
+pub static WITHER_IMMUNE: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Barrier,
+ Block::Bedrock,
+ Block::EndPortal,
+ Block::EndPortalFrame,
+ Block::EndGateway,
+ Block::CommandBlock,
+ Block::RepeatingCommandBlock,
+ Block::ChainCommandBlock,
+ Block::StructureBlock,
+ Block::Jigsaw,
+ Block::MovingPiston,
+ Block::Light,
+ Block::ReinforcedDeepslate,
+ ])
+});
+pub static DARK_OAK_LOGS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::DarkOakLog,
+ Block::DarkOakWood,
+ Block::StrippedDarkOakLog,
+ Block::StrippedDarkOakWood,
+ ])
+});
+pub static STONE_ORE_REPLACEABLES: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Stone,
+ Block::Granite,
+ Block::Diorite,
+ Block::Andesite,
+ ])
+});
+pub static EMERALD_ORES: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::EmeraldOre, Block::DeepslateEmeraldOre]));
+pub static TALL_FLOWERS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Sunflower,
+ Block::Lilac,
+ Block::Peony,
+ Block::RoseBush,
+ Block::PitcherPlant,
+ ])
+});
+pub static BEE_GROWABLES: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::SweetBerryBush,
+ Block::CaveVines,
+ Block::CaveVinesPlant,
+ Block::Beetroots,
+ Block::Carrots,
+ Block::Potatoes,
+ Block::Wheat,
+ Block::MelonStem,
+ Block::PumpkinStem,
+ Block::TorchflowerCrop,
+ Block::PitcherCrop,
+ ])
+});
+pub static DOORS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::IronDoor,
+ Block::OakDoor,
+ Block::SpruceDoor,
+ Block::BirchDoor,
+ Block::JungleDoor,
+ Block::AcaciaDoor,
+ Block::DarkOakDoor,
+ Block::CrimsonDoor,
+ Block::WarpedDoor,
+ Block::MangroveDoor,
+ Block::BambooDoor,
+ Block::CherryDoor,
+ ])
+});
+pub static BEDS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::RedBed,
+ Block::BlackBed,
+ Block::BlueBed,
+ Block::BrownBed,
+ Block::CyanBed,
+ Block::GrayBed,
+ Block::GreenBed,
+ Block::LightBlueBed,
+ Block::LightGrayBed,
+ Block::LimeBed,
+ Block::MagentaBed,
+ Block::OrangeBed,
+ Block::PinkBed,
+ Block::PurpleBed,
+ Block::WhiteBed,
+ Block::YellowBed,
+ ])
+});
+pub static BASE_STONE_OVERWORLD: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Stone,
+ Block::Granite,
+ Block::Diorite,
+ Block::Andesite,
+ Block::Tuff,
+ Block::Deepslate,
+ ])
+});
+pub static SNIFFER_EGG_HATCH_BOOST: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::MossBlock]));
+pub static VALID_SPAWN: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::GrassBlock, Block::Podzol]));
+pub static NEEDS_STONE_TOOL: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::IronBlock,
+ Block::RawIronBlock,
+ Block::IronOre,
+ Block::DeepslateIronOre,
+ Block::LapisBlock,
+ Block::LapisOre,
+ Block::DeepslateLapisOre,
+ Block::CopperBlock,
+ Block::RawCopperBlock,
+ Block::CopperOre,
+ Block::DeepslateCopperOre,
+ Block::CutCopperSlab,
+ Block::CutCopperStairs,
+ Block::CutCopper,
+ Block::WeatheredCopper,
+ Block::WeatheredCutCopperSlab,
+ Block::WeatheredCutCopperStairs,
+ Block::WeatheredCutCopper,
+ Block::OxidizedCopper,
+ Block::OxidizedCutCopperSlab,
+ Block::OxidizedCutCopperStairs,
+ Block::OxidizedCutCopper,
+ Block::ExposedCopper,
+ Block::ExposedCutCopperSlab,
+ Block::ExposedCutCopperStairs,
+ Block::ExposedCutCopper,
+ Block::WaxedCopperBlock,
+ Block::WaxedCutCopperSlab,
+ Block::WaxedCutCopperStairs,
+ Block::WaxedCutCopper,
+ Block::WaxedWeatheredCopper,
+ Block::WaxedWeatheredCutCopperSlab,
+ Block::WaxedWeatheredCutCopperStairs,
+ Block::WaxedWeatheredCutCopper,
+ Block::WaxedExposedCopper,
+ Block::WaxedExposedCutCopperSlab,
+ Block::WaxedExposedCutCopperStairs,
+ Block::WaxedExposedCutCopper,
+ Block::WaxedOxidizedCopper,
+ Block::WaxedOxidizedCutCopperSlab,
+ Block::WaxedOxidizedCutCopperStairs,
+ Block::WaxedOxidizedCutCopper,
+ Block::LightningRod,
+ ])
+});
+pub static SNIFFER_DIGGABLE_BLOCK: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Dirt,
+ Block::GrassBlock,
+ Block::Podzol,
+ Block::CoarseDirt,
+ Block::RootedDirt,
+ Block::MossBlock,
+ Block::Mud,
+ Block::MuddyMangroveRoots,
+ ])
+});
+pub static ANCIENT_CITY_REPLACEABLE: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Deepslate,
+ Block::DeepslateBricks,
+ Block::DeepslateTiles,
+ Block::DeepslateBrickSlab,
+ Block::DeepslateTileSlab,
+ Block::DeepslateBrickStairs,
+ Block::DeepslateTileWall,
+ Block::DeepslateBrickWall,
+ Block::CobbledDeepslate,
+ Block::CrackedDeepslateBricks,
+ Block::CrackedDeepslateTiles,
+ Block::GrayWool,
+ ])
+});
+pub static COPPER_ORES: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::CopperOre, Block::DeepslateCopperOre]));
+pub static WOODEN_PRESSURE_PLATES: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::OakPressurePlate,
+ Block::SprucePressurePlate,
+ Block::BirchPressurePlate,
+ Block::JunglePressurePlate,
+ Block::AcaciaPressurePlate,
+ Block::DarkOakPressurePlate,
+ Block::CrimsonPressurePlate,
+ Block::WarpedPressurePlate,
+ Block::MangrovePressurePlate,
+ Block::BambooPressurePlate,
+ Block::CherryPressurePlate,
+ ])
+});
+pub static NYLIUM: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::CrimsonNylium, Block::WarpedNylium]));
+pub static FEATURES_CANNOT_REPLACE: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Bedrock,
+ Block::Spawner,
+ Block::Chest,
+ Block::EndPortalFrame,
+ Block::ReinforcedDeepslate,
+ ])
+});
+pub static SAND: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Sand,
+ Block::RedSand,
+ Block::SuspiciousSand,
+ Block::SuspiciousSand,
+ ])
+});
+pub static LOGS_THAT_BURN: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::DarkOakLog,
+ Block::DarkOakWood,
+ Block::StrippedDarkOakLog,
+ Block::StrippedDarkOakWood,
+ Block::OakLog,
+ Block::OakWood,
+ Block::StrippedOakLog,
+ Block::StrippedOakWood,
+ Block::AcaciaLog,
+ Block::AcaciaWood,
+ Block::StrippedAcaciaLog,
+ Block::StrippedAcaciaWood,
+ Block::BirchLog,
+ Block::BirchWood,
+ Block::StrippedBirchLog,
+ Block::StrippedBirchWood,
+ Block::JungleLog,
+ Block::JungleWood,
+ Block::StrippedJungleLog,
+ Block::StrippedJungleWood,
+ Block::SpruceLog,
+ Block::SpruceWood,
+ Block::StrippedSpruceLog,
+ Block::StrippedSpruceWood,
+ Block::MangroveLog,
+ Block::MangroveWood,
+ Block::StrippedMangroveLog,
+ Block::StrippedMangroveWood,
+ Block::CherryLog,
+ Block::CherryWood,
+ Block::StrippedCherryLog,
+ Block::StrippedCherryWood,
+ ])
+});
+pub static CHERRY_LOGS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::CherryLog,
+ Block::CherryWood,
+ Block::StrippedCherryLog,
+ Block::StrippedCherryWood,
+ ])
+});
+pub static DAMPENS_VIBRATIONS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::WhiteWool,
+ Block::OrangeWool,
+ Block::MagentaWool,
+ Block::LightBlueWool,
+ Block::YellowWool,
+ Block::LimeWool,
+ Block::PinkWool,
+ Block::GrayWool,
+ Block::LightGrayWool,
+ Block::CyanWool,
+ Block::PurpleWool,
+ Block::BlueWool,
+ Block::BrownWool,
+ Block::GreenWool,
+ Block::RedWool,
+ Block::BlackWool,
+ Block::WhiteCarpet,
+ Block::OrangeCarpet,
+ Block::MagentaCarpet,
+ Block::LightBlueCarpet,
+ Block::YellowCarpet,
+ Block::LimeCarpet,
+ Block::PinkCarpet,
+ Block::GrayCarpet,
+ Block::LightGrayCarpet,
+ Block::CyanCarpet,
+ Block::PurpleCarpet,
+ Block::BlueCarpet,
+ Block::BrownCarpet,
+ Block::GreenCarpet,
+ Block::RedCarpet,
+ Block::BlackCarpet,
+ ])
+});
+pub static DIAMOND_ORES: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::DiamondOre, Block::DeepslateDiamondOre]));
+pub static WOOL: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::WhiteWool,
+ Block::OrangeWool,
+ Block::MagentaWool,
+ Block::LightBlueWool,
+ Block::YellowWool,
+ Block::LimeWool,
+ Block::PinkWool,
+ Block::GrayWool,
+ Block::LightGrayWool,
+ Block::CyanWool,
+ Block::PurpleWool,
+ Block::BlueWool,
+ Block::BrownWool,
+ Block::GreenWool,
+ Block::RedWool,
+ Block::BlackWool,
+ ])
+});
+pub static FOXES_SPAWNABLE_ON: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::GrassBlock,
+ Block::Snow,
+ Block::SnowBlock,
+ Block::Podzol,
+ Block::CoarseDirt,
+ ])
+});
+pub static ALL_HANGING_SIGNS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::OakHangingSign,
+ Block::SpruceHangingSign,
+ Block::BirchHangingSign,
+ Block::AcaciaHangingSign,
+ Block::CherryHangingSign,
+ Block::JungleHangingSign,
+ Block::DarkOakHangingSign,
+ Block::CrimsonHangingSign,
+ Block::WarpedHangingSign,
+ Block::MangroveHangingSign,
+ Block::BambooHangingSign,
+ Block::OakWallHangingSign,
+ Block::SpruceWallHangingSign,
+ Block::BirchWallHangingSign,
+ Block::AcaciaWallHangingSign,
+ Block::CherryWallHangingSign,
+ Block::JungleWallHangingSign,
+ Block::DarkOakWallHangingSign,
+ Block::CrimsonWallHangingSign,
+ Block::WarpedWallHangingSign,
+ Block::MangroveWallHangingSign,
+ Block::BambooWallHangingSign,
+ ])
+});
+pub static WOODEN_TRAPDOORS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::AcaciaTrapdoor,
+ Block::BirchTrapdoor,
+ Block::DarkOakTrapdoor,
+ Block::JungleTrapdoor,
+ Block::OakTrapdoor,
+ Block::SpruceTrapdoor,
+ Block::CrimsonTrapdoor,
+ Block::WarpedTrapdoor,
+ Block::MangroveTrapdoor,
+ Block::BambooTrapdoor,
+ Block::CherryTrapdoor,
+ ])
+});
+pub static DRAGON_TRANSPARENT: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::Light, Block::Fire, Block::SoulFire]));
+pub static REPLACEABLE_BY_TREES: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Grass,
+ Block::Fern,
+ Block::DeadBush,
+ Block::Vine,
+ Block::GlowLichen,
+ Block::Sunflower,
+ Block::Lilac,
+ Block::RoseBush,
+ Block::Peony,
+ Block::TallGrass,
+ Block::LargeFern,
+ Block::HangingRoots,
+ Block::PitcherPlant,
+ Block::Water,
+ Block::Seagrass,
+ Block::TallSeagrass,
+ Block::WarpedRoots,
+ Block::NetherSprouts,
+ Block::CrimsonRoots,
+ Block::JungleLeaves,
+ Block::OakLeaves,
+ Block::SpruceLeaves,
+ Block::DarkOakLeaves,
+ Block::AcaciaLeaves,
+ Block::BirchLeaves,
+ Block::AzaleaLeaves,
+ Block::FloweringAzaleaLeaves,
+ Block::MangroveLeaves,
+ Block::CherryLeaves,
+ ])
+});
+pub static FLOWERS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::FloweringAzaleaLeaves,
+ Block::FloweringAzalea,
+ Block::MangrovePropagule,
+ Block::CherryLeaves,
+ Block::PinkPetals,
+ Block::Dandelion,
+ Block::Poppy,
+ Block::BlueOrchid,
+ Block::Allium,
+ Block::AzureBluet,
+ Block::RedTulip,
+ Block::OrangeTulip,
+ Block::WhiteTulip,
+ Block::PinkTulip,
+ Block::OxeyeDaisy,
+ Block::Cornflower,
+ Block::LilyOfTheValley,
+ Block::WitherRose,
+ Block::Torchflower,
+ Block::Sunflower,
+ Block::Lilac,
+ Block::Peony,
+ Block::RoseBush,
+ Block::PitcherPlant,
+ ])
+});
+pub static FIRE: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::Fire, Block::SoulFire]));
+pub static CANDLE_CAKES: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::CandleCake,
+ Block::WhiteCandleCake,
+ Block::OrangeCandleCake,
+ Block::MagentaCandleCake,
+ Block::LightBlueCandleCake,
+ Block::YellowCandleCake,
+ Block::LimeCandleCake,
+ Block::PinkCandleCake,
+ Block::GrayCandleCake,
+ Block::LightGrayCandleCake,
+ Block::CyanCandleCake,
+ Block::PurpleCandleCake,
+ Block::BlueCandleCake,
+ Block::BrownCandleCake,
+ Block::GreenCandleCake,
+ Block::RedCandleCake,
+ Block::BlackCandleCake,
+ ])
+});
+pub static BANNERS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::WhiteBanner,
+ Block::OrangeBanner,
+ Block::MagentaBanner,
+ Block::LightBlueBanner,
+ Block::YellowBanner,
+ Block::LimeBanner,
+ Block::PinkBanner,
+ Block::GrayBanner,
+ Block::LightGrayBanner,
+ Block::CyanBanner,
+ Block::PurpleBanner,
+ Block::BlueBanner,
+ Block::BrownBanner,
+ Block::GreenBanner,
+ Block::RedBanner,
+ Block::BlackBanner,
+ Block::WhiteWallBanner,
+ Block::OrangeWallBanner,
+ Block::MagentaWallBanner,
+ Block::LightBlueWallBanner,
+ Block::YellowWallBanner,
+ Block::LimeWallBanner,
+ Block::PinkWallBanner,
+ Block::GrayWallBanner,
+ Block::LightGrayWallBanner,
+ Block::CyanWallBanner,
+ Block::PurpleWallBanner,
+ Block::BlueWallBanner,
+ Block::BrownWallBanner,
+ Block::GreenWallBanner,
+ Block::RedWallBanner,
+ Block::BlackWallBanner,
+ ])
+});
+pub static TERRACOTTA: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Terracotta,
+ Block::WhiteTerracotta,
+ Block::OrangeTerracotta,
+ Block::MagentaTerracotta,
+ Block::LightBlueTerracotta,
+ Block::YellowTerracotta,
+ Block::LimeTerracotta,
+ Block::PinkTerracotta,
+ Block::GrayTerracotta,
+ Block::LightGrayTerracotta,
+ Block::CyanTerracotta,
+ Block::PurpleTerracotta,
+ Block::BlueTerracotta,
+ Block::BrownTerracotta,
+ Block::GreenTerracotta,
+ Block::RedTerracotta,
+ Block::BlackTerracotta,
+ ])
+});
+pub static BIRCH_LOGS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::BirchLog,
+ Block::BirchWood,
+ Block::StrippedBirchLog,
+ Block::StrippedBirchWood,
+ ])
+});
+pub static PIGLIN_REPELLENTS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::SoulFire,
+ Block::SoulTorch,
+ Block::SoulLantern,
+ Block::SoulWallTorch,
+ Block::SoulCampfire,
+ ])
+});
+pub static MANGROVE_LOGS_CAN_GROW_THROUGH: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Mud,
+ Block::MuddyMangroveRoots,
+ Block::MangroveRoots,
+ Block::MangroveLeaves,
+ Block::MangroveLog,
+ Block::MangrovePropagule,
+ Block::MossCarpet,
+ Block::Vine,
+ ])
+});
+pub static BEACON_BASE_BLOCKS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::NetheriteBlock,
+ Block::EmeraldBlock,
+ Block::DiamondBlock,
+ Block::GoldBlock,
+ Block::IronBlock,
+ ])
+});
+pub static LAVA_POOL_STONE_CANNOT_REPLACE: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Bedrock,
+ Block::Spawner,
+ Block::Chest,
+ Block::EndPortalFrame,
+ Block::ReinforcedDeepslate,
+ Block::JungleLeaves,
+ Block::OakLeaves,
+ Block::SpruceLeaves,
+ Block::DarkOakLeaves,
+ Block::AcaciaLeaves,
+ Block::BirchLeaves,
+ Block::AzaleaLeaves,
+ Block::FloweringAzaleaLeaves,
+ Block::MangroveLeaves,
+ Block::CherryLeaves,
+ Block::CrimsonStem,
+ Block::StrippedCrimsonStem,
+ Block::CrimsonHyphae,
+ Block::StrippedCrimsonHyphae,
+ Block::WarpedStem,
+ Block::StrippedWarpedStem,
+ Block::WarpedHyphae,
+ Block::StrippedWarpedHyphae,
+ Block::DarkOakLog,
+ Block::DarkOakWood,
+ Block::StrippedDarkOakLog,
+ Block::StrippedDarkOakWood,
+ Block::OakLog,
+ Block::OakWood,
+ Block::StrippedOakLog,
+ Block::StrippedOakWood,
+ Block::AcaciaLog,
+ Block::AcaciaWood,
+ Block::StrippedAcaciaLog,
+ Block::StrippedAcaciaWood,
+ Block::BirchLog,
+ Block::BirchWood,
+ Block::StrippedBirchLog,
+ Block::StrippedBirchWood,
+ Block::JungleLog,
+ Block::JungleWood,
+ Block::StrippedJungleLog,
+ Block::StrippedJungleWood,
+ Block::SpruceLog,
+ Block::SpruceWood,
+ Block::StrippedSpruceLog,
+ Block::StrippedSpruceWood,
+ Block::MangroveLog,
+ Block::MangroveWood,
+ Block::StrippedMangroveLog,
+ Block::StrippedMangroveWood,
+ Block::CherryLog,
+ Block::CherryWood,
+ Block::StrippedCherryLog,
+ Block::StrippedCherryWood,
+ ])
+});
+pub static OVERWORLD_CARVER_REPLACEABLES: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Water,
+ Block::Gravel,
+ Block::SuspiciousGravel,
+ Block::Sandstone,
+ Block::RedSandstone,
+ Block::Calcite,
+ Block::Snow,
+ Block::PackedIce,
+ Block::RawIronBlock,
+ Block::RawCopperBlock,
+ Block::Stone,
+ Block::Granite,
+ Block::Diorite,
+ Block::Andesite,
+ Block::Tuff,
+ Block::Deepslate,
+ Block::Dirt,
+ Block::GrassBlock,
+ Block::Podzol,
+ Block::CoarseDirt,
+ Block::Mycelium,
+ Block::RootedDirt,
+ Block::MossBlock,
+ Block::Mud,
+ Block::MuddyMangroveRoots,
+ Block::Sand,
+ Block::RedSand,
+ Block::SuspiciousSand,
+ Block::SuspiciousSand,
+ Block::Terracotta,
+ Block::WhiteTerracotta,
+ Block::OrangeTerracotta,
+ Block::MagentaTerracotta,
+ Block::LightBlueTerracotta,
+ Block::YellowTerracotta,
+ Block::LimeTerracotta,
+ Block::PinkTerracotta,
+ Block::GrayTerracotta,
+ Block::LightGrayTerracotta,
+ Block::CyanTerracotta,
+ Block::PurpleTerracotta,
+ Block::BlueTerracotta,
+ Block::BrownTerracotta,
+ Block::GreenTerracotta,
+ Block::RedTerracotta,
+ Block::BlackTerracotta,
+ Block::IronOre,
+ Block::DeepslateIronOre,
+ Block::CopperOre,
+ Block::DeepslateCopperOre,
+ ])
+});
+pub static STANDING_SIGNS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::OakSign,
+ Block::SpruceSign,
+ Block::BirchSign,
+ Block::AcaciaSign,
+ Block::JungleSign,
+ Block::DarkOakSign,
+ Block::CrimsonSign,
+ Block::WarpedSign,
+ Block::MangroveSign,
+ Block::BambooSign,
+ Block::CherrySign,
+ ])
+});
+pub static SLABS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::BambooMosaicSlab,
+ Block::StoneSlab,
+ Block::SmoothStoneSlab,
+ Block::StoneBrickSlab,
+ Block::SandstoneSlab,
+ Block::PurpurSlab,
+ Block::QuartzSlab,
+ Block::RedSandstoneSlab,
+ Block::BrickSlab,
+ Block::CobblestoneSlab,
+ Block::NetherBrickSlab,
+ Block::PetrifiedOakSlab,
+ Block::PrismarineSlab,
+ Block::PrismarineBrickSlab,
+ Block::DarkPrismarineSlab,
+ Block::PolishedGraniteSlab,
+ Block::SmoothRedSandstoneSlab,
+ Block::MossyStoneBrickSlab,
+ Block::PolishedDioriteSlab,
+ Block::MossyCobblestoneSlab,
+ Block::EndStoneBrickSlab,
+ Block::SmoothSandstoneSlab,
+ Block::SmoothQuartzSlab,
+ Block::GraniteSlab,
+ Block::AndesiteSlab,
+ Block::RedNetherBrickSlab,
+ Block::PolishedAndesiteSlab,
+ Block::DioriteSlab,
+ Block::CutSandstoneSlab,
+ Block::CutRedSandstoneSlab,
+ Block::BlackstoneSlab,
+ Block::PolishedBlackstoneBrickSlab,
+ Block::PolishedBlackstoneSlab,
+ Block::CobbledDeepslateSlab,
+ Block::PolishedDeepslateSlab,
+ Block::DeepslateTileSlab,
+ Block::DeepslateBrickSlab,
+ Block::WaxedWeatheredCutCopperSlab,
+ Block::WaxedExposedCutCopperSlab,
+ Block::WaxedCutCopperSlab,
+ Block::OxidizedCutCopperSlab,
+ Block::WeatheredCutCopperSlab,
+ Block::ExposedCutCopperSlab,
+ Block::CutCopperSlab,
+ Block::WaxedOxidizedCutCopperSlab,
+ Block::MudBrickSlab,
+ Block::OakSlab,
+ Block::SpruceSlab,
+ Block::BirchSlab,
+ Block::JungleSlab,
+ Block::AcaciaSlab,
+ Block::DarkOakSlab,
+ Block::CrimsonSlab,
+ Block::WarpedSlab,
+ Block::MangroveSlab,
+ Block::BambooSlab,
+ Block::CherrySlab,
+ ])
+});
+pub static ANVIL: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::Anvil, Block::ChippedAnvil, Block::DamagedAnvil]));
+pub static DRAGON_IMMUNE: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Barrier,
+ Block::Bedrock,
+ Block::EndPortal,
+ Block::EndPortalFrame,
+ Block::EndGateway,
+ Block::CommandBlock,
+ Block::RepeatingCommandBlock,
+ Block::ChainCommandBlock,
+ Block::StructureBlock,
+ Block::Jigsaw,
+ Block::MovingPiston,
+ Block::Obsidian,
+ Block::CryingObsidian,
+ Block::EndStone,
+ Block::IronBars,
+ Block::RespawnAnchor,
+ Block::ReinforcedDeepslate,
+ ])
+});
+pub static STAIRS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::BambooMosaicStairs,
+ Block::CobblestoneStairs,
+ Block::SandstoneStairs,
+ Block::NetherBrickStairs,
+ Block::StoneBrickStairs,
+ Block::BrickStairs,
+ Block::PurpurStairs,
+ Block::QuartzStairs,
+ Block::RedSandstoneStairs,
+ Block::PrismarineBrickStairs,
+ Block::PrismarineStairs,
+ Block::DarkPrismarineStairs,
+ Block::PolishedGraniteStairs,
+ Block::SmoothRedSandstoneStairs,
+ Block::MossyStoneBrickStairs,
+ Block::PolishedDioriteStairs,
+ Block::MossyCobblestoneStairs,
+ Block::EndStoneBrickStairs,
+ Block::StoneStairs,
+ Block::SmoothSandstoneStairs,
+ Block::SmoothQuartzStairs,
+ Block::GraniteStairs,
+ Block::AndesiteStairs,
+ Block::RedNetherBrickStairs,
+ Block::PolishedAndesiteStairs,
+ Block::DioriteStairs,
+ Block::BlackstoneStairs,
+ Block::PolishedBlackstoneBrickStairs,
+ Block::PolishedBlackstoneStairs,
+ Block::CobbledDeepslateStairs,
+ Block::PolishedDeepslateStairs,
+ Block::DeepslateTileStairs,
+ Block::DeepslateBrickStairs,
+ Block::OxidizedCutCopperStairs,
+ Block::WeatheredCutCopperStairs,
+ Block::ExposedCutCopperStairs,
+ Block::CutCopperStairs,
+ Block::WaxedWeatheredCutCopperStairs,
+ Block::WaxedExposedCutCopperStairs,
+ Block::WaxedCutCopperStairs,
+ Block::WaxedOxidizedCutCopperStairs,
+ Block::MudBrickStairs,
+ Block::OakStairs,
+ Block::SpruceStairs,
+ Block::BirchStairs,
+ Block::JungleStairs,
+ Block::AcaciaStairs,
+ Block::DarkOakStairs,
+ Block::CrimsonStairs,
+ Block::WarpedStairs,
+ Block::MangroveStairs,
+ Block::BambooStairs,
+ Block::CherryStairs,
+ ])
+});
+pub static CAVE_VINES: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::CaveVinesPlant, Block::CaveVines]));
+pub static NEEDS_DIAMOND_TOOL: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Obsidian,
+ Block::CryingObsidian,
+ Block::NetheriteBlock,
+ Block::RespawnAnchor,
+ Block::AncientDebris,
+ ])
+});
+pub static ENDERMAN_HOLDABLE: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Sand,
+ Block::RedSand,
+ Block::Gravel,
+ Block::BrownMushroom,
+ Block::RedMushroom,
+ Block::Tnt,
+ Block::Cactus,
+ Block::Clay,
+ Block::Pumpkin,
+ Block::CarvedPumpkin,
+ Block::Melon,
+ Block::CrimsonFungus,
+ Block::CrimsonNylium,
+ Block::CrimsonRoots,
+ Block::WarpedFungus,
+ Block::WarpedNylium,
+ Block::WarpedRoots,
+ Block::Dandelion,
+ Block::Poppy,
+ Block::BlueOrchid,
+ Block::Allium,
+ Block::AzureBluet,
+ Block::RedTulip,
+ Block::OrangeTulip,
+ Block::WhiteTulip,
+ Block::PinkTulip,
+ Block::OxeyeDaisy,
+ Block::Cornflower,
+ Block::LilyOfTheValley,
+ Block::WitherRose,
+ Block::Torchflower,
+ Block::Dirt,
+ Block::GrassBlock,
+ Block::Podzol,
+ Block::CoarseDirt,
+ Block::Mycelium,
+ Block::RootedDirt,
+ Block::MossBlock,
+ Block::Mud,
+ Block::MuddyMangroveRoots,
+ ])
+});
+pub static ENCHANTMENT_POWER_TRANSMITTER: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Air,
+ Block::Water,
+ Block::Lava,
+ Block::Grass,
+ Block::Fern,
+ Block::DeadBush,
+ Block::Seagrass,
+ Block::TallSeagrass,
+ Block::Fire,
+ Block::SoulFire,
+ Block::Snow,
+ Block::Vine,
+ Block::GlowLichen,
+ Block::Light,
+ Block::TallGrass,
+ Block::LargeFern,
+ Block::StructureVoid,
+ Block::VoidAir,
+ Block::CaveAir,
+ Block::BubbleColumn,
+ Block::WarpedRoots,
+ Block::NetherSprouts,
+ Block::CrimsonRoots,
+ Block::HangingRoots,
+ ])
+});
+pub static INFINIBURN_END: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::Bedrock, Block::Netherrack, Block::MagmaBlock]));
+pub static SOUL_FIRE_BASE_BLOCKS: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::SoulSand, Block::SoulSoil]));
+pub static WOOL_CARPETS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::WhiteCarpet,
+ Block::OrangeCarpet,
+ Block::MagentaCarpet,
+ Block::LightBlueCarpet,
+ Block::YellowCarpet,
+ Block::LimeCarpet,
+ Block::PinkCarpet,
+ Block::GrayCarpet,
+ Block::LightGrayCarpet,
+ Block::CyanCarpet,
+ Block::PurpleCarpet,
+ Block::BlueCarpet,
+ Block::BrownCarpet,
+ Block::GreenCarpet,
+ Block::RedCarpet,
+ Block::BlackCarpet,
+ ])
+});
+pub static GOATS_SPAWNABLE_ON: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Stone,
+ Block::Snow,
+ Block::SnowBlock,
+ Block::PackedIce,
+ Block::Gravel,
+ Block::GrassBlock,
+ ])
+});
+pub static CORAL_BLOCKS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::TubeCoralBlock,
+ Block::BrainCoralBlock,
+ Block::BubbleCoralBlock,
+ Block::FireCoralBlock,
+ Block::HornCoralBlock,
+ ])
+});
+pub static WOODEN_DOORS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::OakDoor,
+ Block::SpruceDoor,
+ Block::BirchDoor,
+ Block::JungleDoor,
+ Block::AcaciaDoor,
+ Block::DarkOakDoor,
+ Block::CrimsonDoor,
+ Block::WarpedDoor,
+ Block::MangroveDoor,
+ Block::BambooDoor,
+ Block::CherryDoor,
+ ])
+});
+pub static COAL_ORES: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::CoalOre, Block::DeepslateCoalOre]));
+pub static BIG_DRIPLEAF_PLACEABLE: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Farmland,
+ Block::Clay,
+ Block::MossBlock,
+ Block::Dirt,
+ Block::GrassBlock,
+ Block::Podzol,
+ Block::CoarseDirt,
+ Block::Mycelium,
+ Block::RootedDirt,
+ Block::MossBlock,
+ Block::Mud,
+ Block::MuddyMangroveRoots,
+ ])
+});
+pub static BUTTONS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::OakButton,
+ Block::SpruceButton,
+ Block::BirchButton,
+ Block::JungleButton,
+ Block::AcaciaButton,
+ Block::DarkOakButton,
+ Block::CrimsonButton,
+ Block::WarpedButton,
+ Block::MangroveButton,
+ Block::BambooButton,
+ Block::CherryButton,
+ Block::StoneButton,
+ Block::PolishedBlackstoneButton,
+ ])
+});
+pub static GOLD_ORES: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::GoldOre,
+ Block::NetherGoldOre,
+ Block::DeepslateGoldOre,
+ ])
+});
+pub static NEEDS_IRON_TOOL: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::DiamondBlock,
+ Block::DiamondOre,
+ Block::DeepslateDiamondOre,
+ Block::EmeraldOre,
+ Block::DeepslateEmeraldOre,
+ Block::EmeraldBlock,
+ Block::GoldBlock,
+ Block::RawGoldBlock,
+ Block::GoldOre,
+ Block::DeepslateGoldOre,
+ Block::RedstoneOre,
+ Block::DeepslateRedstoneOre,
+ ])
+});
+pub static UNSTABLE_BOTTOM_CENTER: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::AcaciaFenceGate,
+ Block::BirchFenceGate,
+ Block::DarkOakFenceGate,
+ Block::JungleFenceGate,
+ Block::OakFenceGate,
+ Block::SpruceFenceGate,
+ Block::CrimsonFenceGate,
+ Block::WarpedFenceGate,
+ Block::MangroveFenceGate,
+ Block::BambooFenceGate,
+ Block::CherryFenceGate,
+ ])
+});
+pub static CORALS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::TubeCoralFan,
+ Block::BrainCoralFan,
+ Block::BubbleCoralFan,
+ Block::FireCoralFan,
+ Block::HornCoralFan,
+ Block::TubeCoral,
+ Block::BrainCoral,
+ Block::BubbleCoral,
+ Block::FireCoral,
+ Block::HornCoral,
+ ])
+});
+pub static WART_BLOCKS: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::NetherWartBlock, Block::WarpedWartBlock]));
+pub static BEEHIVES: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::BeeNest, Block::Beehive]));
+pub static POLAR_BEARS_SPAWNABLE_ON_ALTERNATE: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::Ice]));
+pub static DEEPSLATE_ORE_REPLACEABLES: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::Deepslate, Block::Tuff]));
+pub static SNAPS_GOAT_HORN: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Stone,
+ Block::PackedIce,
+ Block::IronOre,
+ Block::CoalOre,
+ Block::CopperOre,
+ Block::EmeraldOre,
+ Block::AcaciaLog,
+ Block::BirchLog,
+ Block::OakLog,
+ Block::JungleLog,
+ Block::SpruceLog,
+ Block::DarkOakLog,
+ Block::MangroveLog,
+ Block::CherryLog,
+ ])
+});
+pub static PREVENT_MOB_SPAWNING_INSIDE: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Rail,
+ Block::PoweredRail,
+ Block::DetectorRail,
+ Block::ActivatorRail,
+ ])
+});
+pub static CONVERTABLE_TO_MUD: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::Dirt, Block::CoarseDirt, Block::RootedDirt]));
+pub static SOUL_SPEED_BLOCKS: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::SoulSand, Block::SoulSoil]));
+pub static OVERWORLD_NATURAL_LOGS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::AcaciaLog,
+ Block::BirchLog,
+ Block::OakLog,
+ Block::JungleLog,
+ Block::SpruceLog,
+ Block::DarkOakLog,
+ Block::MangroveLog,
+ Block::CherryLog,
+ ])
+});
+pub static CORAL_PLANTS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::TubeCoral,
+ Block::BrainCoral,
+ Block::BubbleCoral,
+ Block::FireCoral,
+ Block::HornCoral,
+ ])
+});
+pub static PORTALS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::NetherPortal,
+ Block::EndPortal,
+ Block::EndGateway,
+ ])
+});
+pub static SCULK_REPLACEABLE_WORLD_GEN: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::DeepslateBricks,
+ Block::DeepslateTiles,
+ Block::CobbledDeepslate,
+ Block::CrackedDeepslateBricks,
+ Block::CrackedDeepslateTiles,
+ Block::PolishedDeepslate,
+ Block::Sand,
+ Block::RedSand,
+ Block::Gravel,
+ Block::SoulSand,
+ Block::SoulSoil,
+ Block::Calcite,
+ Block::SmoothBasalt,
+ Block::Clay,
+ Block::DripstoneBlock,
+ Block::EndStone,
+ Block::RedSandstone,
+ Block::Sandstone,
+ Block::Stone,
+ Block::Granite,
+ Block::Diorite,
+ Block::Andesite,
+ Block::Tuff,
+ Block::Deepslate,
+ Block::Dirt,
+ Block::GrassBlock,
+ Block::Podzol,
+ Block::CoarseDirt,
+ Block::Mycelium,
+ Block::RootedDirt,
+ Block::MossBlock,
+ Block::Mud,
+ Block::MuddyMangroveRoots,
+ Block::Terracotta,
+ Block::WhiteTerracotta,
+ Block::OrangeTerracotta,
+ Block::MagentaTerracotta,
+ Block::LightBlueTerracotta,
+ Block::YellowTerracotta,
+ Block::LimeTerracotta,
+ Block::PinkTerracotta,
+ Block::GrayTerracotta,
+ Block::LightGrayTerracotta,
+ Block::CyanTerracotta,
+ Block::PurpleTerracotta,
+ Block::BlueTerracotta,
+ Block::BrownTerracotta,
+ Block::GreenTerracotta,
+ Block::RedTerracotta,
+ Block::BlackTerracotta,
+ Block::CrimsonNylium,
+ Block::WarpedNylium,
+ Block::Netherrack,
+ Block::Basalt,
+ Block::Blackstone,
+ ])
+});
+pub static SHULKER_BOXES: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::ShulkerBox,
+ Block::BlackShulkerBox,
+ Block::BlueShulkerBox,
+ Block::BrownShulkerBox,
+ Block::CyanShulkerBox,
+ Block::GrayShulkerBox,
+ Block::GreenShulkerBox,
+ Block::LightBlueShulkerBox,
+ Block::LightGrayShulkerBox,
+ Block::LimeShulkerBox,
+ Block::MagentaShulkerBox,
+ Block::OrangeShulkerBox,
+ Block::PinkShulkerBox,
+ Block::PurpleShulkerBox,
+ Block::RedShulkerBox,
+ Block::WhiteShulkerBox,
+ Block::YellowShulkerBox,
+ ])
+});
+pub static FENCES: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::NetherBrickFence,
+ Block::OakFence,
+ Block::AcaciaFence,
+ Block::DarkOakFence,
+ Block::SpruceFence,
+ Block::BirchFence,
+ Block::JungleFence,
+ Block::CrimsonFence,
+ Block::WarpedFence,
+ Block::MangroveFence,
+ Block::BambooFence,
+ Block::CherryFence,
+ ])
+});
+pub static GEODE_INVALID_BLOCKS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Bedrock,
+ Block::Water,
+ Block::Lava,
+ Block::Ice,
+ Block::PackedIce,
+ Block::BlueIce,
+ ])
+});
+pub static COMPLETES_FIND_TREE_TUTORIAL: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::JungleLeaves,
+ Block::OakLeaves,
+ Block::SpruceLeaves,
+ Block::DarkOakLeaves,
+ Block::AcaciaLeaves,
+ Block::BirchLeaves,
+ Block::AzaleaLeaves,
+ Block::FloweringAzaleaLeaves,
+ Block::MangroveLeaves,
+ Block::CherryLeaves,
+ Block::NetherWartBlock,
+ Block::WarpedWartBlock,
+ Block::CrimsonStem,
+ Block::StrippedCrimsonStem,
+ Block::CrimsonHyphae,
+ Block::StrippedCrimsonHyphae,
+ Block::WarpedStem,
+ Block::StrippedWarpedStem,
+ Block::WarpedHyphae,
+ Block::StrippedWarpedHyphae,
+ Block::DarkOakLog,
+ Block::DarkOakWood,
+ Block::StrippedDarkOakLog,
+ Block::StrippedDarkOakWood,
+ Block::OakLog,
+ Block::OakWood,
+ Block::StrippedOakLog,
+ Block::StrippedOakWood,
+ Block::AcaciaLog,
+ Block::AcaciaWood,
+ Block::StrippedAcaciaLog,
+ Block::StrippedAcaciaWood,
+ Block::BirchLog,
+ Block::BirchWood,
+ Block::StrippedBirchLog,
+ Block::StrippedBirchWood,
+ Block::JungleLog,
+ Block::JungleWood,
+ Block::StrippedJungleLog,
+ Block::StrippedJungleWood,
+ Block::SpruceLog,
+ Block::SpruceWood,
+ Block::StrippedSpruceLog,
+ Block::StrippedSpruceWood,
+ Block::MangroveLog,
+ Block::MangroveWood,
+ Block::StrippedMangroveLog,
+ Block::StrippedMangroveWood,
+ Block::CherryLog,
+ Block::CherryWood,
+ Block::StrippedCherryLog,
+ Block::StrippedCherryWood,
+ ])
+});
+pub static FROG_PREFER_JUMP_TO: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::LilyPad, Block::BigDripleaf]));
+pub static INFINIBURN_OVERWORLD: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::Netherrack, Block::MagmaBlock]));
+pub static WITHER_SUMMON_BASE_BLOCKS: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::SoulSand, Block::SoulSoil]));
+pub static FALL_DAMAGE_RESETTING: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::SweetBerryBush,
+ Block::Cobweb,
+ Block::Ladder,
+ Block::Vine,
+ Block::Scaffolding,
+ Block::WeepingVines,
+ Block::WeepingVinesPlant,
+ Block::TwistingVines,
+ Block::TwistingVinesPlant,
+ Block::CaveVines,
+ Block::CaveVinesPlant,
+ ])
+});
+pub static SMALL_FLOWERS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Dandelion,
+ Block::Poppy,
+ Block::BlueOrchid,
+ Block::Allium,
+ Block::AzureBluet,
+ Block::RedTulip,
+ Block::OrangeTulip,
+ Block::WhiteTulip,
+ Block::PinkTulip,
+ Block::OxeyeDaisy,
+ Block::Cornflower,
+ Block::LilyOfTheValley,
+ Block::WitherRose,
+ Block::Torchflower,
+ ])
+});
+pub static CEILING_HANGING_SIGNS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::OakHangingSign,
+ Block::SpruceHangingSign,
+ Block::BirchHangingSign,
+ Block::AcaciaHangingSign,
+ Block::CherryHangingSign,
+ Block::JungleHangingSign,
+ Block::DarkOakHangingSign,
+ Block::CrimsonHangingSign,
+ Block::WarpedHangingSign,
+ Block::MangroveHangingSign,
+ Block::BambooHangingSign,
+ ])
+});
+pub static REPLACEABLE: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Air,
+ Block::Water,
+ Block::Lava,
+ Block::Grass,
+ Block::Fern,
+ Block::DeadBush,
+ Block::Seagrass,
+ Block::TallSeagrass,
+ Block::Fire,
+ Block::SoulFire,
+ Block::Snow,
+ Block::Vine,
+ Block::GlowLichen,
+ Block::Light,
+ Block::TallGrass,
+ Block::LargeFern,
+ Block::StructureVoid,
+ Block::VoidAir,
+ Block::CaveAir,
+ Block::BubbleColumn,
+ Block::WarpedRoots,
+ Block::NetherSprouts,
+ Block::CrimsonRoots,
+ Block::HangingRoots,
+ ])
+});
+pub static STRIDER_WARM_BLOCKS: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::Lava]));
+pub static ANIMALS_SPAWNABLE_ON: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::GrassBlock]));
+pub static INVALID_SPAWN_INSIDE: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::EndPortal, Block::EndGateway]));
+pub static FENCE_GATES: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::AcaciaFenceGate,
+ Block::BirchFenceGate,
+ Block::DarkOakFenceGate,
+ Block::JungleFenceGate,
+ Block::OakFenceGate,
+ Block::SpruceFenceGate,
+ Block::CrimsonFenceGate,
+ Block::WarpedFenceGate,
+ Block::MangroveFenceGate,
+ Block::BambooFenceGate,
+ Block::CherryFenceGate,
+ ])
+});
+pub static GUARDED_BY_PIGLINS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::GoldBlock,
+ Block::Barrel,
+ Block::Chest,
+ Block::EnderChest,
+ Block::GildedBlackstone,
+ Block::TrappedChest,
+ Block::RawGoldBlock,
+ Block::ShulkerBox,
+ Block::BlackShulkerBox,
+ Block::BlueShulkerBox,
+ Block::BrownShulkerBox,
+ Block::CyanShulkerBox,
+ Block::GrayShulkerBox,
+ Block::GreenShulkerBox,
+ Block::LightBlueShulkerBox,
+ Block::LightGrayShulkerBox,
+ Block::LimeShulkerBox,
+ Block::MagentaShulkerBox,
+ Block::OrangeShulkerBox,
+ Block::PinkShulkerBox,
+ Block::PurpleShulkerBox,
+ Block::RedShulkerBox,
+ Block::WhiteShulkerBox,
+ Block::YellowShulkerBox,
+ Block::GoldOre,
+ Block::NetherGoldOre,
+ Block::DeepslateGoldOre,
+ ])
+});
+pub static AZALEA_GROWS_ON: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::SnowBlock,
+ Block::PowderSnow,
+ Block::Dirt,
+ Block::GrassBlock,
+ Block::Podzol,
+ Block::CoarseDirt,
+ Block::Mycelium,
+ Block::RootedDirt,
+ Block::MossBlock,
+ Block::Mud,
+ Block::MuddyMangroveRoots,
+ Block::Sand,
+ Block::RedSand,
+ Block::SuspiciousSand,
+ Block::SuspiciousSand,
+ Block::Terracotta,
+ Block::WhiteTerracotta,
+ Block::OrangeTerracotta,
+ Block::MagentaTerracotta,
+ Block::LightBlueTerracotta,
+ Block::YellowTerracotta,
+ Block::LimeTerracotta,
+ Block::PinkTerracotta,
+ Block::GrayTerracotta,
+ Block::LightGrayTerracotta,
+ Block::CyanTerracotta,
+ Block::PurpleTerracotta,
+ Block::BlueTerracotta,
+ Block::BrownTerracotta,
+ Block::GreenTerracotta,
+ Block::RedTerracotta,
+ Block::BlackTerracotta,
+ ])
+});
+pub static OAK_LOGS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::OakLog,
+ Block::OakWood,
+ Block::StrippedOakLog,
+ Block::StrippedOakWood,
+ ])
+});
+pub static STONE_BRICKS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::StoneBricks,
+ Block::MossyStoneBricks,
+ Block::CrackedStoneBricks,
+ Block::ChiseledStoneBricks,
+ ])
+});
+pub static LAPIS_ORES: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::LapisOre, Block::DeepslateLapisOre]));
+pub static IMPERMEABLE: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Glass,
+ Block::WhiteStainedGlass,
+ Block::OrangeStainedGlass,
+ Block::MagentaStainedGlass,
+ Block::LightBlueStainedGlass,
+ Block::YellowStainedGlass,
+ Block::LimeStainedGlass,
+ Block::PinkStainedGlass,
+ Block::GrayStainedGlass,
+ Block::LightGrayStainedGlass,
+ Block::CyanStainedGlass,
+ Block::PurpleStainedGlass,
+ Block::BlueStainedGlass,
+ Block::BrownStainedGlass,
+ Block::GreenStainedGlass,
+ Block::RedStainedGlass,
+ Block::BlackStainedGlass,
+ Block::TintedGlass,
+ ])
+});
+pub static ICE: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Ice,
+ Block::PackedIce,
+ Block::BlueIce,
+ Block::FrostedIce,
+ ])
+});
+pub static ALL_SIGNS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::OakSign,
+ Block::SpruceSign,
+ Block::BirchSign,
+ Block::AcaciaSign,
+ Block::JungleSign,
+ Block::DarkOakSign,
+ Block::CrimsonSign,
+ Block::WarpedSign,
+ Block::MangroveSign,
+ Block::BambooSign,
+ Block::CherrySign,
+ Block::OakWallSign,
+ Block::SpruceWallSign,
+ Block::BirchWallSign,
+ Block::AcaciaWallSign,
+ Block::JungleWallSign,
+ Block::DarkOakWallSign,
+ Block::CrimsonWallSign,
+ Block::WarpedWallSign,
+ Block::MangroveWallSign,
+ Block::BambooWallSign,
+ Block::CherryWallSign,
+ Block::OakHangingSign,
+ Block::SpruceHangingSign,
+ Block::BirchHangingSign,
+ Block::AcaciaHangingSign,
+ Block::CherryHangingSign,
+ Block::JungleHangingSign,
+ Block::DarkOakHangingSign,
+ Block::CrimsonHangingSign,
+ Block::WarpedHangingSign,
+ Block::MangroveHangingSign,
+ Block::BambooHangingSign,
+ Block::OakWallHangingSign,
+ Block::SpruceWallHangingSign,
+ Block::BirchWallHangingSign,
+ Block::AcaciaWallHangingSign,
+ Block::CherryWallHangingSign,
+ Block::JungleWallHangingSign,
+ Block::DarkOakWallHangingSign,
+ Block::CrimsonWallHangingSign,
+ Block::WarpedWallHangingSign,
+ Block::MangroveWallHangingSign,
+ Block::BambooWallHangingSign,
+ ])
+});
+pub static SIGNS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::OakSign,
+ Block::SpruceSign,
+ Block::BirchSign,
+ Block::AcaciaSign,
+ Block::JungleSign,
+ Block::DarkOakSign,
+ Block::CrimsonSign,
+ Block::WarpedSign,
+ Block::MangroveSign,
+ Block::BambooSign,
+ Block::CherrySign,
+ Block::OakWallSign,
+ Block::SpruceWallSign,
+ Block::BirchWallSign,
+ Block::AcaciaWallSign,
+ Block::JungleWallSign,
+ Block::DarkOakWallSign,
+ Block::CrimsonWallSign,
+ Block::WarpedWallSign,
+ Block::MangroveWallSign,
+ Block::BambooWallSign,
+ Block::CherryWallSign,
+ ])
+});
+pub static INFINIBURN_NETHER: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::Netherrack, Block::MagmaBlock]));
+pub static NETHER_CARVER_REPLACEABLES: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::SoulSand,
+ Block::SoulSoil,
+ Block::Stone,
+ Block::Granite,
+ Block::Diorite,
+ Block::Andesite,
+ Block::Tuff,
+ Block::Deepslate,
+ Block::Netherrack,
+ Block::Basalt,
+ Block::Blackstone,
+ Block::Dirt,
+ Block::GrassBlock,
+ Block::Podzol,
+ Block::CoarseDirt,
+ Block::Mycelium,
+ Block::RootedDirt,
+ Block::MossBlock,
+ Block::Mud,
+ Block::MuddyMangroveRoots,
+ Block::CrimsonNylium,
+ Block::WarpedNylium,
+ Block::NetherWartBlock,
+ Block::WarpedWartBlock,
+ ])
+});
+pub static CRYSTAL_SOUND_BLOCKS: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::AmethystBlock, Block::BuddingAmethyst]));
+pub static DIRT: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Dirt,
+ Block::GrassBlock,
+ Block::Podzol,
+ Block::CoarseDirt,
+ Block::Mycelium,
+ Block::RootedDirt,
+ Block::MossBlock,
+ Block::Mud,
+ Block::MuddyMangroveRoots,
+ ])
+});
+pub static MOOSHROOMS_SPAWNABLE_ON: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::Mycelium]));
+pub static PRESSURE_PLATES: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::LightWeightedPressurePlate,
+ Block::HeavyWeightedPressurePlate,
+ Block::OakPressurePlate,
+ Block::SprucePressurePlate,
+ Block::BirchPressurePlate,
+ Block::JunglePressurePlate,
+ Block::AcaciaPressurePlate,
+ Block::DarkOakPressurePlate,
+ Block::CrimsonPressurePlate,
+ Block::WarpedPressurePlate,
+ Block::MangrovePressurePlate,
+ Block::BambooPressurePlate,
+ Block::CherryPressurePlate,
+ Block::StonePressurePlate,
+ Block::PolishedBlackstonePressurePlate,
+ ])
+});
+pub static LOGS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::CrimsonStem,
+ Block::StrippedCrimsonStem,
+ Block::CrimsonHyphae,
+ Block::StrippedCrimsonHyphae,
+ Block::WarpedStem,
+ Block::StrippedWarpedStem,
+ Block::WarpedHyphae,
+ Block::StrippedWarpedHyphae,
+ Block::DarkOakLog,
+ Block::DarkOakWood,
+ Block::StrippedDarkOakLog,
+ Block::StrippedDarkOakWood,
+ Block::OakLog,
+ Block::OakWood,
+ Block::StrippedOakLog,
+ Block::StrippedOakWood,
+ Block::AcaciaLog,
+ Block::AcaciaWood,
+ Block::StrippedAcaciaLog,
+ Block::StrippedAcaciaWood,
+ Block::BirchLog,
+ Block::BirchWood,
+ Block::StrippedBirchLog,
+ Block::StrippedBirchWood,
+ Block::JungleLog,
+ Block::JungleWood,
+ Block::StrippedJungleLog,
+ Block::StrippedJungleWood,
+ Block::SpruceLog,
+ Block::SpruceWood,
+ Block::StrippedSpruceLog,
+ Block::StrippedSpruceWood,
+ Block::MangroveLog,
+ Block::MangroveWood,
+ Block::StrippedMangroveLog,
+ Block::StrippedMangroveWood,
+ Block::CherryLog,
+ Block::CherryWood,
+ Block::StrippedCherryLog,
+ Block::StrippedCherryWood,
+ ])
+});
+pub static MANGROVE_ROOTS_CAN_GROW_THROUGH: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Mud,
+ Block::MuddyMangroveRoots,
+ Block::MangroveRoots,
+ Block::MossCarpet,
+ Block::Vine,
+ Block::MangrovePropagule,
+ Block::Snow,
+ ])
+});
+pub static CLIMBABLE: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Ladder,
+ Block::Vine,
+ Block::Scaffolding,
+ Block::WeepingVines,
+ Block::WeepingVinesPlant,
+ Block::TwistingVines,
+ Block::TwistingVinesPlant,
+ Block::CaveVines,
+ Block::CaveVinesPlant,
+ ])
+});
+pub static WOODEN_BUTTONS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::OakButton,
+ Block::SpruceButton,
+ Block::BirchButton,
+ Block::JungleButton,
+ Block::AcaciaButton,
+ Block::DarkOakButton,
+ Block::CrimsonButton,
+ Block::WarpedButton,
+ Block::MangroveButton,
+ Block::BambooButton,
+ Block::CherryButton,
+ ])
+});
+pub static ENCHANTMENT_POWER_PROVIDER: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::Bookshelf]));
+pub static CAULDRONS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Cauldron,
+ Block::WaterCauldron,
+ Block::LavaCauldron,
+ Block::PowderSnowCauldron,
+ ])
+});
+pub static SMELTS_TO_GLASS: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::Sand, Block::RedSand]));
+pub static WALL_HANGING_SIGNS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::OakWallHangingSign,
+ Block::SpruceWallHangingSign,
+ Block::BirchWallHangingSign,
+ Block::AcaciaWallHangingSign,
+ Block::CherryWallHangingSign,
+ Block::JungleWallHangingSign,
+ Block::DarkOakWallHangingSign,
+ Block::CrimsonWallHangingSign,
+ Block::WarpedWallHangingSign,
+ Block::MangroveWallHangingSign,
+ Block::BambooWallHangingSign,
+ ])
+});
+pub static WALL_POST_OVERRIDE: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Torch,
+ Block::SoulTorch,
+ Block::RedstoneTorch,
+ Block::Tripwire,
+ Block::WhiteBanner,
+ Block::OrangeBanner,
+ Block::MagentaBanner,
+ Block::LightBlueBanner,
+ Block::YellowBanner,
+ Block::LimeBanner,
+ Block::PinkBanner,
+ Block::GrayBanner,
+ Block::LightGrayBanner,
+ Block::CyanBanner,
+ Block::PurpleBanner,
+ Block::BlueBanner,
+ Block::BrownBanner,
+ Block::GreenBanner,
+ Block::RedBanner,
+ Block::BlackBanner,
+ Block::WhiteWallBanner,
+ Block::OrangeWallBanner,
+ Block::MagentaWallBanner,
+ Block::LightBlueWallBanner,
+ Block::YellowWallBanner,
+ Block::LimeWallBanner,
+ Block::PinkWallBanner,
+ Block::GrayWallBanner,
+ Block::LightGrayWallBanner,
+ Block::CyanWallBanner,
+ Block::PurpleWallBanner,
+ Block::BlueWallBanner,
+ Block::BrownWallBanner,
+ Block::GreenWallBanner,
+ Block::RedWallBanner,
+ Block::BlackWallBanner,
+ Block::LightWeightedPressurePlate,
+ Block::HeavyWeightedPressurePlate,
+ Block::OakSign,
+ Block::SpruceSign,
+ Block::BirchSign,
+ Block::AcaciaSign,
+ Block::JungleSign,
+ Block::DarkOakSign,
+ Block::CrimsonSign,
+ Block::WarpedSign,
+ Block::MangroveSign,
+ Block::BambooSign,
+ Block::CherrySign,
+ Block::OakWallSign,
+ Block::SpruceWallSign,
+ Block::BirchWallSign,
+ Block::AcaciaWallSign,
+ Block::JungleWallSign,
+ Block::DarkOakWallSign,
+ Block::CrimsonWallSign,
+ Block::WarpedWallSign,
+ Block::MangroveWallSign,
+ Block::BambooWallSign,
+ Block::CherryWallSign,
+ Block::OakPressurePlate,
+ Block::SprucePressurePlate,
+ Block::BirchPressurePlate,
+ Block::JunglePressurePlate,
+ Block::AcaciaPressurePlate,
+ Block::DarkOakPressurePlate,
+ Block::CrimsonPressurePlate,
+ Block::WarpedPressurePlate,
+ Block::MangrovePressurePlate,
+ Block::BambooPressurePlate,
+ Block::CherryPressurePlate,
+ Block::StonePressurePlate,
+ Block::PolishedBlackstonePressurePlate,
+ ])
+});
+pub static HOGLIN_REPELLENTS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::WarpedFungus,
+ Block::PottedWarpedFungus,
+ Block::NetherPortal,
+ Block::RespawnAnchor,
+ ])
+});
+pub static FLOWER_POTS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::FlowerPot,
+ Block::PottedPoppy,
+ Block::PottedBlueOrchid,
+ Block::PottedAllium,
+ Block::PottedAzureBluet,
+ Block::PottedRedTulip,
+ Block::PottedOrangeTulip,
+ Block::PottedWhiteTulip,
+ Block::PottedPinkTulip,
+ Block::PottedOxeyeDaisy,
+ Block::PottedDandelion,
+ Block::PottedOakSapling,
+ Block::PottedSpruceSapling,
+ Block::PottedBirchSapling,
+ Block::PottedJungleSapling,
+ Block::PottedAcaciaSapling,
+ Block::PottedDarkOakSapling,
+ Block::PottedRedMushroom,
+ Block::PottedBrownMushroom,
+ Block::PottedDeadBush,
+ Block::PottedFern,
+ Block::PottedCactus,
+ Block::PottedCornflower,
+ Block::PottedLilyOfTheValley,
+ Block::PottedWitherRose,
+ Block::PottedBamboo,
+ Block::PottedCrimsonFungus,
+ Block::PottedWarpedFungus,
+ Block::PottedCrimsonRoots,
+ Block::PottedWarpedRoots,
+ Block::PottedAzaleaBush,
+ Block::PottedFloweringAzaleaBush,
+ Block::PottedMangrovePropagule,
+ Block::PottedCherrySapling,
+ Block::PottedTorchflower,
+ ])
+});
+pub static JUNGLE_LOGS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::JungleLog,
+ Block::JungleWood,
+ Block::StrippedJungleLog,
+ Block::StrippedJungleWood,
+ ])
+});
+pub static DRIPSTONE_REPLACEABLE_BLOCKS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Stone,
+ Block::Granite,
+ Block::Diorite,
+ Block::Andesite,
+ Block::Tuff,
+ Block::Deepslate,
+ ])
+});
+pub static SNOW: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::Snow, Block::SnowBlock, Block::PowderSnow]));
+pub static TRAPDOORS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::IronTrapdoor,
+ Block::AcaciaTrapdoor,
+ Block::BirchTrapdoor,
+ Block::DarkOakTrapdoor,
+ Block::JungleTrapdoor,
+ Block::OakTrapdoor,
+ Block::SpruceTrapdoor,
+ Block::CrimsonTrapdoor,
+ Block::WarpedTrapdoor,
+ Block::MangroveTrapdoor,
+ Block::BambooTrapdoor,
+ Block::CherryTrapdoor,
+ ])
+});
+pub static AXOLOTLS_SPAWNABLE_ON: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::Clay]));
+pub static TRAIL_RUINS_REPLACEABLE: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::Gravel]));
+pub static WARPED_STEMS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::WarpedStem,
+ Block::StrippedWarpedStem,
+ Block::WarpedHyphae,
+ Block::StrippedWarpedHyphae,
+ ])
+});
+pub static SNOW_LAYER_CAN_SURVIVE_ON: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::HoneyBlock, Block::SoulSand, Block::Mud]));
+pub static BASE_STONE_NETHER: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::Netherrack, Block::Basalt, Block::Blackstone]));
+pub static CAMPFIRES: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::Campfire, Block::SoulCampfire]));
+pub static IRON_ORES: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::IronOre, Block::DeepslateIronOre]));
+pub static RAILS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Rail,
+ Block::PoweredRail,
+ Block::DetectorRail,
+ Block::ActivatorRail,
+ ])
+});
+pub static PLANKS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::OakPlanks,
+ Block::SprucePlanks,
+ Block::BirchPlanks,
+ Block::JunglePlanks,
+ Block::AcaciaPlanks,
+ Block::DarkOakPlanks,
+ Block::CrimsonPlanks,
+ Block::WarpedPlanks,
+ Block::MangrovePlanks,
+ Block::BambooPlanks,
+ Block::CherryPlanks,
+ ])
+});
+pub static COMBINATION_STEP_SOUND_BLOCKS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::MossCarpet,
+ Block::Snow,
+ Block::NetherSprouts,
+ Block::WarpedRoots,
+ Block::CrimsonRoots,
+ Block::WhiteCarpet,
+ Block::OrangeCarpet,
+ Block::MagentaCarpet,
+ Block::LightBlueCarpet,
+ Block::YellowCarpet,
+ Block::LimeCarpet,
+ Block::PinkCarpet,
+ Block::GrayCarpet,
+ Block::LightGrayCarpet,
+ Block::CyanCarpet,
+ Block::PurpleCarpet,
+ Block::BlueCarpet,
+ Block::BrownCarpet,
+ Block::GreenCarpet,
+ Block::RedCarpet,
+ Block::BlackCarpet,
+ ])
+});
+pub static SCULK_REPLACEABLE: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Sand,
+ Block::RedSand,
+ Block::Gravel,
+ Block::SoulSand,
+ Block::SoulSoil,
+ Block::Calcite,
+ Block::SmoothBasalt,
+ Block::Clay,
+ Block::DripstoneBlock,
+ Block::EndStone,
+ Block::RedSandstone,
+ Block::Sandstone,
+ Block::Stone,
+ Block::Granite,
+ Block::Diorite,
+ Block::Andesite,
+ Block::Tuff,
+ Block::Deepslate,
+ Block::Dirt,
+ Block::GrassBlock,
+ Block::Podzol,
+ Block::CoarseDirt,
+ Block::Mycelium,
+ Block::RootedDirt,
+ Block::MossBlock,
+ Block::Mud,
+ Block::MuddyMangroveRoots,
+ Block::Terracotta,
+ Block::WhiteTerracotta,
+ Block::OrangeTerracotta,
+ Block::MagentaTerracotta,
+ Block::LightBlueTerracotta,
+ Block::YellowTerracotta,
+ Block::LimeTerracotta,
+ Block::PinkTerracotta,
+ Block::GrayTerracotta,
+ Block::LightGrayTerracotta,
+ Block::CyanTerracotta,
+ Block::PurpleTerracotta,
+ Block::BlueTerracotta,
+ Block::BrownTerracotta,
+ Block::GreenTerracotta,
+ Block::RedTerracotta,
+ Block::BlackTerracotta,
+ Block::CrimsonNylium,
+ Block::WarpedNylium,
+ Block::Netherrack,
+ Block::Basalt,
+ Block::Blackstone,
+ ])
+});
+pub static BAMBOO_BLOCKS: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::BambooBlock, Block::StrippedBambooBlock]));
+pub static MOSS_REPLACEABLE: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Stone,
+ Block::Granite,
+ Block::Diorite,
+ Block::Andesite,
+ Block::Tuff,
+ Block::Deepslate,
+ Block::CaveVinesPlant,
+ Block::CaveVines,
+ Block::Dirt,
+ Block::GrassBlock,
+ Block::Podzol,
+ Block::CoarseDirt,
+ Block::Mycelium,
+ Block::RootedDirt,
+ Block::MossBlock,
+ Block::Mud,
+ Block::MuddyMangroveRoots,
+ ])
+});
+pub static CANDLES: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Candle,
+ Block::WhiteCandle,
+ Block::OrangeCandle,
+ Block::MagentaCandle,
+ Block::LightBlueCandle,
+ Block::YellowCandle,
+ Block::LimeCandle,
+ Block::PinkCandle,
+ Block::GrayCandle,
+ Block::LightGrayCandle,
+ Block::CyanCandle,
+ Block::PurpleCandle,
+ Block::BlueCandle,
+ Block::BrownCandle,
+ Block::GreenCandle,
+ Block::RedCandle,
+ Block::BlackCandle,
+ ])
+});
+pub static SPRUCE_LOGS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::SpruceLog,
+ Block::SpruceWood,
+ Block::StrippedSpruceLog,
+ Block::StrippedSpruceWood,
+ ])
+});
+pub static OCCLUDES_VIBRATION_SIGNALS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::WhiteWool,
+ Block::OrangeWool,
+ Block::MagentaWool,
+ Block::LightBlueWool,
+ Block::YellowWool,
+ Block::LimeWool,
+ Block::PinkWool,
+ Block::GrayWool,
+ Block::LightGrayWool,
+ Block::CyanWool,
+ Block::PurpleWool,
+ Block::BlueWool,
+ Block::BrownWool,
+ Block::GreenWool,
+ Block::RedWool,
+ Block::BlackWool,
+ ])
+});
+pub static AZALEA_ROOT_REPLACEABLE: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::RedSand,
+ Block::Clay,
+ Block::Gravel,
+ Block::Sand,
+ Block::SnowBlock,
+ Block::PowderSnow,
+ Block::Stone,
+ Block::Granite,
+ Block::Diorite,
+ Block::Andesite,
+ Block::Tuff,
+ Block::Deepslate,
+ Block::Dirt,
+ Block::GrassBlock,
+ Block::Podzol,
+ Block::CoarseDirt,
+ Block::Mycelium,
+ Block::RootedDirt,
+ Block::MossBlock,
+ Block::Mud,
+ Block::MuddyMangroveRoots,
+ Block::Terracotta,
+ Block::WhiteTerracotta,
+ Block::OrangeTerracotta,
+ Block::MagentaTerracotta,
+ Block::LightBlueTerracotta,
+ Block::YellowTerracotta,
+ Block::LimeTerracotta,
+ Block::PinkTerracotta,
+ Block::GrayTerracotta,
+ Block::LightGrayTerracotta,
+ Block::CyanTerracotta,
+ Block::PurpleTerracotta,
+ Block::BlueTerracotta,
+ Block::BrownTerracotta,
+ Block::GreenTerracotta,
+ Block::RedTerracotta,
+ Block::BlackTerracotta,
+ ])
+});
+pub static RABBITS_SPAWNABLE_ON: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::GrassBlock,
+ Block::Snow,
+ Block::SnowBlock,
+ Block::Sand,
+ ])
+});
+pub static SAPLINGS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::OakSapling,
+ Block::SpruceSapling,
+ Block::BirchSapling,
+ Block::JungleSapling,
+ Block::AcaciaSapling,
+ Block::DarkOakSapling,
+ Block::Azalea,
+ Block::FloweringAzalea,
+ Block::MangrovePropagule,
+ Block::CherrySapling,
+ ])
+});
+pub static LEAVES: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::JungleLeaves,
+ Block::OakLeaves,
+ Block::SpruceLeaves,
+ Block::DarkOakLeaves,
+ Block::AcaciaLeaves,
+ Block::BirchLeaves,
+ Block::AzaleaLeaves,
+ Block::FloweringAzaleaLeaves,
+ Block::MangroveLeaves,
+ Block::CherryLeaves,
+ ])
+});
+pub static STONE_BUTTONS: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::StoneButton, Block::PolishedBlackstoneButton]));
+pub static REDSTONE_ORES: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::RedstoneOre, Block::DeepslateRedstoneOre]));
+pub static CRIMSON_STEMS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::CrimsonStem,
+ Block::StrippedCrimsonStem,
+ Block::CrimsonHyphae,
+ Block::StrippedCrimsonHyphae,
+ ])
+});
+pub static FROGS_SPAWNABLE_ON: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::GrassBlock,
+ Block::Mud,
+ Block::MangroveRoots,
+ Block::MuddyMangroveRoots,
+ ])
+});
+pub static MAINTAINS_FARMLAND: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::PumpkinStem,
+ Block::AttachedPumpkinStem,
+ Block::MelonStem,
+ Block::AttachedMelonStem,
+ Block::Beetroots,
+ Block::Carrots,
+ Block::Potatoes,
+ Block::TorchflowerCrop,
+ Block::Torchflower,
+ Block::PitcherCrop,
+ Block::Wheat,
+ ])
+});
+pub static CROPS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::Beetroots,
+ Block::Carrots,
+ Block::Potatoes,
+ Block::Wheat,
+ Block::MelonStem,
+ Block::PumpkinStem,
+ Block::TorchflowerCrop,
+ Block::PitcherCrop,
+ ])
+});
+pub static WALLS: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::CobblestoneWall,
+ Block::MossyCobblestoneWall,
+ Block::BrickWall,
+ Block::PrismarineWall,
+ Block::RedSandstoneWall,
+ Block::MossyStoneBrickWall,
+ Block::GraniteWall,
+ Block::StoneBrickWall,
+ Block::NetherBrickWall,
+ Block::AndesiteWall,
+ Block::RedNetherBrickWall,
+ Block::SandstoneWall,
+ Block::EndStoneBrickWall,
+ Block::DioriteWall,
+ Block::BlackstoneWall,
+ Block::PolishedBlackstoneBrickWall,
+ Block::PolishedBlackstoneWall,
+ Block::CobbledDeepslateWall,
+ Block::PolishedDeepslateWall,
+ Block::DeepslateTileWall,
+ Block::DeepslateBrickWall,
+ Block::MudBrickWall,
+ ])
+});
+pub static STONE_PRESSURE_PLATES: Lazy<HashSet<Block>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Block::StonePressurePlate,
+ Block::PolishedBlackstonePressurePlate,
+ ])
+});
+pub static VIBRATION_RESONATORS: Lazy<HashSet<Block>> =
+ Lazy::new(|| HashSet::from_iter(vec![Block::AmethystBlock]));
diff --git a/azalea-registry/src/tags/fluids.rs b/azalea-registry/src/tags/fluids.rs
new file mode 100644
index 00000000..4f177f95
--- /dev/null
+++ b/azalea-registry/src/tags/fluids.rs
@@ -0,0 +1,12 @@
+// This file was generated by codegen/lib/code/tags.py, don't edit it manually!
+
+use std::collections::HashSet;
+
+use once_cell::sync::Lazy;
+
+use crate::Fluid;
+
+pub static LAVA: Lazy<HashSet<Fluid>> =
+ Lazy::new(|| HashSet::from_iter(vec![Fluid::Lava, Fluid::FlowingLava]));
+pub static WATER: Lazy<HashSet<Fluid>> =
+ Lazy::new(|| HashSet::from_iter(vec![Fluid::Water, Fluid::FlowingWater]));
diff --git a/azalea-registry/src/tags/items.rs b/azalea-registry/src/tags/items.rs
new file mode 100644
index 00000000..d826703d
--- /dev/null
+++ b/azalea-registry/src/tags/items.rs
@@ -0,0 +1,1379 @@
+// This file was generated by codegen/lib/code/tags.py, don't edit it manually!
+
+use std::collections::HashSet;
+
+use once_cell::sync::Lazy;
+
+use crate::Item;
+
+pub static WOODEN_FENCES: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::OakFence,
+ Item::AcaciaFence,
+ Item::DarkOakFence,
+ Item::SpruceFence,
+ Item::BirchFence,
+ Item::JungleFence,
+ Item::CrimsonFence,
+ Item::WarpedFence,
+ Item::MangroveFence,
+ Item::BambooFence,
+ Item::CherryFence,
+ ])
+});
+pub static ACACIA_LOGS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::AcaciaLog,
+ Item::AcaciaWood,
+ Item::StrippedAcaciaLog,
+ Item::StrippedAcaciaWood,
+ ])
+});
+pub static CREEPER_IGNITERS: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::FlintAndSteel, Item::FireCharge]));
+pub static WOODEN_SLABS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::OakSlab,
+ Item::SpruceSlab,
+ Item::BirchSlab,
+ Item::JungleSlab,
+ Item::AcaciaSlab,
+ Item::DarkOakSlab,
+ Item::CrimsonSlab,
+ Item::WarpedSlab,
+ Item::MangroveSlab,
+ Item::BambooSlab,
+ Item::CherrySlab,
+ ])
+});
+pub static WOODEN_STAIRS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::OakStairs,
+ Item::SpruceStairs,
+ Item::BirchStairs,
+ Item::JungleStairs,
+ Item::AcaciaStairs,
+ Item::DarkOakStairs,
+ Item::CrimsonStairs,
+ Item::WarpedStairs,
+ Item::MangroveStairs,
+ Item::BambooStairs,
+ Item::CherryStairs,
+ ])
+});
+pub static MANGROVE_LOGS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::MangroveLog,
+ Item::MangroveWood,
+ Item::StrippedMangroveLog,
+ Item::StrippedMangroveWood,
+ ])
+});
+pub static SHOVELS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::DiamondShovel,
+ Item::StoneShovel,
+ Item::GoldenShovel,
+ Item::NetheriteShovel,
+ Item::WoodenShovel,
+ Item::IronShovel,
+ ])
+});
+pub static DARK_OAK_LOGS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::DarkOakLog,
+ Item::DarkOakWood,
+ Item::StrippedDarkOakLog,
+ Item::StrippedDarkOakWood,
+ ])
+});
+pub static EMERALD_ORES: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::EmeraldOre, Item::DeepslateEmeraldOre]));
+pub static TALL_FLOWERS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::Sunflower,
+ Item::Lilac,
+ Item::Peony,
+ Item::RoseBush,
+ Item::PitcherPlant,
+ ])
+});
+pub static DOORS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::IronDoor,
+ Item::OakDoor,
+ Item::SpruceDoor,
+ Item::BirchDoor,
+ Item::JungleDoor,
+ Item::AcaciaDoor,
+ Item::DarkOakDoor,
+ Item::CrimsonDoor,
+ Item::WarpedDoor,
+ Item::MangroveDoor,
+ Item::BambooDoor,
+ Item::CherryDoor,
+ ])
+});
+pub static BEDS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::RedBed,
+ Item::BlackBed,
+ Item::BlueBed,
+ Item::BrownBed,
+ Item::CyanBed,
+ Item::GrayBed,
+ Item::GreenBed,
+ Item::LightBlueBed,
+ Item::LightGrayBed,
+ Item::LimeBed,
+ Item::MagentaBed,
+ Item::OrangeBed,
+ Item::PinkBed,
+ Item::PurpleBed,
+ Item::WhiteBed,
+ Item::YellowBed,
+ ])
+});
+pub static COMPASSES: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::Compass, Item::RecoveryCompass]));
+pub static DECORATED_POT_INGREDIENTS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::Brick,
+ Item::AnglerPotterySherd,
+ Item::ArcherPotterySherd,
+ Item::ArmsUpPotterySherd,
+ Item::BladePotterySherd,
+ Item::BrewerPotterySherd,
+ Item::BurnPotterySherd,
+ Item::DangerPotterySherd,
+ Item::ExplorerPotterySherd,
+ Item::FriendPotterySherd,
+ Item::HeartPotterySherd,
+ Item::HeartbreakPotterySherd,
+ Item::HowlPotterySherd,
+ Item::MinerPotterySherd,
+ Item::MournerPotterySherd,
+ Item::PlentyPotterySherd,
+ Item::PrizePotterySherd,
+ Item::SheafPotterySherd,
+ Item::ShelterPotterySherd,
+ Item::SkullPotterySherd,
+ Item::SnortPotterySherd,
+ ])
+});
+pub static COPPER_ORES: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::CopperOre, Item::DeepslateCopperOre]));
+pub static TRIM_TEMPLATES: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::WardArmorTrimSmithingTemplate,
+ Item::SpireArmorTrimSmithingTemplate,
+ Item::CoastArmorTrimSmithingTemplate,
+ Item::EyeArmorTrimSmithingTemplate,
+ Item::DuneArmorTrimSmithingTemplate,
+ Item::WildArmorTrimSmithingTemplate,
+ Item::RibArmorTrimSmithingTemplate,
+ Item::TideArmorTrimSmithingTemplate,
+ Item::SentryArmorTrimSmithingTemplate,
+ Item::VexArmorTrimSmithingTemplate,
+ Item::SnoutArmorTrimSmithingTemplate,
+ Item::WayfinderArmorTrimSmithingTemplate,
+ Item::ShaperArmorTrimSmithingTemplate,
+ Item::SilenceArmorTrimSmithingTemplate,
+ Item::RaiserArmorTrimSmithingTemplate,
+ Item::HostArmorTrimSmithingTemplate,
+ ])
+});
+pub static WOODEN_PRESSURE_PLATES: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::OakPressurePlate,
+ Item::SprucePressurePlate,
+ Item::BirchPressurePlate,
+ Item::JunglePressurePlate,
+ Item::AcaciaPressurePlate,
+ Item::DarkOakPressurePlate,
+ Item::CrimsonPressurePlate,
+ Item::WarpedPressurePlate,
+ Item::MangrovePressurePlate,
+ Item::BambooPressurePlate,
+ Item::CherryPressurePlate,
+ ])
+});
+pub static NOTEBLOCK_TOP_INSTRUMENTS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::ZombieHead,
+ Item::SkeletonSkull,
+ Item::CreeperHead,
+ Item::DragonHead,
+ Item::WitherSkeletonSkull,
+ Item::PiglinHead,
+ Item::PlayerHead,
+ ])
+});
+pub static BREAKS_DECORATED_POTS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::Trident,
+ Item::DiamondSword,
+ Item::StoneSword,
+ Item::GoldenSword,
+ Item::NetheriteSword,
+ Item::WoodenSword,
+ Item::IronSword,
+ Item::DiamondAxe,
+ Item::StoneAxe,
+ Item::GoldenAxe,
+ Item::NetheriteAxe,
+ Item::WoodenAxe,
+ Item::IronAxe,
+ Item::DiamondPickaxe,
+ Item::StonePickaxe,
+ Item::GoldenPickaxe,
+ Item::NetheritePickaxe,
+ Item::WoodenPickaxe,
+ Item::IronPickaxe,
+ Item::DiamondShovel,
+ Item::StoneShovel,
+ Item::GoldenShovel,
+ Item::NetheriteShovel,
+ Item::WoodenShovel,
+ Item::IronShovel,
+ Item::DiamondHoe,
+ Item::StoneHoe,
+ Item::GoldenHoe,
+ Item::NetheriteHoe,
+ Item::WoodenHoe,
+ Item::IronHoe,
+ ])
+});
+pub static SAND: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::Sand,
+ Item::RedSand,
+ Item::SuspiciousSand,
+ Item::SuspiciousSand,
+ ])
+});
+pub static LOGS_THAT_BURN: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::DarkOakLog,
+ Item::DarkOakWood,
+ Item::StrippedDarkOakLog,
+ Item::StrippedDarkOakWood,
+ Item::OakLog,
+ Item::OakWood,
+ Item::StrippedOakLog,
+ Item::StrippedOakWood,
+ Item::AcaciaLog,
+ Item::AcaciaWood,
+ Item::StrippedAcaciaLog,
+ Item::StrippedAcaciaWood,
+ Item::BirchLog,
+ Item::BirchWood,
+ Item::StrippedBirchLog,
+ Item::StrippedBirchWood,
+ Item::JungleLog,
+ Item::JungleWood,
+ Item::StrippedJungleLog,
+ Item::StrippedJungleWood,
+ Item::SpruceLog,
+ Item::SpruceWood,
+ Item::StrippedSpruceLog,
+ Item::StrippedSpruceWood,
+ Item::MangroveLog,
+ Item::MangroveWood,
+ Item::StrippedMangroveLog,
+ Item::StrippedMangroveWood,
+ Item::CherryLog,
+ Item::CherryWood,
+ Item::StrippedCherryLog,
+ Item::StrippedCherryWood,
+ ])
+});
+pub static CHERRY_LOGS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::CherryLog,
+ Item::CherryWood,
+ Item::StrippedCherryLog,
+ Item::StrippedCherryWood,
+ ])
+});
+pub static DAMPENS_VIBRATIONS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::WhiteWool,
+ Item::OrangeWool,
+ Item::MagentaWool,
+ Item::LightBlueWool,
+ Item::YellowWool,
+ Item::LimeWool,
+ Item::PinkWool,
+ Item::GrayWool,
+ Item::LightGrayWool,
+ Item::CyanWool,
+ Item::PurpleWool,
+ Item::BlueWool,
+ Item::BrownWool,
+ Item::GreenWool,
+ Item::RedWool,
+ Item::BlackWool,
+ Item::WhiteCarpet,
+ Item::OrangeCarpet,
+ Item::MagentaCarpet,
+ Item::LightBlueCarpet,
+ Item::YellowCarpet,
+ Item::LimeCarpet,
+ Item::PinkCarpet,
+ Item::GrayCarpet,
+ Item::LightGrayCarpet,
+ Item::CyanCarpet,
+ Item::PurpleCarpet,
+ Item::BlueCarpet,
+ Item::BrownCarpet,
+ Item::GreenCarpet,
+ Item::RedCarpet,
+ Item::BlackCarpet,
+ ])
+});
+pub static DIAMOND_ORES: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::DiamondOre, Item::DeepslateDiamondOre]));
+pub static WOOL: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::WhiteWool,
+ Item::OrangeWool,
+ Item::MagentaWool,
+ Item::LightBlueWool,
+ Item::YellowWool,
+ Item::LimeWool,
+ Item::PinkWool,
+ Item::GrayWool,
+ Item::LightGrayWool,
+ Item::CyanWool,
+ Item::PurpleWool,
+ Item::BlueWool,
+ Item::BrownWool,
+ Item::GreenWool,
+ Item::RedWool,
+ Item::BlackWool,
+ ])
+});
+pub static WOODEN_TRAPDOORS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::AcaciaTrapdoor,
+ Item::BirchTrapdoor,
+ Item::DarkOakTrapdoor,
+ Item::JungleTrapdoor,
+ Item::OakTrapdoor,
+ Item::SpruceTrapdoor,
+ Item::CrimsonTrapdoor,
+ Item::WarpedTrapdoor,
+ Item::MangroveTrapdoor,
+ Item::BambooTrapdoor,
+ Item::CherryTrapdoor,
+ ])
+});
+pub static FLOWERS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::FloweringAzaleaLeaves,
+ Item::FloweringAzalea,
+ Item::MangrovePropagule,
+ Item::CherryLeaves,
+ Item::PinkPetals,
+ Item::Dandelion,
+ Item::Poppy,
+ Item::BlueOrchid,
+ Item::Allium,
+ Item::AzureBluet,
+ Item::RedTulip,
+ Item::OrangeTulip,
+ Item::WhiteTulip,
+ Item::PinkTulip,
+ Item::OxeyeDaisy,
+ Item::Cornflower,
+ Item::LilyOfTheValley,
+ Item::WitherRose,
+ Item::Torchflower,
+ Item::Sunflower,
+ Item::Lilac,
+ Item::Peony,
+ Item::RoseBush,
+ Item::PitcherPlant,
+ ])
+});
+pub static BANNERS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::WhiteBanner,
+ Item::OrangeBanner,
+ Item::MagentaBanner,
+ Item::LightBlueBanner,
+ Item::YellowBanner,
+ Item::LimeBanner,
+ Item::PinkBanner,
+ Item::GrayBanner,
+ Item::LightGrayBanner,
+ Item::CyanBanner,
+ Item::PurpleBanner,
+ Item::BlueBanner,
+ Item::BrownBanner,
+ Item::GreenBanner,
+ Item::RedBanner,
+ Item::BlackBanner,
+ ])
+});
+pub static TERRACOTTA: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::Terracotta,
+ Item::WhiteTerracotta,
+ Item::OrangeTerracotta,
+ Item::MagentaTerracotta,
+ Item::LightBlueTerracotta,
+ Item::YellowTerracotta,
+ Item::LimeTerracotta,
+ Item::PinkTerracotta,
+ Item::GrayTerracotta,
+ Item::LightGrayTerracotta,
+ Item::CyanTerracotta,
+ Item::PurpleTerracotta,
+ Item::BlueTerracotta,
+ Item::BrownTerracotta,
+ Item::GreenTerracotta,
+ Item::RedTerracotta,
+ Item::BlackTerracotta,
+ ])
+});
+pub static COALS: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::Coal, Item::Charcoal]));
+pub static BIRCH_LOGS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::BirchLog,
+ Item::BirchWood,
+ Item::StrippedBirchLog,
+ Item::StrippedBirchWood,
+ ])
+});
+pub static PIGLIN_REPELLENTS: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::SoulTorch, Item::SoulLantern, Item::SoulCampfire]));
+pub static CREEPER_DROP_MUSIC_DISCS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::MusicDisc13,
+ Item::MusicDiscCat,
+ Item::MusicDiscBlocks,
+ Item::MusicDiscChirp,
+ Item::MusicDiscFar,
+ Item::MusicDiscMall,
+ Item::MusicDiscMellohi,
+ Item::MusicDiscStal,
+ Item::MusicDiscStrad,
+ Item::MusicDiscWard,
+ Item::MusicDisc11,
+ Item::MusicDiscWait,
+ ])
+});
+pub static SLABS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::BambooMosaicSlab,
+ Item::StoneSlab,
+ Item::SmoothStoneSlab,
+ Item::StoneBrickSlab,
+ Item::SandstoneSlab,
+ Item::PurpurSlab,
+ Item::QuartzSlab,
+ Item::RedSandstoneSlab,
+ Item::BrickSlab,
+ Item::CobblestoneSlab,
+ Item::NetherBrickSlab,
+ Item::PetrifiedOakSlab,
+ Item::PrismarineSlab,
+ Item::PrismarineBrickSlab,
+ Item::DarkPrismarineSlab,
+ Item::PolishedGraniteSlab,
+ Item::SmoothRedSandstoneSlab,
+ Item::MossyStoneBrickSlab,
+ Item::PolishedDioriteSlab,
+ Item::MossyCobblestoneSlab,
+ Item::EndStoneBrickSlab,
+ Item::SmoothSandstoneSlab,
+ Item::SmoothQuartzSlab,
+ Item::GraniteSlab,
+ Item::AndesiteSlab,
+ Item::RedNetherBrickSlab,
+ Item::PolishedAndesiteSlab,
+ Item::DioriteSlab,
+ Item::CutSandstoneSlab,
+ Item::CutRedSandstoneSlab,
+ Item::BlackstoneSlab,
+ Item::PolishedBlackstoneBrickSlab,
+ Item::PolishedBlackstoneSlab,
+ Item::CobbledDeepslateSlab,
+ Item::PolishedDeepslateSlab,
+ Item::DeepslateTileSlab,
+ Item::DeepslateBrickSlab,
+ Item::WaxedWeatheredCutCopperSlab,
+ Item::WaxedExposedCutCopperSlab,
+ Item::WaxedCutCopperSlab,
+ Item::OxidizedCutCopperSlab,
+ Item::WeatheredCutCopperSlab,
+ Item::ExposedCutCopperSlab,
+ Item::CutCopperSlab,
+ Item::WaxedOxidizedCutCopperSlab,
+ Item::MudBrickSlab,
+ Item::OakSlab,
+ Item::SpruceSlab,
+ Item::BirchSlab,
+ Item::JungleSlab,
+ Item::AcaciaSlab,
+ Item::DarkOakSlab,
+ Item::CrimsonSlab,
+ Item::WarpedSlab,
+ Item::MangroveSlab,
+ Item::BambooSlab,
+ Item::CherrySlab,
+ ])
+});
+pub static ANVIL: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::Anvil, Item::ChippedAnvil, Item::DamagedAnvil]));
+pub static STAIRS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::BambooMosaicStairs,
+ Item::CobblestoneStairs,
+ Item::SandstoneStairs,
+ Item::NetherBrickStairs,
+ Item::StoneBrickStairs,
+ Item::BrickStairs,
+ Item::PurpurStairs,
+ Item::QuartzStairs,
+ Item::RedSandstoneStairs,
+ Item::PrismarineBrickStairs,
+ Item::PrismarineStairs,
+ Item::DarkPrismarineStairs,
+ Item::PolishedGraniteStairs,
+ Item::SmoothRedSandstoneStairs,
+ Item::MossyStoneBrickStairs,
+ Item::PolishedDioriteStairs,
+ Item::MossyCobblestoneStairs,
+ Item::EndStoneBrickStairs,
+ Item::StoneStairs,
+ Item::SmoothSandstoneStairs,
+ Item::SmoothQuartzStairs,
+ Item::GraniteStairs,
+ Item::AndesiteStairs,
+ Item::RedNetherBrickStairs,
+ Item::PolishedAndesiteStairs,
+ Item::DioriteStairs,
+ Item::BlackstoneStairs,
+ Item::PolishedBlackstoneBrickStairs,
+ Item::PolishedBlackstoneStairs,
+ Item::CobbledDeepslateStairs,
+ Item::PolishedDeepslateStairs,
+ Item::DeepslateTileStairs,
+ Item::DeepslateBrickStairs,
+ Item::OxidizedCutCopperStairs,
+ Item::WeatheredCutCopperStairs,
+ Item::ExposedCutCopperStairs,
+ Item::CutCopperStairs,
+ Item::WaxedWeatheredCutCopperStairs,
+ Item::WaxedExposedCutCopperStairs,
+ Item::WaxedCutCopperStairs,
+ Item::WaxedOxidizedCutCopperStairs,
+ Item::MudBrickStairs,
+ Item::OakStairs,
+ Item::SpruceStairs,
+ Item::BirchStairs,
+ Item::JungleStairs,
+ Item::AcaciaStairs,
+ Item::DarkOakStairs,
+ Item::CrimsonStairs,
+ Item::WarpedStairs,
+ Item::MangroveStairs,
+ Item::BambooStairs,
+ Item::CherryStairs,
+ ])
+});
+pub static STONE_CRAFTING_MATERIALS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::Cobblestone,
+ Item::Blackstone,
+ Item::CobbledDeepslate,
+ ])
+});
+pub static FISHES: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::Cod,
+ Item::CookedCod,
+ Item::Salmon,
+ Item::CookedSalmon,
+ Item::Pufferfish,
+ Item::TropicalFish,
+ ])
+});
+pub static SOUL_FIRE_BASE_BLOCKS: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::SoulSand, Item::SoulSoil]));
+pub static AXOLOTL_TEMPT_ITEMS: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::TropicalFishBucket]));
+pub static WOOL_CARPETS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::WhiteCarpet,
+ Item::OrangeCarpet,
+ Item::MagentaCarpet,
+ Item::LightBlueCarpet,
+ Item::YellowCarpet,
+ Item::LimeCarpet,
+ Item::PinkCarpet,
+ Item::GrayCarpet,
+ Item::LightGrayCarpet,
+ Item::CyanCarpet,
+ Item::PurpleCarpet,
+ Item::BlueCarpet,
+ Item::BrownCarpet,
+ Item::GreenCarpet,
+ Item::RedCarpet,
+ Item::BlackCarpet,
+ ])
+});
+pub static VILLAGER_PLANTABLE_SEEDS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::WheatSeeds,
+ Item::Potato,
+ Item::Carrot,
+ Item::BeetrootSeeds,
+ Item::TorchflowerSeeds,
+ Item::PitcherPod,
+ ])
+});
+pub static WOODEN_DOORS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::OakDoor,
+ Item::SpruceDoor,
+ Item::BirchDoor,
+ Item::JungleDoor,
+ Item::AcaciaDoor,
+ Item::DarkOakDoor,
+ Item::CrimsonDoor,
+ Item::WarpedDoor,
+ Item::MangroveDoor,
+ Item::BambooDoor,
+ Item::CherryDoor,
+ ])
+});
+pub static COAL_ORES: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::CoalOre, Item::DeepslateCoalOre]));
+pub static TOOLS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::Trident,
+ Item::DiamondSword,
+ Item::StoneSword,
+ Item::GoldenSword,
+ Item::NetheriteSword,
+ Item::WoodenSword,
+ Item::IronSword,
+ Item::DiamondAxe,
+ Item::StoneAxe,
+ Item::GoldenAxe,
+ Item::NetheriteAxe,
+ Item::WoodenAxe,
+ Item::IronAxe,
+ Item::DiamondPickaxe,
+ Item::StonePickaxe,
+ Item::GoldenPickaxe,
+ Item::NetheritePickaxe,
+ Item::WoodenPickaxe,
+ Item::IronPickaxe,
+ Item::DiamondShovel,
+ Item::StoneShovel,
+ Item::GoldenShovel,
+ Item::NetheriteShovel,
+ Item::WoodenShovel,
+ Item::IronShovel,
+ Item::DiamondHoe,
+ Item::StoneHoe,
+ Item::GoldenHoe,
+ Item::NetheriteHoe,
+ Item::WoodenHoe,
+ Item::IronHoe,
+ ])
+});
+pub static BUTTONS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::OakButton,
+ Item::SpruceButton,
+ Item::BirchButton,
+ Item::JungleButton,
+ Item::AcaciaButton,
+ Item::DarkOakButton,
+ Item::CrimsonButton,
+ Item::WarpedButton,
+ Item::MangroveButton,
+ Item::BambooButton,
+ Item::CherryButton,
+ Item::StoneButton,
+ Item::PolishedBlackstoneButton,
+ ])
+});
+pub static GOLD_ORES: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::GoldOre,
+ Item::NetherGoldOre,
+ Item::DeepslateGoldOre,
+ ])
+});
+pub static WART_BLOCKS: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::NetherWartBlock, Item::WarpedWartBlock]));
+pub static NON_FLAMMABLE_WOOD: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::WarpedStem,
+ Item::StrippedWarpedStem,
+ Item::WarpedHyphae,
+ Item::StrippedWarpedHyphae,
+ Item::CrimsonStem,
+ Item::StrippedCrimsonStem,
+ Item::CrimsonHyphae,
+ Item::StrippedCrimsonHyphae,
+ Item::CrimsonPlanks,
+ Item::WarpedPlanks,
+ Item::CrimsonSlab,
+ Item::WarpedSlab,
+ Item::CrimsonPressurePlate,
+ Item::WarpedPressurePlate,
+ Item::CrimsonFence,
+ Item::WarpedFence,
+ Item::CrimsonTrapdoor,
+ Item::WarpedTrapdoor,
+ Item::CrimsonFenceGate,
+ Item::WarpedFenceGate,
+ Item::CrimsonStairs,
+ Item::WarpedStairs,
+ Item::CrimsonButton,
+ Item::WarpedButton,
+ Item::CrimsonDoor,
+ Item::WarpedDoor,
+ Item::CrimsonSign,
+ Item::WarpedSign,
+ Item::WarpedHangingSign,
+ Item::CrimsonHangingSign,
+ ])
+});
+pub static PICKAXES: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::DiamondPickaxe,
+ Item::StonePickaxe,
+ Item::GoldenPickaxe,
+ Item::NetheritePickaxe,
+ Item::WoodenPickaxe,
+ Item::IronPickaxe,
+ ])
+});
+pub static HOES: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::DiamondHoe,
+ Item::StoneHoe,
+ Item::GoldenHoe,
+ Item::NetheriteHoe,
+ Item::WoodenHoe,
+ Item::IronHoe,
+ ])
+});
+pub static FENCES: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::NetherBrickFence,
+ Item::OakFence,
+ Item::AcaciaFence,
+ Item::DarkOakFence,
+ Item::SpruceFence,
+ Item::BirchFence,
+ Item::JungleFence,
+ Item::CrimsonFence,
+ Item::WarpedFence,
+ Item::MangroveFence,
+ Item::BambooFence,
+ Item::CherryFence,
+ ])
+});
+pub static COMPLETES_FIND_TREE_TUTORIAL: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::JungleLeaves,
+ Item::OakLeaves,
+ Item::SpruceLeaves,
+ Item::DarkOakLeaves,
+ Item::AcaciaLeaves,
+ Item::BirchLeaves,
+ Item::AzaleaLeaves,
+ Item::FloweringAzaleaLeaves,
+ Item::MangroveLeaves,
+ Item::CherryLeaves,
+ Item::NetherWartBlock,
+ Item::WarpedWartBlock,
+ Item::CrimsonStem,
+ Item::StrippedCrimsonStem,
+ Item::CrimsonHyphae,
+ Item::StrippedCrimsonHyphae,
+ Item::WarpedStem,
+ Item::StrippedWarpedStem,
+ Item::WarpedHyphae,
+ Item::StrippedWarpedHyphae,
+ Item::DarkOakLog,
+ Item::DarkOakWood,
+ Item::StrippedDarkOakLog,
+ Item::StrippedDarkOakWood,
+ Item::OakLog,
+ Item::OakWood,
+ Item::StrippedOakLog,
+ Item::StrippedOakWood,
+ Item::AcaciaLog,
+ Item::AcaciaWood,
+ Item::StrippedAcaciaLog,
+ Item::StrippedAcaciaWood,
+ Item::BirchLog,
+ Item::BirchWood,
+ Item::StrippedBirchLog,
+ Item::StrippedBirchWood,
+ Item::JungleLog,
+ Item::JungleWood,
+ Item::StrippedJungleLog,
+ Item::StrippedJungleWood,
+ Item::SpruceLog,
+ Item::SpruceWood,
+ Item::StrippedSpruceLog,
+ Item::StrippedSpruceWood,
+ Item::MangroveLog,
+ Item::MangroveWood,
+ Item::StrippedMangroveLog,
+ Item::StrippedMangroveWood,
+ Item::CherryLog,
+ Item::CherryWood,
+ Item::StrippedCherryLog,
+ Item::StrippedCherryWood,
+ ])
+});
+pub static SMALL_FLOWERS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::Dandelion,
+ Item::Poppy,
+ Item::BlueOrchid,
+ Item::Allium,
+ Item::AzureBluet,
+ Item::RedTulip,
+ Item::OrangeTulip,
+ Item::WhiteTulip,
+ Item::PinkTulip,
+ Item::OxeyeDaisy,
+ Item::Cornflower,
+ Item::LilyOfTheValley,
+ Item::WitherRose,
+ Item::Torchflower,
+ ])
+});
+pub static PIGLIN_FOOD: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::Porkchop, Item::CookedPorkchop]));
+pub static FENCE_GATES: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::AcaciaFenceGate,
+ Item::BirchFenceGate,
+ Item::DarkOakFenceGate,
+ Item::JungleFenceGate,
+ Item::OakFenceGate,
+ Item::SpruceFenceGate,
+ Item::CrimsonFenceGate,
+ Item::WarpedFenceGate,
+ Item::MangroveFenceGate,
+ Item::BambooFenceGate,
+ Item::CherryFenceGate,
+ ])
+});
+pub static OAK_LOGS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::OakLog,
+ Item::OakWood,
+ Item::StrippedOakLog,
+ Item::StrippedOakWood,
+ ])
+});
+pub static TRIM_MATERIALS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::IronIngot,
+ Item::CopperIngot,
+ Item::GoldIngot,
+ Item::LapisLazuli,
+ Item::Emerald,
+ Item::Diamond,
+ Item::NetheriteIngot,
+ Item::Redstone,
+ Item::Quartz,
+ Item::AmethystShard,
+ ])
+});
+pub static STONE_BRICKS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::StoneBricks,
+ Item::MossyStoneBricks,
+ Item::CrackedStoneBricks,
+ Item::ChiseledStoneBricks,
+ ])
+});
+pub static STONE_TOOL_MATERIALS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::Cobblestone,
+ Item::Blackstone,
+ Item::CobbledDeepslate,
+ ])
+});
+pub static LAPIS_ORES: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::LapisOre, Item::DeepslateLapisOre]));
+pub static SIGNS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::OakSign,
+ Item::SpruceSign,
+ Item::BirchSign,
+ Item::AcaciaSign,
+ Item::JungleSign,
+ Item::DarkOakSign,
+ Item::CrimsonSign,
+ Item::WarpedSign,
+ Item::MangroveSign,
+ Item::BambooSign,
+ Item::CherrySign,
+ ])
+});
+pub static DIRT: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::Dirt,
+ Item::GrassBlock,
+ Item::Podzol,
+ Item::CoarseDirt,
+ Item::Mycelium,
+ Item::RootedDirt,
+ Item::MossBlock,
+ Item::Mud,
+ Item::MuddyMangroveRoots,
+ ])
+});
+pub static LOGS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::CrimsonStem,
+ Item::StrippedCrimsonStem,
+ Item::CrimsonHyphae,
+ Item::StrippedCrimsonHyphae,
+ Item::WarpedStem,
+ Item::StrippedWarpedStem,
+ Item::WarpedHyphae,
+ Item::StrippedWarpedHyphae,
+ Item::DarkOakLog,
+ Item::DarkOakWood,
+ Item::StrippedDarkOakLog,
+ Item::StrippedDarkOakWood,
+ Item::OakLog,
+ Item::OakWood,
+ Item::StrippedOakLog,
+ Item::StrippedOakWood,
+ Item::AcaciaLog,
+ Item::AcaciaWood,
+ Item::StrippedAcaciaLog,
+ Item::StrippedAcaciaWood,
+ Item::BirchLog,
+ Item::BirchWood,
+ Item::StrippedBirchLog,
+ Item::StrippedBirchWood,
+ Item::JungleLog,
+ Item::JungleWood,
+ Item::StrippedJungleLog,
+ Item::StrippedJungleWood,
+ Item::SpruceLog,
+ Item::SpruceWood,
+ Item::StrippedSpruceLog,
+ Item::StrippedSpruceWood,
+ Item::MangroveLog,
+ Item::MangroveWood,
+ Item::StrippedMangroveLog,
+ Item::StrippedMangroveWood,
+ Item::CherryLog,
+ Item::CherryWood,
+ Item::StrippedCherryLog,
+ Item::StrippedCherryWood,
+ ])
+});
+pub static AXES: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::DiamondAxe,
+ Item::StoneAxe,
+ Item::GoldenAxe,
+ Item::NetheriteAxe,
+ Item::WoodenAxe,
+ Item::IronAxe,
+ ])
+});
+pub static CHEST_BOATS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::OakChestBoat,
+ Item::SpruceChestBoat,
+ Item::BirchChestBoat,
+ Item::JungleChestBoat,
+ Item::AcaciaChestBoat,
+ Item::DarkOakChestBoat,
+ Item::MangroveChestBoat,
+ Item::BambooChestRaft,
+ Item::CherryChestBoat,
+ ])
+});
+pub static BOOKSHELF_BOOKS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::Book,
+ Item::WrittenBook,
+ Item::EnchantedBook,
+ Item::WritableBook,
+ Item::KnowledgeBook,
+ ])
+});
+pub static ARROWS: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::Arrow, Item::TippedArrow, Item::SpectralArrow]));
+pub static PIGLIN_LOVED: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::GoldBlock,
+ Item::GildedBlackstone,
+ Item::LightWeightedPressurePlate,
+ Item::GoldIngot,
+ Item::Bell,
+ Item::Clock,
+ Item::GoldenCarrot,
+ Item::GlisteringMelonSlice,
+ Item::GoldenApple,
+ Item::EnchantedGoldenApple,
+ Item::GoldenHelmet,
+ Item::GoldenChestplate,
+ Item::GoldenLeggings,
+ Item::GoldenBoots,
+ Item::GoldenHorseArmor,
+ Item::GoldenSword,
+ Item::GoldenPickaxe,
+ Item::GoldenShovel,
+ Item::GoldenAxe,
+ Item::GoldenHoe,
+ Item::RawGold,
+ Item::RawGoldBlock,
+ Item::GoldOre,
+ Item::NetherGoldOre,
+ Item::DeepslateGoldOre,
+ ])
+});
+pub static WOODEN_BUTTONS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::OakButton,
+ Item::SpruceButton,
+ Item::BirchButton,
+ Item::JungleButton,
+ Item::AcaciaButton,
+ Item::DarkOakButton,
+ Item::CrimsonButton,
+ Item::WarpedButton,
+ Item::MangroveButton,
+ Item::BambooButton,
+ Item::CherryButton,
+ ])
+});
+pub static SMELTS_TO_GLASS: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::Sand, Item::RedSand]));
+pub static JUNGLE_LOGS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::JungleLog,
+ Item::JungleWood,
+ Item::StrippedJungleLog,
+ Item::StrippedJungleWood,
+ ])
+});
+pub static TRAPDOORS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::IronTrapdoor,
+ Item::AcaciaTrapdoor,
+ Item::BirchTrapdoor,
+ Item::DarkOakTrapdoor,
+ Item::JungleTrapdoor,
+ Item::OakTrapdoor,
+ Item::SpruceTrapdoor,
+ Item::CrimsonTrapdoor,
+ Item::WarpedTrapdoor,
+ Item::MangroveTrapdoor,
+ Item::BambooTrapdoor,
+ Item::CherryTrapdoor,
+ ])
+});
+pub static IGNORED_BY_PIGLIN_BABIES: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::Leather]));
+pub static WARPED_STEMS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::WarpedStem,
+ Item::StrippedWarpedStem,
+ Item::WarpedHyphae,
+ Item::StrippedWarpedHyphae,
+ ])
+});
+pub static BEACON_PAYMENT_ITEMS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::NetheriteIngot,
+ Item::Emerald,
+ Item::Diamond,
+ Item::GoldIngot,
+ Item::IronIngot,
+ ])
+});
+pub static IRON_ORES: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::IronOre, Item::DeepslateIronOre]));
+pub static BOATS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::OakBoat,
+ Item::SpruceBoat,
+ Item::BirchBoat,
+ Item::JungleBoat,
+ Item::AcaciaBoat,
+ Item::DarkOakBoat,
+ Item::MangroveBoat,
+ Item::BambooRaft,
+ Item::CherryBoat,
+ Item::OakChestBoat,
+ Item::SpruceChestBoat,
+ Item::BirchChestBoat,
+ Item::JungleChestBoat,
+ Item::AcaciaChestBoat,
+ Item::DarkOakChestBoat,
+ Item::MangroveChestBoat,
+ Item::BambooChestRaft,
+ Item::CherryChestBoat,
+ ])
+});
+pub static RAILS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::Rail,
+ Item::PoweredRail,
+ Item::DetectorRail,
+ Item::ActivatorRail,
+ ])
+});
+pub static TRIMMABLE_ARMOR: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::NetheriteHelmet,
+ Item::NetheriteChestplate,
+ Item::NetheriteLeggings,
+ Item::NetheriteBoots,
+ Item::DiamondHelmet,
+ Item::DiamondChestplate,
+ Item::DiamondLeggings,
+ Item::DiamondBoots,
+ Item::GoldenHelmet,
+ Item::GoldenChestplate,
+ Item::GoldenLeggings,
+ Item::GoldenBoots,
+ Item::IronHelmet,
+ Item::IronChestplate,
+ Item::IronLeggings,
+ Item::IronBoots,
+ Item::ChainmailHelmet,
+ Item::ChainmailChestplate,
+ Item::ChainmailLeggings,
+ Item::ChainmailBoots,
+ Item::LeatherHelmet,
+ Item::LeatherChestplate,
+ Item::LeatherLeggings,
+ Item::LeatherBoots,
+ Item::TurtleHelmet,
+ ])
+});
+pub static PLANKS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::OakPlanks,
+ Item::SprucePlanks,
+ Item::BirchPlanks,
+ Item::JunglePlanks,
+ Item::AcaciaPlanks,
+ Item::DarkOakPlanks,
+ Item::CrimsonPlanks,
+ Item::WarpedPlanks,
+ Item::MangrovePlanks,
+ Item::BambooPlanks,
+ Item::CherryPlanks,
+ ])
+});
+pub static FOX_FOOD: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::SweetBerries, Item::GlowBerries]));
+pub static BAMBOO_BLOCKS: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::BambooBlock, Item::StrippedBambooBlock]));
+pub static SNIFFER_FOOD: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::TorchflowerSeeds]));
+pub static CANDLES: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::Candle,
+ Item::WhiteCandle,
+ Item::OrangeCandle,
+ Item::MagentaCandle,
+ Item::LightBlueCandle,
+ Item::YellowCandle,
+ Item::LimeCandle,
+ Item::PinkCandle,
+ Item::GrayCandle,
+ Item::LightGrayCandle,
+ Item::CyanCandle,
+ Item::PurpleCandle,
+ Item::BlueCandle,
+ Item::BrownCandle,
+ Item::GreenCandle,
+ Item::RedCandle,
+ Item::BlackCandle,
+ ])
+});
+pub static SPRUCE_LOGS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::SpruceLog,
+ Item::SpruceWood,
+ Item::StrippedSpruceLog,
+ Item::StrippedSpruceWood,
+ ])
+});
+pub static SWORDS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::DiamondSword,
+ Item::StoneSword,
+ Item::GoldenSword,
+ Item::NetheriteSword,
+ Item::WoodenSword,
+ Item::IronSword,
+ ])
+});
+pub static LECTERN_BOOKS: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::WrittenBook, Item::WritableBook]));
+pub static DECORATED_POT_SHERDS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::AnglerPotterySherd,
+ Item::ArcherPotterySherd,
+ Item::ArmsUpPotterySherd,
+ Item::BladePotterySherd,
+ Item::BrewerPotterySherd,
+ Item::BurnPotterySherd,
+ Item::DangerPotterySherd,
+ Item::ExplorerPotterySherd,
+ Item::FriendPotterySherd,
+ Item::HeartPotterySherd,
+ Item::HeartbreakPotterySherd,
+ Item::HowlPotterySherd,
+ Item::MinerPotterySherd,
+ Item::MournerPotterySherd,
+ Item::PlentyPotterySherd,
+ Item::PrizePotterySherd,
+ Item::SheafPotterySherd,
+ Item::ShelterPotterySherd,
+ Item::SkullPotterySherd,
+ Item::SnortPotterySherd,
+ ])
+});
+pub static SAPLINGS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::OakSapling,
+ Item::SpruceSapling,
+ Item::BirchSapling,
+ Item::JungleSapling,
+ Item::AcaciaSapling,
+ Item::DarkOakSapling,
+ Item::Azalea,
+ Item::FloweringAzalea,
+ Item::MangrovePropagule,
+ Item::CherrySapling,
+ ])
+});
+pub static LEAVES: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::JungleLeaves,
+ Item::OakLeaves,
+ Item::SpruceLeaves,
+ Item::DarkOakLeaves,
+ Item::AcaciaLeaves,
+ Item::BirchLeaves,
+ Item::AzaleaLeaves,
+ Item::FloweringAzaleaLeaves,
+ Item::MangroveLeaves,
+ Item::CherryLeaves,
+ ])
+});
+pub static STONE_BUTTONS: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::StoneButton, Item::PolishedBlackstoneButton]));
+pub static REDSTONE_ORES: Lazy<HashSet<Item>> =
+ Lazy::new(|| HashSet::from_iter(vec![Item::RedstoneOre, Item::DeepslateRedstoneOre]));
+pub static CRIMSON_STEMS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::CrimsonStem,
+ Item::StrippedCrimsonStem,
+ Item::CrimsonHyphae,
+ Item::StrippedCrimsonHyphae,
+ ])
+});
+pub static HANGING_SIGNS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::OakHangingSign,
+ Item::SpruceHangingSign,
+ Item::BirchHangingSign,
+ Item::AcaciaHangingSign,
+ Item::CherryHangingSign,
+ Item::JungleHangingSign,
+ Item::DarkOakHangingSign,
+ Item::CrimsonHangingSign,
+ Item::WarpedHangingSign,
+ Item::MangroveHangingSign,
+ Item::BambooHangingSign,
+ ])
+});
+pub static WALLS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::CobblestoneWall,
+ Item::MossyCobblestoneWall,
+ Item::BrickWall,
+ Item::PrismarineWall,
+ Item::RedSandstoneWall,
+ Item::MossyStoneBrickWall,
+ Item::GraniteWall,
+ Item::StoneBrickWall,
+ Item::NetherBrickWall,
+ Item::AndesiteWall,
+ Item::RedNetherBrickWall,
+ Item::SandstoneWall,
+ Item::EndStoneBrickWall,
+ Item::DioriteWall,
+ Item::BlackstoneWall,
+ Item::PolishedBlackstoneBrickWall,
+ Item::PolishedBlackstoneWall,
+ Item::CobbledDeepslateWall,
+ Item::PolishedDeepslateWall,
+ Item::DeepslateTileWall,
+ Item::DeepslateBrickWall,
+ Item::MudBrickWall,
+ ])
+});
+pub static CLUSTER_MAX_HARVESTABLES: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::DiamondPickaxe,
+ Item::GoldenPickaxe,
+ Item::IronPickaxe,
+ Item::NetheritePickaxe,
+ Item::StonePickaxe,
+ Item::WoodenPickaxe,
+ ])
+});
+pub static MUSIC_DISCS: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::MusicDiscPigstep,
+ Item::MusicDiscOtherside,
+ Item::MusicDisc5,
+ Item::MusicDiscRelic,
+ Item::MusicDisc13,
+ Item::MusicDiscCat,
+ Item::MusicDiscBlocks,
+ Item::MusicDiscChirp,
+ Item::MusicDiscFar,
+ Item::MusicDiscMall,
+ Item::MusicDiscMellohi,
+ Item::MusicDiscStal,
+ Item::MusicDiscStrad,
+ Item::MusicDiscWard,
+ Item::MusicDisc11,
+ Item::MusicDiscWait,
+ ])
+});
+pub static FREEZE_IMMUNE_WEARABLES: Lazy<HashSet<Item>> = Lazy::new(|| {
+ HashSet::from_iter(vec![
+ Item::LeatherBoots,
+ Item::LeatherLeggings,
+ Item::LeatherChestplate,
+ Item::LeatherHelmet,
+ Item::LeatherHorseArmor,
+ ])
+});
diff --git a/azalea-registry/src/tags/mod.rs b/azalea-registry/src/tags/mod.rs
new file mode 100644
index 00000000..7ac46e6a
--- /dev/null
+++ b/azalea-registry/src/tags/mod.rs
@@ -0,0 +1,3 @@
+pub mod blocks;
+pub mod fluids;
+pub mod items;
diff --git a/azalea-world/src/container.rs b/azalea-world/src/container.rs
index 2cf8da8e..f1884265 100644
--- a/azalea-world/src/container.rs
+++ b/azalea-world/src/container.rs
@@ -1,5 +1,6 @@
use azalea_core::ResourceLocation;
-use bevy_ecs::system::Resource;
+use bevy_ecs::{component::Component, system::Resource};
+use derive_more::{Deref, DerefMut};
use log::error;
use nohash_hasher::IntMap;
use parking_lot::RwLock;
@@ -8,7 +9,7 @@ use std::{
sync::{Arc, Weak},
};
-use crate::{entity::WorldName, ChunkStorage, Instance};
+use crate::{ChunkStorage, Instance};
/// A container of [`Instance`]s (aka worlds). Instances are stored as a Weak
/// pointer here, so if no clients are using an instance it will be forgotten.
@@ -37,7 +38,7 @@ impl InstanceContainer {
}
/// Get a world from the container.
- pub fn get(&self, name: &WorldName) -> Option<Arc<RwLock<Instance>>> {
+ pub fn get(&self, name: &InstanceName) -> Option<Arc<RwLock<Instance>>> {
self.worlds.get(name).and_then(|world| world.upgrade())
}
@@ -76,3 +77,9 @@ impl InstanceContainer {
}
}
}
+
+/// The name of the [`Instance`](crate::Instance) (world) the entity is
+/// in. If two entities share the same world name, we assume they're in the same
+/// instance.
+#[derive(Component, Clone, Debug, PartialEq, Deref, DerefMut)]
+pub struct InstanceName(pub ResourceLocation);
diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs
index 77498efd..be2c46c1 100644
--- a/azalea-world/src/lib.rs
+++ b/azalea-world/src/lib.rs
@@ -6,7 +6,6 @@
mod bit_storage;
mod chunk_storage;
mod container;
-pub mod entity;
pub mod iterators;
pub mod palette;
mod world;
diff --git a/azalea-world/src/world.rs b/azalea-world/src/world.rs
index a2b351c2..4784880b 100644
--- a/azalea-world/src/world.rs
+++ b/azalea-world/src/world.rs
@@ -1,19 +1,8 @@
-use crate::{
- entity::{
- EntityInfos, EntityUuid, LoadedBy, Local, MinecraftEntityId, PartialEntityInfos, WorldName,
- },
- iterators::ChunkIterator,
- palette::Palette,
- ChunkStorage, InstanceContainer, PartialChunkStorage,
-};
-use azalea_block::{BlockState, BlockStates};
+use crate::{iterators::ChunkIterator, palette::Palette, ChunkStorage, PartialChunkStorage};
+use azalea_block::{BlockState, BlockStates, FluidState};
use azalea_core::{BlockPos, ChunkPos};
-use bevy_ecs::{
- entity::Entity,
- query::{Changed, With, Without},
- system::{Commands, Query, Res, ResMut},
-};
-use log::{debug, error, info};
+use bevy_ecs::{component::Component, entity::Entity};
+use derive_more::{Deref, DerefMut};
use nohash_hasher::IntMap;
use std::fmt::Formatter;
use std::{
@@ -45,133 +34,45 @@ impl PartialInstance {
}
}
-/// Remove new entities that have the same id as an existing entity, and
-/// increase the reference counts.
-///
-/// This is the reason why spawning entities into the ECS when you get a spawn
-/// entity packet is okay. This system will make sure the new entity gets
-/// combined into the old one.
-#[allow(clippy::type_complexity)]
-pub fn deduplicate_entities(
- mut commands: Commands,
- mut query: Query<
- (Entity, &MinecraftEntityId, &WorldName),
- (Changed<MinecraftEntityId>, Without<Local>),
- >,
- mut loaded_by_query: Query<&mut LoadedBy>,
- instance_container: Res<InstanceContainer>,
-) {
- // if this entity already exists, remove it
- for (new_entity, id, world_name) in query.iter_mut() {
- if let Some(world_lock) = instance_container.get(world_name) {
- let world = world_lock.write();
- if let Some(old_entity) = world.entity_by_id.get(id) {
- if old_entity == &new_entity {
- continue;
- }
+/// An entity ID used by Minecraft. These are not guaranteed to be unique in
+/// shared worlds, that's what [`Entity`] is for.
+#[derive(Component, Copy, Clone, Debug, PartialEq, Eq, Deref, DerefMut)]
+pub struct MinecraftEntityId(pub u32);
- // this entity already exists!!! remove the one we just added but increase
- // the reference count
- let new_loaded_by = loaded_by_query
- .get(new_entity)
- .unwrap_or_else(|_| panic!(
- "Entities should always have the LoadedBy component ({new_entity:?} did not)"
- ))
- .clone();
- let old_loaded_by = loaded_by_query.get_mut(*old_entity);
- // merge them if possible
- if let Ok(mut old_loaded_by) = old_loaded_by {
- old_loaded_by.extend(new_loaded_by.iter());
- }
- commands.entity(new_entity).despawn();
- info!(
- "Entity with id {id:?} / {new_entity:?} already existed in the world, merging it with {old_entity:?}"
- );
- break;
- }
- } else {
- error!("Entity was inserted into a world that doesn't exist.");
- }
+impl std::hash::Hash for MinecraftEntityId {
+ fn hash<H: std::hash::Hasher>(&self, hasher: &mut H) {
+ hasher.write_u32(self.0);
}
}
-
-// when a local entity is added, if there was already an entity with the same id
-// then delete the old entity
-#[allow(clippy::type_complexity)]
-pub fn deduplicate_local_entities(
- mut commands: Commands,
- mut query: Query<
- (Entity, &MinecraftEntityId, &WorldName),
- (Changed<MinecraftEntityId>, With<Local>),
- >,
- instance_container: Res<InstanceContainer>,
-) {
- // if this entity already exists, remove the old one
- for (new_entity, id, world_name) in query.iter_mut() {
- if let Some(world_lock) = instance_container.get(world_name) {
- let world = world_lock.write();
- if let Some(old_entity) = world.entity_by_id.get(id) {
- if old_entity == &new_entity {
- // lol
- continue;
- }
-
- commands.entity(*old_entity).despawn();
- debug!(
- "Added local entity {id:?} / {new_entity:?} but already existed in world as {old_entity:?}, despawning {old_entity:?}"
- );
- break;
- }
- } else {
- error!("Entity was inserted into a world that doesn't exist.");
- }
- }
+impl nohash_hasher::IsEnabled for MinecraftEntityId {}
+
+/// Keep track of certain metadatas that are only relevant for this partial
+/// world.
+#[derive(Debug, Default)]
+pub struct PartialEntityInfos {
+ // note: using MinecraftEntityId for entity ids is acceptable here since
+ // there's no chance of collisions here
+ /// The entity id of the player that owns this partial world. This will
+ /// make `RelativeEntityUpdate` pretend the entity doesn't exist so
+ /// it doesn't get modified from outside sources.
+ pub owner_entity: Option<Entity>,
+ /// A counter for each entity that tracks how many updates we've observed
+ /// for it.
+ ///
+ /// This is used for shared worlds (i.e. swarms), to make sure we don't
+ /// update entities twice on accident.
+ pub updates_received: IntMap<MinecraftEntityId, u32>,
}
-pub fn update_uuid_index(
- mut entity_infos: ResMut<EntityInfos>,
- query: Query<(Entity, &EntityUuid, Option<&Local>), Changed<EntityUuid>>,
-) {
- for (entity, &uuid, local) in query.iter() {
- // only add it if it doesn't already exist in
- // entity_infos.entity_by_uuid
- if local.is_none() {
- if let Some(old_entity) = entity_infos.entity_by_uuid.get(&uuid) {
- debug!(
- "Entity with UUID {uuid:?} already existed in the world, not adding to
- index (old ecs id: {old_entity:?} / new ecs id: {entity:?})"
- );
- continue;
- }
+impl PartialEntityInfos {
+ pub fn new(owner_entity: Option<Entity>) -> Self {
+ Self {
+ owner_entity,
+ updates_received: IntMap::default(),
}
- entity_infos.entity_by_uuid.insert(*uuid, entity);
}
}
-// /// Clear all entities in a chunk. This will not clear them from the
-// /// shared storage unless there are no other references to them.
-// pub fn clear_entities_in_chunk(
-// mut commands: Commands,
-// partial_entity_infos: &mut PartialEntityInfos,
-// chunk: &ChunkPos,
-// instance_container: &WorldContainer,
-// world_name: &WorldName,
-// mut query: Query<(&MinecraftEntityId, &mut ReferenceCount)>,
-// ) {
-// let world_lock = instance_container.get(world_name).unwrap();
-// let world = world_lock.read();
-
-// if let Some(entities) = world.entities_by_chunk.get(chunk).cloned() {
-// for &entity in &entities {
-// let (id, mut reference_count) = query.get_mut(entity).unwrap();
-// if partial_entity_infos.loaded_entity_ids.remove(id) {
-// // decrease the reference count
-// **reference_count -= 1;
-// }
-// }
-// }
-// }
-
/// A world where the chunks are stored as weak pointers. This is used for
/// shared worlds.
#[derive(Default, Debug)]
@@ -191,6 +92,18 @@ impl Instance {
self.entity_by_id.get(entity_id).copied()
}
+ pub fn get_block_state(&self, pos: &BlockPos) -> Option<BlockState> {
+ self.chunks.get_block_state(pos)
+ }
+
+ pub fn get_fluid_state(&self, pos: &BlockPos) -> Option<FluidState> {
+ self.chunks.get_block_state(pos).map(FluidState::from)
+ }
+
+ pub fn set_block_state(&self, pos: &BlockPos, state: BlockState) -> Option<BlockState> {
+ self.chunks.set_block_state(pos, state)
+ }
+
/// Find the coordinates of a block in the world.
///
/// Note that this is sorted by `x+y+z` and not `x^2+y^2+z^2`, for
@@ -290,31 +203,6 @@ impl Default for PartialInstance {
}
}
-/// System to keep the entity_by_id index up-to-date.
-pub fn update_entity_by_id_index(
- mut query: Query<
- (Entity, &MinecraftEntityId, &WorldName, Option<&Local>),
- Changed<MinecraftEntityId>,
- >,
- instance_container: Res<InstanceContainer>,
-) {
- for (entity, id, world_name, local) in query.iter_mut() {
- let world_lock = instance_container.get(world_name).unwrap();
- let mut world = world_lock.write();
- if local.is_none() {
- if let Some(old_entity) = world.entity_by_id.get(id) {
- debug!(
- "Entity with ID {id:?} already existed in the world, not adding to
- index (old ecs id: {old_entity:?} / new ecs id: {entity:?})"
- );
- continue;
- }
- }
- world.entity_by_id.insert(*id, entity);
- debug!("Added {entity:?} to {world_name:?} with {id:?}.");
- }
-}
-
impl From<ChunkStorage> for Instance {
/// Make an empty world from this `ChunkStorage`. This is meant to be a
/// convenience function for tests.
diff --git a/azalea/Cargo.toml b/azalea/Cargo.toml
index 4b396e39..da574353 100644
--- a/azalea/Cargo.toml
+++ b/azalea/Cargo.toml
@@ -40,6 +40,7 @@ thiserror = "^1.0.43"
tokio = "^1.29.1"
uuid = "1.4.0"
bevy_log = "0.11.0"
+azalea-entity = { version = "0.1.0", path = "../azalea-entity" }
[features]
default = ["log"]
diff --git a/azalea/examples/testbot.rs b/azalea/examples/testbot.rs
index 1774d005..d9bd8681 100644
--- a/azalea/examples/testbot.rs
+++ b/azalea/examples/testbot.rs
@@ -89,7 +89,7 @@ async fn handle(mut bot: Client, event: Event, _state: State) -> anyhow::Result<
bot.disconnect();
}
let Some(sender) = m.username() else {
- return Ok(())
+ return Ok(());
};
// let mut ecs = bot.ecs.lock();
// let entity = bot
@@ -164,6 +164,21 @@ async fn handle(mut bot: Client, event: Event, _state: State) -> anyhow::Result<
bot.chat("no diamond block found");
}
}
+ "mineblock" => {
+ let target_pos = bot
+ .world()
+ .read()
+ .find_block(bot.position(), &azalea::Block::DiamondBlock.into());
+ if let Some(target_pos) = target_pos {
+ // +1 to stand on top of the block
+ bot.chat("ok mining diamond block");
+ bot.look_at(target_pos.center());
+ bot.mine(target_pos).await;
+ bot.chat("finished mining");
+ } else {
+ bot.chat("no diamond block found");
+ }
+ }
"lever" => {
let target_pos = bot
.world()
@@ -171,7 +186,7 @@ async fn handle(mut bot: Client, event: Event, _state: State) -> anyhow::Result<
.find_block(bot.position(), &azalea::Block::Lever.into());
let Some(target_pos) = target_pos else {
bot.chat("no lever found");
- return Ok(())
+ return Ok(());
};
bot.goto(BlockPosGoal::from(target_pos));
bot.look_at(target_pos.center());
@@ -188,7 +203,7 @@ async fn handle(mut bot: Client, event: Event, _state: State) -> anyhow::Result<
.find_block(bot.position(), &azalea::Block::Chest.into());
let Some(target_pos) = target_pos else {
bot.chat("no chest found");
- return Ok(())
+ return Ok(());
};
bot.look_at(target_pos.center());
let container = bot.open_container(target_pos).await;
diff --git a/azalea/src/bot.rs b/azalea/src/bot.rs
index 47c825ca..7940e7b0 100644
--- a/azalea/src/bot.rs
+++ b/azalea/src/bot.rs
@@ -9,9 +9,10 @@ use crate::ecs::{
system::{Commands, Query},
};
use azalea_core::Vec3;
+use azalea_entity::{
+ clamp_look_direction, metadata::Player, EyeHeight, Jumping, Local, LookDirection, Position,
+};
use azalea_physics::{force_jump_listener, PhysicsSet};
-use azalea_world::entity::{clamp_look_direction, EyeHeight, LookDirection};
-use azalea_world::entity::{metadata::Player, Jumping, Local, Position};
use bevy_app::{FixedUpdate, Update};
use bevy_ecs::prelude::Event;
use bevy_ecs::schedule::IntoSystemConfigs;
diff --git a/azalea/src/lib.rs b/azalea/src/lib.rs
index 1c6966c5..297199a0 100644
--- a/azalea/src/lib.rs
+++ b/azalea/src/lib.rs
@@ -6,6 +6,7 @@
mod auto_respawn;
mod bot;
mod container;
+pub mod mining;
pub mod pathfinder;
pub mod prelude;
pub mod swarm;
@@ -17,9 +18,10 @@ pub use azalea_brigadier as brigadier;
pub use azalea_chat::FormattedText;
pub use azalea_client::*;
pub use azalea_core::{BlockPos, Vec3};
+pub use azalea_entity as entity;
pub use azalea_protocol as protocol;
pub use azalea_registry::{Block, EntityKind, Item};
-pub use azalea_world::{entity, Instance};
+pub use azalea_world::Instance;
pub use bot::DefaultBotPlugins;
use ecs::component::Component;
use futures::Future;
diff --git a/azalea/src/mining.rs b/azalea/src/mining.rs
new file mode 100644
index 00000000..8ba16436
--- /dev/null
+++ b/azalea/src/mining.rs
@@ -0,0 +1,40 @@
+use azalea_client::{
+ interact::SwingArmEvent,
+ mining::{Mining, StartMiningBlockEvent},
+ Client, TickBroadcast,
+};
+use azalea_core::BlockPos;
+
+pub trait MiningExt {
+ /// Start mining a block.
+ async fn mine(&mut self, position: BlockPos);
+}
+
+impl MiningExt for Client {
+ /// Start mining a block. This won't turn the bot's head towards the block,
+ /// so you'll have to do that yourself with [`look_at`].
+ ///
+ /// [`look_at`]: crate::prelude::BotClientExt::look_at
+ async fn mine(&mut self, position: BlockPos) {
+ self.ecs.lock().send_event(StartMiningBlockEvent {
+ entity: self.entity,
+ position,
+ });
+ // vanilla sends an extra swing arm packet when we start mining
+ self.ecs.lock().send_event(SwingArmEvent {
+ entity: self.entity,
+ });
+
+ let mut receiver = {
+ let ecs = self.ecs.lock();
+ let tick_broadcast = ecs.resource::<TickBroadcast>();
+ tick_broadcast.subscribe()
+ };
+ while receiver.recv().await.is_ok() {
+ let ecs = self.ecs.lock();
+ if ecs.get::<Mining>(self.entity).is_none() {
+ break;
+ }
+ }
+ }
+}
diff --git a/azalea/src/pathfinder/mod.rs b/azalea/src/pathfinder/mod.rs
index 9547d263..f4e4d599 100644
--- a/azalea/src/pathfinder/mod.rs
+++ b/azalea/src/pathfinder/mod.rs
@@ -16,13 +16,11 @@ use crate::ecs::{
use astar::Edge;
use azalea_client::{StartSprintEvent, StartWalkEvent};
use azalea_core::{BlockPos, CardinalDirection};
+use azalea_entity::metadata::Player;
+use azalea_entity::Local;
+use azalea_entity::{Physics, Position};
use azalea_physics::PhysicsSet;
-use azalea_world::entity::metadata::Player;
-use azalea_world::entity::Local;
-use azalea_world::{
- entity::{Physics, Position, WorldName},
- InstanceContainer,
-};
+use azalea_world::{InstanceContainer, InstanceName};
use bevy_app::{FixedUpdate, Update};
use bevy_ecs::prelude::Event;
use bevy_ecs::schedule::IntoSystemConfigs;
@@ -106,7 +104,7 @@ pub struct ComputePath(Task<Option<PathFoundEvent>>);
fn goto_listener(
mut commands: Commands,
mut events: EventReader<GotoEvent>,
- mut query: Query<(&Position, &WorldName)>,
+ mut query: Query<(&Position, &InstanceName)>,
instance_container: Res<InstanceContainer>,
) {
let thread_pool = AsyncComputeTaskPool::get();
diff --git a/azalea/src/prelude.rs b/azalea/src/prelude.rs
index 87cb0b53..ff3c11de 100644
--- a/azalea/src/prelude.rs
+++ b/azalea/src/prelude.rs
@@ -2,8 +2,8 @@
//! re-exported here.
pub use crate::{
- bot::BotClientExt, container::ContainerClientExt, pathfinder::PathfinderClientExt,
- ClientBuilder,
+ bot::BotClientExt, container::ContainerClientExt, mining::MiningExt,
+ pathfinder::PathfinderClientExt, ClientBuilder,
};
pub use azalea_client::{Account, Client, Event};
// this is necessary to make the macros that reference bevy_ecs work
diff --git a/azalea/src/swarm/events.rs b/azalea/src/swarm/events.rs
index b4752abf..3b290608 100644
--- a/azalea/src/swarm/events.rs
+++ b/azalea/src/swarm/events.rs
@@ -1,5 +1,5 @@
use azalea_client::LocalPlayer;
-use azalea_world::entity::MinecraftEntityId;
+use azalea_world::MinecraftEntityId;
use bevy_app::{App, Plugin, Update};
use bevy_ecs::prelude::*;
use derive_more::{Deref, DerefMut};
diff --git a/codegen/.gitignore b/codegen/.gitignore
index 2ef6e1be..ee2504d7 100755
--- a/codegen/.gitignore
+++ b/codegen/.gitignore
@@ -1,3 +1,5 @@
-downloads
__pycache__
*.tmp
+
+downloads
+__cache__
diff --git a/codegen/genblocks.py b/codegen/genblocks.py
index 45e7683e..5e28b60a 100755
--- a/codegen/genblocks.py
+++ b/codegen/genblocks.py
@@ -20,7 +20,7 @@ ordered_blocks = lib.extract.get_ordered_blocks_burger(version_id)
block_states_report = lib.extract.get_block_states_report(version_id)
lib.code.blocks.generate_blocks(
- block_states_burger, block_states_report, ordered_blocks, mappings)
+ block_states_burger, block_states_report, pixlyzer_block_datas, ordered_blocks, mappings)
lib.code.shapes.generate_block_shapes(
pixlyzer_block_datas, shape_datas['shapes'], shape_datas['aabbs'], block_states_report, block_states_burger, mappings)
diff --git a/codegen/genregistries.py b/codegen/genregistries.py
index e24dcc6a..01e84cb3 100755
--- a/codegen/genregistries.py
+++ b/codegen/genregistries.py
@@ -3,16 +3,30 @@ import lib.code.registry
import lib.code.version
import lib.code.packet
import lib.code.utils
+import lib.code.tags
import lib.download
import lib.extract
import lib.utils
-version_id = lib.code.version.get_version_id()
-registries = lib.extract.get_registries_report(version_id)
+def generate(version_id: str):
+ registries = lib.extract.get_registries_report(version_id)
-lib.code.registry.generate_registries(registries)
-lib.code.inventory.update_menus(registries['minecraft:menu']['entries'])
+ lib.code.registry.generate_registries(registries)
+ lib.code.inventory.update_menus(registries['minecraft:menu']['entries'])
-lib.code.utils.fmt()
-print('Done!')
+ block_tags = lib.extract.get_registry_tags(version_id, 'blocks')
+ item_tags = lib.extract.get_registry_tags(version_id, 'items')
+ fluid_tags = lib.extract.get_registry_tags(version_id, 'fluids')
+
+ lib.code.tags.generate_tags(block_tags, 'blocks', 'Block')
+ lib.code.tags.generate_tags(item_tags, 'items', 'Item')
+ lib.code.tags.generate_tags(fluid_tags, 'fluids', 'Fluid')
+
+ lib.code.utils.fmt()
+
+ print('Done!')
+
+if __name__ == '__main__':
+ version_id = lib.code.version.get_version_id()
+ generate(version_id)
diff --git a/codegen/lib/code/blocks.py b/codegen/lib/code/blocks.py
index a01df648..3af19fa8 100755
--- a/codegen/lib/code/blocks.py
+++ b/codegen/lib/code/blocks.py
@@ -13,7 +13,7 @@ BLOCKS_RS_DIR = get_dir_location('../azalea-block/src/generated.rs')
# - Block: Has properties and states.
-def generate_blocks(blocks_burger: dict, blocks_report: dict, ordered_blocks: list[str], mappings: Mappings):
+def generate_blocks(blocks_burger: dict, blocks_report: dict, pixlyzer_block_datas: dict, ordered_blocks: list[str], mappings: Mappings):
with open(BLOCKS_RS_DIR, 'r') as f:
existing_code = f.read().splitlines()
@@ -90,6 +90,7 @@ def generate_blocks(blocks_burger: dict, blocks_report: dict, ordered_blocks: li
for block_id in ordered_blocks:
block_data_burger = blocks_burger[block_id]
block_data_report = blocks_report['minecraft:' + block_id]
+ block_data_pixlyzer = pixlyzer_block_datas[f'minecraft:{block_id}']
block_properties = block_data_burger.get('states', [])
block_properties_burger = block_data_burger.get('states', [])
@@ -134,9 +135,28 @@ def generate_blocks(blocks_burger: dict, blocks_report: dict, ordered_blocks: li
else:
properties_code += '\n }'
+ # make the block behavior
+ behavior_constructor = 'BlockBehavior::new()'
+ # requires tool
+ if block_data_pixlyzer.get('requires_tool'):
+ behavior_constructor += '.requires_correct_tool_for_drops()'
+ # strength
+ destroy_time = block_data_pixlyzer.get('hardness')
+ explosion_resistance = block_data_pixlyzer.get('explosion_resistance')
+ if destroy_time and explosion_resistance:
+ behavior_constructor += f'.strength({destroy_time}, {explosion_resistance})'
+ elif destroy_time:
+ behavior_constructor += f'.destroy_time({destroy_time})'
+ elif explosion_resistance:
+ behavior_constructor += f'.explosion_resistance({explosion_resistance})'
+ # friction
+ friction = block_data_pixlyzer.get('friction')
+ if friction != None:
+ behavior_constructor += f'.friction({friction})'
+
# TODO: use burger to generate the blockbehavior
new_make_block_states_macro_code.append(
- f' {block_id} => BlockBehavior::default(), {properties_code},')
+ f' {block_id} => {behavior_constructor}, {properties_code},')
new_make_block_states_macro_code.append(' }')
new_make_block_states_macro_code.append('}')
diff --git a/codegen/lib/code/shapes.py b/codegen/lib/code/shapes.py
index 7682fe53..18f2ccbd 100755
--- a/codegen/lib/code/shapes.py
+++ b/codegen/lib/code/shapes.py
@@ -66,7 +66,7 @@ def simplify_shapes(blocks: dict, shapes: dict, aabbs: dict):
def generate_block_shapes_code(blocks: dict, shapes: dict, block_states_report, block_datas_burger, mappings: Mappings):
- # look at downloads/generator-mod-*/blockCollisionShapes.json for format of blocks and shapes
+ # look at __cache__/generator-mod-*/blockCollisionShapes.json for format of blocks and shapes
generated_shape_code = ''
for (shape_id, shape) in sorted(shapes.items(), key=lambda shape: int(shape[0])):
diff --git a/codegen/lib/code/tags.py b/codegen/lib/code/tags.py
new file mode 100644
index 00000000..40b60ae3
--- /dev/null
+++ b/codegen/lib/code/tags.py
@@ -0,0 +1,35 @@
+from lib.utils import to_snake_case, upper_first_letter, get_dir_location, to_camel_case
+
+REGISTRIES_DIR = get_dir_location('../azalea-registry/src/tags')
+
+
+def generate_tags(registries: dict, file_name: str, struct_name: str):
+ tags_dir = f'{REGISTRIES_DIR}/{file_name}.rs'
+
+ generated = f'''// This file was generated by codegen/lib/code/tags.py, don't edit it manually!
+
+use std::collections::HashSet;
+
+use once_cell::sync::Lazy;
+
+use crate::{struct_name};
+
+'''
+
+ for tag_name, tag in registries.items():
+ tag_name = tag_name.replace('/', '_')
+ static_set_name = to_snake_case(tag_name).upper()
+ generated += f'pub static {static_set_name}: Lazy<HashSet<{struct_name}>> = Lazy::new(|| HashSet::from_iter(vec!['
+
+ queue = tag['values'].copy()
+ while queue != []:
+ item = queue.pop(0)
+ namespace, item_name = item.split(':')
+ if namespace[0] == '#':
+ queue += registries[item_name]['values']
+ continue
+ generated += f'{struct_name}::{upper_first_letter(to_camel_case(item_name))},\n'
+ generated += ']));\n'
+
+ with open(tags_dir, 'w') as f:
+ f.write(generated) \ No newline at end of file
diff --git a/codegen/lib/download.py b/codegen/lib/download.py
index 1b22fbcc..319c6080 100755
--- a/codegen/lib/download.py
+++ b/codegen/lib/download.py
@@ -5,47 +5,47 @@ import requests
import json
import os
-# make sure the downloads directory exists
-print('Making downloads')
-if not os.path.exists(get_dir_location('downloads')):
- print('Made downloads directory.', get_dir_location('downloads'))
- os.mkdir(get_dir_location('downloads'))
+# make sure the cache directory exists
+print('Making __cache__')
+if not os.path.exists(get_dir_location('__cache__')):
+ print('Made __cache__ directory.', get_dir_location('__cache__'))
+ os.mkdir(get_dir_location('__cache__'))
def get_burger():
- if not os.path.exists(get_dir_location('downloads/Burger')):
+ if not os.path.exists(get_dir_location('__cache__/Burger')):
print('\033[92mDownloading Burger...\033[m')
os.system(
- f'cd {get_dir_location("downloads")} && git clone https://github.com/pokechu22/Burger && cd Burger && git pull')
+ f'cd {get_dir_location("__cache__")} && git clone https://github.com/pokechu22/Burger && cd Burger && git pull')
print('\033[92mInstalling dependencies...\033[m')
- os.system(f'cd {get_dir_location("downloads")}/Burger && pip install six jawa')
+ os.system(f'cd {get_dir_location("__cache__")}/Burger && pip install six jawa')
def get_pixlyzer():
- if not os.path.exists(get_dir_location('downloads/pixlyzer')):
+ if not os.path.exists(get_dir_location('__cache__/pixlyzer')):
print('\033[92mDownloading bixilon/pixlyzer...\033[m')
os.system(
- f'cd {get_dir_location("downloads")} && git clone https://gitlab.bixilon.de/bixilon/pixlyzer.git && cd pixlyzer && git pull')
- return get_dir_location('downloads/pixlyzer')
+ f'cd {get_dir_location("__cache__")} && git clone https://gitlab.bixilon.de/bixilon/pixlyzer.git && cd pixlyzer && git pull')
+ return get_dir_location('__cache__/pixlyzer')
def get_version_manifest():
- if not os.path.exists(get_dir_location(f'downloads/version_manifest.json')):
+ if not os.path.exists(get_dir_location(f'__cache__/version_manifest.json')):
print(
f'\033[92mDownloading version manifest...\033[m')
version_manifest_data = requests.get(
'https://piston-meta.mojang.com/mc/game/version_manifest_v2.json').json()
- with open(get_dir_location(f'downloads/version_manifest.json'), 'w') as f:
+ with open(get_dir_location(f'__cache__/version_manifest.json'), 'w') as f:
json.dump(version_manifest_data, f)
else:
- with open(get_dir_location(f'downloads/version_manifest.json'), 'r') as f:
+ with open(get_dir_location(f'__cache__/version_manifest.json'), 'r') as f:
version_manifest_data = json.load(f)
return version_manifest_data
def get_version_data(version_id: str):
- if not os.path.exists(get_dir_location(f'downloads/{version_id}.json')):
+ if not os.path.exists(get_dir_location(f'__cache__/{version_id}.json')):
version_manifest_data = get_version_manifest()
print(
@@ -55,60 +55,60 @@ def get_version_data(version_id: str):
filter(lambda v: v['id'] == version_id, version_manifest_data['versions']))['url']
except StopIteration:
raise ValueError(
- f'No version with id {version_id} found. Maybe delete downloads/version_manifest.json and try again?')
+ f'No version with id {version_id} found. Maybe delete __cache__/version_manifest.json and try again?')
package_data = requests.get(package_url).json()
- with open(get_dir_location(f'downloads/{version_id}.json'), 'w') as f:
+ with open(get_dir_location(f'__cache__/{version_id}.json'), 'w') as f:
json.dump(package_data, f)
else:
- with open(get_dir_location(f'downloads/{version_id}.json'), 'r') as f:
+ with open(get_dir_location(f'__cache__/{version_id}.json'), 'r') as f:
package_data = json.load(f)
return package_data
def get_client_jar(version_id: str):
- if not os.path.exists(get_dir_location(f'downloads/client-{version_id}.jar')):
+ if not os.path.exists(get_dir_location(f'__cache__/client-{version_id}.jar')):
package_data = get_version_data(version_id)
print('\033[92mDownloading client jar...\033[m')
client_jar_url = package_data['downloads']['client']['url']
- with open(get_dir_location(f'downloads/client-{version_id}.jar'), 'wb') as f:
+ with open(get_dir_location(f'__cache__/client-{version_id}.jar'), 'wb') as f:
f.write(requests.get(client_jar_url).content)
def get_server_jar(version_id: str):
- if not os.path.exists(get_dir_location(f'downloads/server-{version_id}.jar')):
+ if not os.path.exists(get_dir_location(f'__cache__/server-{version_id}.jar')):
package_data = get_version_data(version_id)
print('\033[92mDownloading server jar...\033[m')
server_jar_url = package_data['downloads']['server']['url']
- with open(get_dir_location(f'downloads/server-{version_id}.jar'), 'wb') as f:
+ with open(get_dir_location(f'__cache__/server-{version_id}.jar'), 'wb') as f:
f.write(requests.get(server_jar_url).content)
def get_mappings_for_version(version_id: str):
- if not os.path.exists(get_dir_location(f'downloads/mappings-{version_id}.txt')):
+ if not os.path.exists(get_dir_location(f'__cache__/mappings-{version_id}.txt')):
package_data = get_version_data(version_id)
client_mappings_url = package_data['downloads']['client_mappings']['url']
mappings_text = requests.get(client_mappings_url).text
- with open(get_dir_location(f'downloads/mappings-{version_id}.txt'), 'w') as f:
+ with open(get_dir_location(f'__cache__/mappings-{version_id}.txt'), 'w') as f:
f.write(mappings_text)
else:
- with open(get_dir_location(f'downloads/mappings-{version_id}.txt'), 'r') as f:
+ with open(get_dir_location(f'__cache__/mappings-{version_id}.txt'), 'r') as f:
mappings_text = f.read()
return Mappings.parse(mappings_text)
def get_yarn_versions():
# https://meta.fabricmc.net/v2/versions/yarn
- if not os.path.exists(get_dir_location('downloads/yarn_versions.json')):
+ if not os.path.exists(get_dir_location('__cache__/yarn_versions.json')):
print('\033[92mDownloading yarn versions...\033[m')
yarn_versions_data = requests.get(
'https://meta.fabricmc.net/v2/versions/yarn').json()
- with open(get_dir_location('downloads/yarn_versions.json'), 'w') as f:
+ with open(get_dir_location('__cache__/yarn_versions.json'), 'w') as f:
json.dump(yarn_versions_data, f)
else:
- with open(get_dir_location('downloads/yarn_versions.json'), 'r') as f:
+ with open(get_dir_location('__cache__/yarn_versions.json'), 'r') as f:
yarn_versions_data = json.load(f)
return yarn_versions_data
@@ -121,7 +121,7 @@ def get_yarn_data(version_id: str):
def get_fabric_api_versions():
# https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api/maven-metadata.xml
- if not os.path.exists(get_dir_location('downloads/fabric_api_versions.json')):
+ if not os.path.exists(get_dir_location('__cache__/fabric_api_versions.json')):
print('\033[92mDownloading Fabric API versions...\033[m')
fabric_api_versions_xml_text = requests.get(
'https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api/maven-metadata.xml').text
@@ -138,17 +138,17 @@ def get_fabric_api_versions():
for version_el in versions_el.findall('version'):
fabric_api_versions.append(version_el.text)
- with open(get_dir_location('downloads/fabric_api_versions.json'), 'w') as f:
+ with open(get_dir_location('__cache__/fabric_api_versions.json'), 'w') as f:
f.write(json.dumps(fabric_api_versions))
else:
- with open(get_dir_location('downloads/fabric_api_versions.json'), 'r') as f:
+ with open(get_dir_location('__cache__/fabric_api_versions.json'), 'r') as f:
fabric_api_versions = json.loads(f.read())
return fabric_api_versions
def get_fabric_loader_versions():
# https://meta.fabricmc.net/v2/versions/loader
- if not os.path.exists(get_dir_location('downloads/fabric_loader_versions.json')):
+ if not os.path.exists(get_dir_location('__cache__/fabric_loader_versions.json')):
print('\033[92mDownloading Fabric loader versions...\033[m')
fabric_api_versions_json = requests.get(
'https://meta.fabricmc.net/v2/versions/loader').json()
@@ -157,10 +157,10 @@ def get_fabric_loader_versions():
for version in fabric_api_versions_json:
fabric_api_versions.append(version['version'])
- with open(get_dir_location('downloads/fabric_loader_versions.json'), 'w') as f:
+ with open(get_dir_location('__cache__/fabric_loader_versions.json'), 'w') as f:
f.write(json.dumps(fabric_api_versions))
else:
- with open(get_dir_location('downloads/fabric_loader_versions.json'), 'r') as f:
+ with open(get_dir_location('__cache__/fabric_loader_versions.json'), 'r') as f:
fabric_api_versions = json.loads(f.read())
return fabric_api_versions
@@ -174,14 +174,14 @@ def clear_version_cache():
'fabric_loader_versions.json'
]
for file in files:
- if os.path.exists(get_dir_location(f'downloads/{file}')):
- os.remove(get_dir_location(f'downloads/{file}'))
+ if os.path.exists(get_dir_location(f'__cache__/{file}')):
+ os.remove(get_dir_location(f'__cache__/{file}'))
- burger_path = get_dir_location("downloads/Burger")
+ burger_path = get_dir_location("__cache__/Burger")
if os.path.exists(burger_path):
os.system(
f'cd {burger_path} && git pull')
- pixlyzer_path = get_dir_location('downloads/pixlyzer')
+ pixlyzer_path = get_dir_location('__cache__/pixlyzer')
if os.path.exists(pixlyzer_path):
os.system(
f'cd {pixlyzer_path} && git pull') \ No newline at end of file
diff --git a/codegen/lib/extract.py b/codegen/lib/extract.py
index f7c78d29..608673fa 100755
--- a/codegen/lib/extract.py
+++ b/codegen/lib/extract.py
@@ -12,27 +12,44 @@ import os
def generate_data_from_server_jar(version_id: str):
- if os.path.exists(get_dir_location(f'downloads/generated-{version_id}')):
+ if os.path.exists(get_dir_location(f'__cache__/generated-{version_id}')):
return
get_server_jar(version_id)
os.system(
- f'cd {get_dir_location(f"downloads")} && java -DbundlerMainClass=net.minecraft.data.Main -jar {get_dir_location(f"downloads/server-{version_id}.jar")} --all --output \"{get_dir_location(f"downloads/generated-{version_id}")}\"'
+ f'cd {get_dir_location(f"__cache__")} && java -DbundlerMainClass=net.minecraft.data.Main -jar {get_dir_location(f"__cache__/server-{version_id}.jar")} --all --output \"{get_dir_location(f"__cache__/generated-{version_id}")}\"'
)
def get_block_states_report(version_id: str):
generate_data_from_server_jar(version_id)
- with open(get_dir_location(f'downloads/generated-{version_id}/reports/blocks.json'), 'r') as f:
+ with open(get_dir_location(f'__cache__/generated-{version_id}/reports/blocks.json'), 'r') as f:
return json.load(f)
def get_registries_report(version_id: str):
generate_data_from_server_jar(version_id)
- with open(get_dir_location(f'downloads/generated-{version_id}/reports/registries.json'), 'r') as f:
+ with open(get_dir_location(f'__cache__/generated-{version_id}/reports/registries.json'), 'r') as f:
return json.load(f)
+def get_registry_tags(version_id: str, name: str):
+ generate_data_from_server_jar(version_id)
+ tags_directory = get_dir_location(f'__cache__/generated-{version_id}/data/minecraft/tags/{name}')
+ if not os.path.exists(tags_directory):
+ return {}
+ tags = {}
+ for root, dirs, files in os.walk(tags_directory, topdown=False):
+ for name in files:
+ file = os.path.join(root, name)
+ relative_path = file.replace(tags_directory, '')[1:]
+ if not file.endswith('.json'):
+ continue
+ with open(file, 'r') as f:
+ tags[relative_path[:-5]] = json.load(f)
+ return tags
+
+
def get_block_states_burger(version_id: str):
burger_data = get_burger_data_for_version(version_id)
return burger_data[0]['blocks']['block']
@@ -96,15 +113,15 @@ def run_python_command_and_download_deps(command):
def get_burger_data_for_version(version_id: str):
- if not os.path.exists(get_dir_location(f'downloads/burger-{version_id}.json')):
+ if not os.path.exists(get_dir_location(f'__cache__/burger-{version_id}.json')):
get_burger()
get_client_jar(version_id)
print('\033[92mRunning Burger...\033[m')
run_python_command_and_download_deps(
- f'cd {get_dir_location("downloads/Burger")} && {determine_python_command()} munch.py {get_dir_location("downloads")}/client-{version_id}.jar --output {get_dir_location("downloads")}/burger-{version_id}.json'
+ f'cd {get_dir_location("__cache__/Burger")} && {determine_python_command()} munch.py {get_dir_location("__cache__")}/client-{version_id}.jar --output {get_dir_location("__cache__")}/burger-{version_id}.json'
)
- with open(get_dir_location(f'downloads/burger-{version_id}.json'), 'r') as f:
+ with open(get_dir_location(f'__cache__/burger-{version_id}.json'), 'r') as f:
return json.load(f)
@@ -113,7 +130,7 @@ def get_pixlyzer_data(version_id: str, category: str):
Gets data from Pixlyzer. Note that this requires Yarn to release updates first.
'''
- target_dir = get_dir_location(f'downloads/pixlyzer-{version_id}')
+ target_dir = get_dir_location(f'__cache__/pixlyzer-{version_id}')
# TODO: right now this False is hard-coded, it should retry with this
# enabled if # initially getting the data fails
@@ -249,7 +266,7 @@ def get_pixlyzer_data(version_id: str, category: str):
def get_file_from_jar(version_id: str, file_dir: str):
get_client_jar(version_id)
- with ZipFile(get_dir_location(f'downloads/client-{version_id}.jar')) as z:
+ with ZipFile(get_dir_location(f'__cache__/client-{version_id}.jar')) as z:
with z.open(file_dir) as f:
return f.read()
diff --git a/codegen/migrate.py b/codegen/migrate.py
index 0222ab00..6e51c2df 100755
--- a/codegen/migrate.py
+++ b/codegen/migrate.py
@@ -133,9 +133,8 @@ language = lib.extract.get_en_us_lang(new_version_id)
lib.code.language.write_language(language)
print('Generating registries...')
-registries = lib.extract.get_registries_report(new_version_id)
-lib.code.registry.generate_registries(registries)
-lib.code.inventory.update_menus(registries['minecraft:menu']['entries'])
+import genregistries
+genregistries.generate(new_version_id)
print('Generating entity metadata...')
burger_entities_data = new_burger_data[0]['entities']