aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock215
-rwxr-xr-xCargo.toml1
-rw-r--r--azalea-client/Cargo.toml9
-rwxr-xr-xazalea-client/src/chat.rs24
-rw-r--r--azalea-client/src/client.rs102
-rw-r--r--azalea-client/src/disconnect.rs29
-rw-r--r--azalea-client/src/entity_query.rs12
-rw-r--r--azalea-client/src/events.rs12
-rw-r--r--azalea-client/src/lib.rs1
-rw-r--r--azalea-client/src/local_player.rs15
-rw-r--r--azalea-client/src/movement.rs37
-rw-r--r--azalea-client/src/packet_handling.rs66
-rwxr-xr-xazalea-client/src/player.rs4
-rw-r--r--azalea-client/src/task_pool.rs26
-rw-r--r--azalea-core/Cargo.toml8
-rw-r--r--azalea-ecs/Cargo.toml14
-rwxr-xr-xazalea-ecs/azalea-ecs-macros/Cargo.toml15
-rw-r--r--azalea-ecs/azalea-ecs-macros/src/component.rs125
-rw-r--r--azalea-ecs/azalea-ecs-macros/src/fetch.rs466
-rwxr-xr-xazalea-ecs/azalea-ecs-macros/src/lib.rs525
-rw-r--r--azalea-ecs/azalea-ecs-macros/src/utils/attrs.rs45
-rw-r--r--azalea-ecs/azalea-ecs-macros/src/utils/mod.rs227
-rw-r--r--azalea-ecs/azalea-ecs-macros/src/utils/shape.rs21
-rw-r--r--azalea-ecs/azalea-ecs-macros/src/utils/symbol.rs35
-rw-r--r--azalea-ecs/src/lib.rs157
-rw-r--r--azalea-physics/Cargo.toml12
-rw-r--r--azalea-physics/src/collision/mod.rs8
-rw-r--r--azalea-physics/src/collision/world_collisions.rs8
-rw-r--r--azalea-physics/src/lib.rs68
-rw-r--r--azalea-protocol/Cargo.toml41
-rw-r--r--azalea-world/Cargo.toml3
-rw-r--r--azalea-world/src/container.rs12
-rw-r--r--azalea-world/src/entity/attributes.rs2
-rwxr-xr-xazalea-world/src/entity/data.rs2
-rwxr-xr-xazalea-world/src/entity/dimensions.rs2
-rw-r--r--azalea-world/src/entity/info.rs86
-rw-r--r--azalea-world/src/entity/metadata.rs262
-rw-r--r--azalea-world/src/entity/mod.rs6
-rw-r--r--azalea-world/src/world.rs8
-rw-r--r--azalea/Cargo.toml28
-rwxr-xr-xazalea/examples/pvp.rs2
-rw-r--r--azalea/examples/testbot.rs18
-rw-r--r--azalea/src/bot.rs26
-rw-r--r--azalea/src/lib.rs15
-rw-r--r--azalea/src/pathfinder/mod.rs20
-rw-r--r--azalea/src/pathfinder/moves.rs20
-rw-r--r--azalea/src/prelude.rs4
-rw-r--r--azalea/src/swarm/chat.rs18
-rw-r--r--azalea/src/swarm/events.rs8
-rw-r--r--azalea/src/swarm/mod.rs11
-rw-r--r--codegen/lib/code/entity.py14
51 files changed, 633 insertions, 2262 deletions
diff --git a/Cargo.lock b/Cargo.lock
index d342c77b..6058bc2a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -79,7 +79,7 @@ version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833"
dependencies = [
- "concurrent-queue 2.1.0",
+ "concurrent-queue",
"event-listener",
"futures-core",
]
@@ -105,7 +105,7 @@ checksum = "17adb73da160dfb475c183343c8cccd80721ea5a605d3eb57125f0a7b7a92d0b"
dependencies = [
"async-lock",
"async-task",
- "concurrent-queue 2.1.0",
+ "concurrent-queue",
"fastrand",
"futures-lite",
"slab",
@@ -176,11 +176,12 @@ dependencies = [
"azalea-chat",
"azalea-client",
"azalea-core",
- "azalea-ecs",
"azalea-physics",
"azalea-protocol",
"azalea-registry",
"azalea-world",
+ "bevy_app",
+ "bevy_ecs",
"bevy_tasks",
"derive_more",
"futures",
@@ -284,11 +285,12 @@ dependencies = [
"azalea-chat",
"azalea-core",
"azalea-crypto",
- "azalea-ecs",
"azalea-physics",
"azalea-protocol",
"azalea-registry",
"azalea-world",
+ "bevy_app",
+ "bevy_ecs",
"bevy_log",
"bevy_tasks",
"bevy_time",
@@ -332,26 +334,6 @@ dependencies = [
]
[[package]]
-name = "azalea-ecs"
-version = "0.6.0"
-dependencies = [
- "azalea-ecs-macros",
- "bevy_app",
- "bevy_ecs",
- "tokio",
-]
-
-[[package]]
-name = "azalea-ecs-macros"
-version = "0.6.0"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
- "toml 0.7.0",
-]
-
-[[package]]
name = "azalea-language"
version = "0.6.0"
dependencies = [
@@ -381,9 +363,11 @@ version = "0.6.0"
dependencies = [
"azalea-block",
"azalea-core",
- "azalea-ecs",
"azalea-registry",
"azalea-world",
+ "bevy_app",
+ "bevy_ecs",
+ "bevy_time",
"once_cell",
"parking_lot",
"uuid",
@@ -461,9 +445,10 @@ dependencies = [
"azalea-buf",
"azalea-chat",
"azalea-core",
- "azalea-ecs",
"azalea-nbt",
"azalea-registry",
+ "bevy_app",
+ "bevy_ecs",
"derive_more",
"enum-as-inner",
"log",
@@ -497,9 +482,9 @@ checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
[[package]]
name = "bevy_app"
-version = "0.9.1"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "536e4d0018347478545ed8b6cb6e57b9279ee984868e81b7c0e78e0fb3222e42"
+checksum = "960c6e444dc6a25dd51a2196f04872ae9e2e876802b66c391104849ec9225e38"
dependencies = [
"bevy_derive",
"bevy_ecs",
@@ -512,9 +497,9 @@ dependencies = [
[[package]]
name = "bevy_derive"
-version = "0.9.1"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7baf73c58d41c353c6fd08e6764a2e7420c9f19e8227b391c50981db6d0282a6"
+checksum = "cdf11701c01bf4dc7a3fac9f4547f3643d3db4cc1682af40c8c86e2f8734b617"
dependencies = [
"bevy_macro_utils",
"quote",
@@ -523,9 +508,9 @@ dependencies = [
[[package]]
name = "bevy_ecs"
-version = "0.9.1"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4c071d7c6bc9801253485e05d0c257284150de755391902746837ba21c0cf74"
+checksum = "fdc5b19451128091e8507c9247888359ca0bfa895e7f6ca749ccc55c5463bef6"
dependencies = [
"async-channel",
"bevy_ecs_macros",
@@ -536,16 +521,16 @@ dependencies = [
"downcast-rs",
"event-listener",
"fixedbitset",
- "fxhash",
+ "rustc-hash",
"serde",
"thread_local",
]
[[package]]
name = "bevy_ecs_macros"
-version = "0.9.1"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c15bd45438eeb681ad74f2d205bb07a5699f98f9524462a30ec764afab2742ce"
+checksum = "b1e79757319533bde006a4f30c268223ec6426371297182925932075ccfdae30"
dependencies = [
"bevy_macro_utils",
"proc-macro2",
@@ -555,9 +540,9 @@ dependencies = [
[[package]]
name = "bevy_log"
-version = "0.9.1"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c480bac54cf4ae76edc3ae9ae3fa7c5e1b385e7f2111ef5ec3fd00cf3a7998b"
+checksum = "47dcb09ec71145c80d88a84181cc1449d30f23c571bdd58c59c10eece82dfaa5"
dependencies = [
"android_log-sys",
"bevy_app",
@@ -571,20 +556,20 @@ dependencies = [
[[package]]
name = "bevy_macro_utils"
-version = "0.9.1"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "022bb69196deeea691b6997414af85bbd7f2b34a8914c4aa7a7ff4dfa44f7677"
+checksum = "f24ca3363292f1435641fbafd5c24ce362137dd7d69bee56dcaaa2bc1d512ffe"
dependencies = [
"quote",
"syn",
- "toml 0.5.11",
+ "toml_edit",
]
[[package]]
name = "bevy_math"
-version = "0.9.1"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d434c77ab766c806ed9062ef8a7285b3b02b47df51f188d4496199c3ac062eaf"
+checksum = "5e45e46c2ac0a92db3ae622f2ed690928fe2612e7c9470a46d0ed4c2c77e2e95"
dependencies = [
"glam",
"serde",
@@ -592,15 +577,15 @@ dependencies = [
[[package]]
name = "bevy_ptr"
-version = "0.9.1"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ec44f7655039546bc5d34d98de877083473f3e9b2b81d560c528d6d74d3eff4"
+checksum = "a96c24da064370917b92c2a84527e6a73b620c50ac5ef8b1af8c04ccf5256a7c"
[[package]]
name = "bevy_reflect"
-version = "0.9.1"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6deae303a7f69dc243b2fa35b5e193cc920229f448942080c8eb2dbd9de6d37a"
+checksum = "ab880e0eed9df5c99ce1a2f89edc11cdef1bc78413719b29e9ad7e3bc27f4c20"
dependencies = [
"bevy_math",
"bevy_ptr",
@@ -618,9 +603,9 @@ dependencies = [
[[package]]
name = "bevy_reflect_derive"
-version = "0.9.1"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2bf4cb9cd5acb4193f890f36cb63679f1502e2de025e66a63b194b8b133d018"
+checksum = "3b361b8671bdffe93978270dd770b03b48560c3127fdf9003f98111fb806bb11"
dependencies = [
"bevy_macro_utils",
"bit-set",
@@ -632,14 +617,14 @@ dependencies = [
[[package]]
name = "bevy_tasks"
-version = "0.9.1"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "680b16b53df9c9f24681dd95f4d772d83760bd19adf8bca00f358a3aad997853"
+checksum = "3e368e4177fe70d695d5cb67fb7480fa262de79948d9b883a21788b9abf5a85a"
dependencies = [
"async-channel",
"async-executor",
"async-task",
- "concurrent-queue 1.2.4",
+ "concurrent-queue",
"futures-lite",
"once_cell",
"wasm-bindgen-futures",
@@ -647,32 +632,47 @@ dependencies = [
[[package]]
name = "bevy_time"
-version = "0.9.1"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a5c38a6d3ea929c7f81e6adf5a6c62cf7e8c40f5106c2174d6057e9d8ea624d"
+checksum = "d2f2863cfc08fa38909e047a1bbc2dd71d0836057ed0840c69ace9dff3e0c298"
dependencies = [
"bevy_app",
"bevy_ecs",
"bevy_reflect",
"bevy_utils",
"crossbeam-channel",
+ "thiserror",
]
[[package]]
name = "bevy_utils"
-version = "0.9.1"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "16750aae52cd35bd7b60eb61cee883420b250e11b4a290b8d44b2b2941795739"
+checksum = "04d90ce493910ad9af3b4220ea6864c7d1472761086a98230ecac59c8d547e95"
dependencies = [
"ahash 0.7.6",
+ "bevy_utils_proc_macros",
"getrandom",
"hashbrown",
"instant",
+ "petgraph",
+ "thiserror",
"tracing",
"uuid",
]
[[package]]
+name = "bevy_utils_proc_macros"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62a42e465c446800c57a5bf65b64f4fa1c1f3a74efc2a64a2a001e4a4f548a2e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "bit-set"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -739,12 +739,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c"
[[package]]
-name = "cache-padded"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c"
-
-[[package]]
name = "cast"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -804,15 +798,6 @@ dependencies = [
[[package]]
name = "concurrent-queue"
-version = "1.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af4780a44ab5696ea9e28294517f1fffb421a83a25af521333c838635509db9c"
-dependencies = [
- "cache-padded",
-]
-
-[[package]]
-name = "concurrent-queue"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c278839b831783b70278b14df4d45e1beb1aad306c07bb796637de9a0e323e8e"
@@ -1200,15 +1185,6 @@ dependencies = [
]
[[package]]
-name = "fxhash"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
-dependencies = [
- "byteorder",
-]
-
-[[package]]
name = "generic-array"
version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1239,9 +1215,9 @@ checksum = "221996f774192f0f718773def8201c4ae31f02616a54ccfc2d358bb0e5cefdec"
[[package]]
name = "glam"
-version = "0.22.0"
+version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12f597d56c1bd55a811a1be189459e8fad2bbc272616375602443bdfb37fa774"
+checksum = "8e4afd9ad95555081e109fe1d21f2a30c691b5f0919c67dfa690a2e1eb6bd51c"
dependencies = [
"bytemuck",
"serde",
@@ -1581,15 +1557,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
[[package]]
-name = "nom8"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8"
-dependencies = [
- "memchr",
-]
-
-[[package]]
name = "nu-ansi-term"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1829,9 +1796,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.50"
+version = "1.0.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
+checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
dependencies = [
"unicode-ident",
]
@@ -2004,6 +1971,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
[[package]]
+name = "rustc-hash"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+
+[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2112,15 +2085,6 @@ dependencies = [
]
[[package]]
-name = "serde_spanned"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c68e921cef53841b8925c2abadd27c9b891d9613bdc43d6b823062866df38e8"
-dependencies = [
- "serde",
-]
-
-[[package]]
name = "serde_urlencoded"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2209,9 +2173,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "syn"
-version = "1.0.107"
+version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
@@ -2358,46 +2322,20 @@ dependencies = [
]
[[package]]
-name = "toml"
-version = "0.5.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "toml"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f560bc7fb3eb31f5eee1340c68a2160cad39605b7b9c9ec32045ddbdee13b85"
-dependencies = [
- "serde",
- "serde_spanned",
- "toml_datetime",
- "toml_edit",
-]
-
-[[package]]
name = "toml_datetime"
-version = "0.6.0"
+version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "886f31a9b85b6182cabd4d8b07df3b451afcc216563748201490940d2a28ed36"
-dependencies = [
- "serde",
-]
+checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622"
[[package]]
name = "toml_edit"
-version = "0.19.0"
+version = "0.19.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "233d8716cdc5d20ec88a18a839edaf545edc71efa4a5ff700ef4a102c26cd8fa"
+checksum = "9a1eb0622d28f4b9c90adc4ea4b2b46b47663fde9ac5fafcb14a1369d5508825"
dependencies = [
"indexmap",
- "nom8",
- "serde",
- "serde_spanned",
"toml_datetime",
+ "winnow",
]
[[package]]
@@ -2823,6 +2761,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
[[package]]
+name = "winnow"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee7b2c67f962bf5042bfd8b6a916178df33a26eec343ae064cb8e069f638fa6f"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
name = "winreg"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index febe6517..b7439bd1 100755
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,7 +15,6 @@ members = [
"azalea-buf",
"azalea-physics",
"azalea-registry",
- "azalea-ecs",
]
[profile.release]
diff --git a/azalea-client/Cargo.toml b/azalea-client/Cargo.toml
index 6bb31069..f25aa290 100644
--- a/azalea-client/Cargo.toml
+++ b/azalea-client/Cargo.toml
@@ -16,14 +16,15 @@ azalea-block = { path = "../azalea-block", version = "0.6.0" }
azalea-chat = { path = "../azalea-chat", version = "0.6.0" }
azalea-core = { path = "../azalea-core", version = "0.6.0" }
azalea-crypto = { path = "../azalea-crypto", version = "0.6.0" }
-azalea-ecs = { path = "../azalea-ecs", version = "0.6.0" }
azalea-physics = { path = "../azalea-physics", version = "0.6.0" }
azalea-protocol = { path = "../azalea-protocol", version = "0.6.0" }
azalea-registry = { path = "../azalea-registry", version = "0.6.0" }
azalea-world = { path = "../azalea-world", version = "0.6.0" }
-bevy_log = "0.9.1"
-bevy_tasks = "0.9.1"
-bevy_time = "0.9.1"
+bevy_app = "0.10.0"
+bevy_ecs = "0.10.0"
+bevy_log = "0.10.0"
+bevy_tasks = "0.10.0"
+bevy_time = "0.10.0"
derive_more = { version = "0.99.17", features = ["deref", "deref_mut"] }
futures = "0.3.25"
log = "0.4.17"
diff --git a/azalea-client/src/chat.rs b/azalea-client/src/chat.rs
index e127f0d7..0ae0250a 100755
--- a/azalea-client/src/chat.rs
+++ b/azalea-client/src/chat.rs
@@ -1,18 +1,18 @@
//! Implementations of chat-related features.
use azalea_chat::FormattedText;
-use azalea_ecs::{
- app::{App, Plugin},
- entity::Entity,
- event::{EventReader, EventWriter},
- schedule::IntoSystemDescriptor,
-};
use azalea_protocol::packets::game::{
clientbound_player_chat_packet::ClientboundPlayerChatPacket,
clientbound_system_chat_packet::ClientboundSystemChatPacket,
serverbound_chat_command_packet::ServerboundChatCommandPacket,
serverbound_chat_packet::{LastSeenMessagesUpdate, ServerboundChatPacket},
};
+use bevy_app::{App, Plugin};
+use bevy_ecs::{
+ entity::Entity,
+ event::{EventReader, EventWriter},
+ schedule::{IntoSystemConfig, IntoSystemConfigs},
+};
use std::{
sync::Arc,
time::{SystemTime, UNIX_EPOCH},
@@ -159,12 +159,12 @@ impl Plugin for ChatPlugin {
app.add_event::<SendChatEvent>()
.add_event::<SendChatKindEvent>()
.add_event::<ChatReceivedEvent>()
- .add_system(handle_send_chat_event.label("handle_send_chat_event"))
- .add_system(
- handle_send_chat_kind_event
- .label("handle_send_chat_kind_event")
- .after(handle_send_chat_event)
- .after(handle_send_packet_event),
+ .add_systems(
+ (
+ handle_send_chat_event,
+ handle_send_chat_kind_event.after(handle_send_packet_event),
+ )
+ .chain(),
);
}
}
diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs
index 661858db..79501fd4 100644
--- a/azalea-client/src/client.rs
+++ b/azalea-client/src/client.rs
@@ -6,25 +6,16 @@ use crate::{
death_event, handle_send_packet_event, update_in_loaded_chunk, GameProfileComponent,
LocalPlayer, PhysicsState, SendPacketEvent,
},
- movement::{local_player_ai_step, send_position, sprint_listener, walk_listener},
+ movement::PlayerMovePlugin,
packet_handling::{self, PacketHandlerPlugin, PacketReceiver},
player::retroactively_add_game_profile_component,
task_pool::TaskPoolPlugin,
- Account, PlayerInfo, StartSprintEvent, StartWalkEvent,
+ Account, PlayerInfo,
};
use azalea_auth::{game_profile::GameProfile, sessionserver::ClientSessionServerError};
use azalea_chat::FormattedText;
-use azalea_ecs::{
- app::{App, Plugin, PluginGroup, PluginGroupBuilder},
- bundle::Bundle,
- component::Component,
- entity::Entity,
- schedule::{IntoSystemDescriptor, ReportExecutionOrderAmbiguities, Schedule, Stage, SystemSet},
- AppTickExt,
-};
-use azalea_ecs::{ecs::Ecs, TickPlugin};
-use azalea_physics::PhysicsPlugin;
+use azalea_physics::{PhysicsPlugin, PhysicsSet};
use azalea_protocol::{
connect::{Connection, ConnectionError},
packets::{
@@ -46,13 +37,23 @@ use azalea_protocol::{
resolver, ServerAddress,
};
use azalea_world::{
- entity::{EntityPlugin, Local, WorldName},
- PartialWorld, World, WorldContainer,
+ entity::{EntityPlugin, EntityUpdateSet, Local, WorldName},
+ Instance, PartialWorld, WorldContainer,
+};
+use bevy_app::{App, CoreSchedule, Plugin, PluginGroup, PluginGroupBuilder};
+use bevy_ecs::{
+ bundle::Bundle,
+ component::Component,
+ entity::Entity,
+ schedule::IntoSystemConfig,
+ schedule::{LogLevel, ScheduleBuildSettings, ScheduleLabel},
+ world::World,
};
use bevy_log::LogPlugin;
+use bevy_time::{prelude::FixedTime, TimePlugin};
use log::{debug, error};
use parking_lot::{Mutex, RwLock};
-use std::{collections::HashMap, fmt::Debug, io, net::SocketAddr, sync::Arc};
+use std::{collections::HashMap, fmt::Debug, io, net::SocketAddr, sync::Arc, time::Duration};
use thiserror::Error;
use tokio::{sync::mpsc, time};
use uuid::Uuid;
@@ -86,7 +87,7 @@ pub struct Client {
/// The entity component system. You probably don't need to access this
/// directly. Note that if you're using a shared world (i.e. a swarm), this
/// will contain all entities in all worlds.
- pub ecs: Arc<Mutex<Ecs>>,
+ pub ecs: Arc<Mutex<World>>,
/// Use this to force the client to run the schedule outside of a tick.
pub run_schedule_sender: mpsc::UnboundedSender<()>,
@@ -120,7 +121,7 @@ impl Client {
pub fn new(
profile: GameProfile,
entity: Entity,
- ecs: Arc<Mutex<Ecs>>,
+ ecs: Arc<Mutex<World>>,
run_schedule_sender: mpsc::UnboundedSender<()>,
) -> Self {
Self {
@@ -180,7 +181,7 @@ impl Client {
/// Create a [`Client`] when you already have the ECS made with
/// [`start_ecs`]. You'd usually want to use [`Self::join`] instead.
pub async fn start_client(
- ecs_lock: Arc<Mutex<Ecs>>,
+ ecs_lock: Arc<Mutex<World>>,
account: &Account,
address: &ServerAddress,
resolved_address: &SocketAddr,
@@ -226,7 +227,7 @@ impl Client {
packet_writer_sender,
// default to an empty world, it'll be set correctly later when we
// get the login packet
- Arc::new(RwLock::new(World::default())),
+ Arc::new(RwLock::new(Instance::default())),
read_packets_task,
write_packets_task,
);
@@ -382,13 +383,13 @@ impl Client {
});
}
- pub fn local_player<'a>(&'a self, ecs: &'a mut Ecs) -> &'a LocalPlayer {
+ pub fn local_player<'a>(&'a self, ecs: &'a mut World) -> &'a LocalPlayer {
self.query::<&LocalPlayer>(ecs)
}
pub fn local_player_mut<'a>(
&'a self,
- ecs: &'a mut Ecs,
- ) -> azalea_ecs::ecs::Mut<'a, LocalPlayer> {
+ ecs: &'a mut World,
+ ) -> bevy_ecs::world::Mut<'a, LocalPlayer> {
self.query::<&mut LocalPlayer>(ecs)
}
@@ -416,7 +417,7 @@ impl Client {
/// client, then it'll be the same as the world the client has loaded.
/// 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<World>> {
+ pub fn world(&self) -> Arc<RwLock<Instance>> {
let world_name = self.component::<WorldName>();
let ecs = self.ecs.lock();
let world_container = ecs.resource::<WorldContainer>();
@@ -493,33 +494,20 @@ pub struct JoinedClientBundle {
pub struct AzaleaPlugin;
impl Plugin for AzaleaPlugin {
fn build(&self, app: &mut App) {
- app.add_event::<StartWalkEvent>()
- .add_event::<StartSprintEvent>();
-
- app.add_tick_system_set(
- SystemSet::new()
- .with_system(send_position.after("ai_step"))
- .with_system(update_in_loaded_chunk.before(send_position).after("travel"))
- .with_system(
- local_player_ai_step
- .before(azalea_physics::ai_step)
- .label("ai_step"),
- ),
+ // Minecraft ticks happen every 50ms
+ app.insert_resource(FixedTime::new(Duration::from_millis(50)));
+
+ app.add_system(
+ update_in_loaded_chunk
+ .after(PhysicsSet)
+ .after(handle_send_packet_event),
);
// fire the Death event when the player dies.
app.add_system(death_event);
- // walk and sprint event listeners
- app.add_system(walk_listener.label("walk_listener"))
- .add_system(
- sprint_listener
- .label("sprint_listener")
- .before("walk_listener"),
- );
-
// add GameProfileComponent when we get an AddPlayerEvent
- app.add_system(retroactively_add_game_profile_component.after("update_indexes"));
+ app.add_system(retroactively_add_game_profile_component.after(EntityUpdateSet::Index));
app.add_event::<SendPacketEvent>()
.add_system(handle_send_packet_event);
@@ -544,7 +532,12 @@ pub fn init_ecs_app() -> App {
let mut app = App::new();
- app.insert_resource(ReportExecutionOrderAmbiguities);
+ app.edit_schedule(CoreSchedule::Main, |schedule| {
+ schedule.set_build_settings(ScheduleBuildSettings {
+ ambiguity_detection: LogLevel::Warn,
+ ..Default::default()
+ });
+ });
app.add_plugins(DefaultPlugins);
app
@@ -554,17 +547,19 @@ pub fn init_ecs_app() -> App {
/// first.
#[doc(hidden)]
pub fn start_ecs(
- app: App,
+ mut app: App,
run_schedule_receiver: mpsc::UnboundedReceiver<()>,
run_schedule_sender: mpsc::UnboundedSender<()>,
-) -> Arc<Mutex<Ecs>> {
+) -> Arc<Mutex<World>> {
+ app.setup();
+
// all resources should have been added by now so we can take the ecs from the
// app
let ecs = Arc::new(Mutex::new(app.world));
tokio::spawn(run_schedule_loop(
ecs.clone(),
- app.schedule,
+ app.outer_schedule_label,
run_schedule_receiver,
));
tokio::spawn(tick_run_schedule_loop(run_schedule_sender));
@@ -573,14 +568,16 @@ pub fn start_ecs(
}
async fn run_schedule_loop(
- ecs: Arc<Mutex<Ecs>>,
- mut schedule: Schedule,
+ ecs: Arc<Mutex<World>>,
+ outer_schedule_label: Box<dyn ScheduleLabel>,
mut run_schedule_receiver: mpsc::UnboundedReceiver<()>,
) {
loop {
// whenever we get an event from run_schedule_receiver, run the schedule
run_schedule_receiver.recv().await;
- schedule.run(&mut ecs.lock());
+ let mut ecs = ecs.lock();
+ ecs.run_schedule_ref(&*outer_schedule_label);
+ ecs.clear_trackers();
}
}
@@ -609,7 +606,7 @@ impl PluginGroup for DefaultPlugins {
fn build(self) -> PluginGroupBuilder {
PluginGroupBuilder::start::<Self>()
.add(LogPlugin::default())
- .add(TickPlugin::default())
+ .add(TimePlugin::default())
.add(PacketHandlerPlugin)
.add(AzaleaPlugin)
.add(EntityPlugin)
@@ -618,5 +615,6 @@ impl PluginGroup for DefaultPlugins {
.add(TaskPoolPlugin::default())
.add(ChatPlugin)
.add(DisconnectPlugin)
+ .add(PlayerMovePlugin)
}
}
diff --git a/azalea-client/src/disconnect.rs b/azalea-client/src/disconnect.rs
index 9fd57e57..3b8d133e 100644
--- a/azalea-client/src/disconnect.rs
+++ b/azalea-client/src/disconnect.rs
@@ -1,30 +1,30 @@
//! Disconnect a client from the server.
-use azalea_ecs::{
- app::{App, CoreStage, Plugin},
+use bevy_app::{App, CoreSet, Plugin};
+use bevy_ecs::{
component::Component,
entity::Entity,
event::{EventReader, EventWriter},
query::Changed,
- schedule::IntoSystemDescriptor,
+ schedule::IntoSystemConfigs,
system::{Commands, Query},
- AppTickExt,
};
use derive_more::Deref;
-use crate::{client::JoinedClientBundle, movement::send_position, LocalPlayer};
+use crate::{client::JoinedClientBundle, LocalPlayer};
pub struct DisconnectPlugin;
impl Plugin for DisconnectPlugin {
fn build(&self, app: &mut App) {
- app.add_event::<DisconnectEvent>()
- .add_system_to_stage(CoreStage::PostUpdate, handle_disconnect)
- .add_tick_system(
- update_read_packets_task_running_component
- .before(disconnect_on_read_packets_ended)
- .before(send_position),
+ app.add_event::<DisconnectEvent>().add_systems(
+ (
+ update_read_packets_task_running_component,
+ disconnect_on_read_packets_ended,
+ remove_components_from_disconnected_players,
)
- .add_tick_system(disconnect_on_read_packets_ended);
+ .in_base_set(CoreSet::PostUpdate)
+ .chain(),
+ );
}
}
@@ -35,7 +35,10 @@ pub struct DisconnectEvent {
/// System that removes the [`JoinedClientBundle`] from the entity when it
/// receives a [`DisconnectEvent`].
-pub fn handle_disconnect(mut commands: Commands, mut events: EventReader<DisconnectEvent>) {
+pub fn remove_components_from_disconnected_players(
+ mut commands: Commands,
+ mut events: EventReader<DisconnectEvent>,
+) {
for DisconnectEvent { entity } in events.iter() {
commands.entity(*entity).remove::<JoinedClientBundle>();
}
diff --git a/azalea-client/src/entity_query.rs b/azalea-client/src/entity_query.rs
index e39a7d2f..8fe94659 100644
--- a/azalea-client/src/entity_query.rs
+++ b/azalea-client/src/entity_query.rs
@@ -1,10 +1,10 @@
use std::sync::Arc;
-use azalea_ecs::{
+use bevy_ecs::{
component::Component,
- ecs::Ecs,
entity::Entity,
query::{ROQueryItem, ReadOnlyWorldQuery, WorldQuery},
+ world::World,
};
use parking_lot::Mutex;
@@ -22,7 +22,7 @@ impl Client {
/// .is_some();
/// # }
/// ```
- pub fn query<'w, Q: WorldQuery>(&self, ecs: &'w mut Ecs) -> <Q as WorldQuery>::Item<'w> {
+ pub fn query<'w, Q: WorldQuery>(&self, ecs: &'w mut World) -> <Q as WorldQuery>::Item<'w> {
ecs.query::<Q>()
.get_mut(ecs, self.entity)
.expect("Our client is missing a required component.")
@@ -38,7 +38,7 @@ impl Client {
/// Note that this will very likely change in the future.
/// ```
/// use azalea_client::{Client, GameProfileComponent};
- /// use azalea_ecs::query::With;
+ /// use bevy_ecs::query::With;
/// use azalea_world::entity::{Position, metadata::Player};
///
/// # fn example(mut bot: Client, sender_name: String) {
@@ -74,7 +74,7 @@ impl Client {
}
pub trait EntityPredicate<Q: ReadOnlyWorldQuery, Filter: ReadOnlyWorldQuery> {
- fn find(&self, ecs_lock: Arc<Mutex<Ecs>>) -> Option<Entity>;
+ fn find(&self, ecs_lock: Arc<Mutex<World>>) -> Option<Entity>;
}
impl<F, Q, Filter> EntityPredicate<(Q,), Filter> for F
where
@@ -82,7 +82,7 @@ where
Q: ReadOnlyWorldQuery,
Filter: ReadOnlyWorldQuery,
{
- fn find(&self, ecs_lock: Arc<Mutex<Ecs>>) -> Option<Entity> {
+ fn find(&self, ecs_lock: Arc<Mutex<World>>) -> Option<Entity> {
let mut ecs = ecs_lock.lock();
let mut query = ecs.query_filtered::<(Entity, Q), Filter>();
let entity = query.iter(&ecs).find(|(_, q)| (self)(q)).map(|(e, _)| e);
diff --git a/azalea-client/src/events.rs b/azalea-client/src/events.rs
index 085f5368..c7ff20aa 100644
--- a/azalea-client/src/events.rs
+++ b/azalea-client/src/events.rs
@@ -3,18 +3,12 @@
use std::sync::Arc;
-use azalea_ecs::{
- app::{App, Plugin},
- component::Component,
- event::EventReader,
- query::Added,
- system::Query,
- AppTickExt,
-};
use azalea_protocol::packets::game::{
clientbound_player_combat_kill_packet::ClientboundPlayerCombatKillPacket, ClientboundGamePacket,
};
use azalea_world::entity::MinecraftEntityId;
+use bevy_app::{App, CoreSchedule, IntoSystemAppConfig, Plugin};
+use bevy_ecs::{component::Component, event::EventReader, query::Added, system::Query};
use derive_more::{Deref, DerefMut};
use tokio::sync::mpsc;
@@ -115,7 +109,7 @@ impl Plugin for EventPlugin {
.add_system(remove_player_listener)
.add_system(death_listener)
.add_system(keepalive_listener)
- .add_tick_system(tick_listener);
+ .add_system(tick_listener.in_schedule(CoreSchedule::FixedUpdate));
}
}
diff --git a/azalea-client/src/lib.rs b/azalea-client/src/lib.rs
index 8e119c0e..44a4db6b 100644
--- a/azalea-client/src/lib.rs
+++ b/azalea-client/src/lib.rs
@@ -26,7 +26,6 @@ mod player;
pub mod task_pool;
pub use account::Account;
-pub use azalea_ecs as ecs;
pub use client::{init_ecs_app, start_ecs, Client, ClientInformation, JoinError};
pub use events::Event;
pub use local_player::{GameProfileComponent, LocalPlayer};
diff --git a/azalea-client/src/local_player.rs b/azalea-client/src/local_player.rs
index d31f840f..be847e78 100644
--- a/azalea-client/src/local_player.rs
+++ b/azalea-client/src/local_player.rs
@@ -2,14 +2,13 @@ use std::{collections::HashMap, io, sync::Arc};
use azalea_auth::game_profile::GameProfile;
use azalea_core::ChunkPos;
-use azalea_ecs::component::Component;
-use azalea_ecs::entity::Entity;
-use azalea_ecs::event::EventReader;
-use azalea_ecs::{query::Added, system::Query};
use azalea_protocol::packets::game::ServerboundGamePacket;
use azalea_world::{
entity::{self, Dead},
- PartialWorld, World,
+ Instance, PartialWorld,
+};
+use bevy_ecs::{
+ component::Component, entity::Entity, event::EventReader, query::Added, system::Query,
};
use derive_more::{Deref, DerefMut};
use parking_lot::RwLock;
@@ -44,7 +43,7 @@ pub struct LocalPlayer {
pub partial_world: Arc<RwLock<PartialWorld>>,
/// The world is the combined [`PartialWorld`]s of all clients in the same
/// world. (Only relevant if you're using a shared world, i.e. a swarm)
- pub world: Arc<RwLock<World>>,
+ pub world: Arc<RwLock<Instance>>,
/// A task that reads packets from the server. The client is disconnected
/// when this task ends.
@@ -88,7 +87,7 @@ impl LocalPlayer {
pub fn new(
entity: Entity,
packet_writer: mpsc::UnboundedSender<ServerboundGamePacket>,
- world: Arc<RwLock<World>>,
+ world: Arc<RwLock<Instance>>,
read_packets_task: JoinHandle<()>,
write_packets_task: JoinHandle<()>,
) -> Self {
@@ -129,7 +128,7 @@ impl Drop for LocalPlayer {
/// Update the [`LocalPlayerInLoadedChunk`] component for all [`LocalPlayer`]s.
pub fn update_in_loaded_chunk(
- mut commands: azalea_ecs::system::Commands,
+ mut commands: bevy_ecs::system::Commands,
query: Query<(Entity, &LocalPlayer, &entity::Position)>,
) {
for (entity, local_player, position) in &query {
diff --git a/azalea-client/src/movement.rs b/azalea-client/src/movement.rs
index f379501c..f6123c70 100644
--- a/azalea-client/src/movement.rs
+++ b/azalea-client/src/movement.rs
@@ -1,7 +1,8 @@
use crate::client::Client;
-use crate::local_player::{LocalPlayer, LocalPlayerInLoadedChunk, PhysicsState};
-use azalea_ecs::entity::Entity;
-use azalea_ecs::{event::EventReader, query::With, system::Query};
+use crate::local_player::{
+ update_in_loaded_chunk, LocalPlayer, LocalPlayerInLoadedChunk, PhysicsState,
+};
+use azalea_physics::{force_jump_listener, PhysicsSet};
use azalea_protocol::packets::game::serverbound_player_command_packet::ServerboundPlayerCommandPacket;
use azalea_protocol::packets::game::{
serverbound_move_player_pos_packet::ServerboundMovePlayerPosPacket,
@@ -13,6 +14,14 @@ use azalea_world::{
entity::{self, metadata::Sprinting, Attributes, Jumping, MinecraftEntityId},
MoveEntityError,
};
+use bevy_app::{App, CoreSchedule, IntoSystemAppConfigs, Plugin};
+use bevy_ecs::{
+ entity::Entity,
+ event::EventReader,
+ query::With,
+ schedule::{IntoSystemConfig, IntoSystemConfigs},
+ system::Query,
+};
use std::backtrace::Backtrace;
use thiserror::Error;
@@ -34,6 +43,28 @@ impl From<MoveEntityError> for MovePlayerError {
}
}
+pub struct PlayerMovePlugin;
+
+impl Plugin for PlayerMovePlugin {
+ fn build(&self, app: &mut App) {
+ app.add_event::<StartWalkEvent>()
+ .add_event::<StartSprintEvent>()
+ .add_systems(
+ (sprint_listener, walk_listener)
+ .chain()
+ .before(force_jump_listener),
+ )
+ .add_systems(
+ (
+ local_player_ai_step.in_set(PhysicsSet),
+ send_position.after(update_in_loaded_chunk),
+ )
+ .chain()
+ .in_schedule(CoreSchedule::FixedUpdate),
+ );
+ }
+}
+
impl Client {
/// Set whether we're jumping. This acts as if you held space in
/// vanilla. If you want to jump once, use the `jump` function.
diff --git a/azalea-client/src/packet_handling.rs b/azalea-client/src/packet_handling.rs
index 9f8c5f1a..76e6ee41 100644
--- a/azalea-client/src/packet_handling.rs
+++ b/azalea-client/src/packet_handling.rs
@@ -1,15 +1,6 @@
use std::{collections::HashSet, io::Cursor, sync::Arc};
use azalea_core::{ChunkPos, ResourceLocation, Vec3};
-use azalea_ecs::{
- app::{App, CoreStage, Plugin},
- component::Component,
- ecs::Ecs,
- entity::Entity,
- event::{EventReader, EventWriter, Events},
- schedule::{StageLabel, SystemStage},
- system::{Commands, Query, ResMut, SystemState},
-};
use azalea_protocol::{
connect::{ReadConnection, WriteConnection},
packets::game::{
@@ -25,12 +16,21 @@ use azalea_protocol::{
use azalea_world::{
entity::{
metadata::{apply_metadata, Health, PlayerMetadataBundle},
- set_rotation, Dead, EntityBundle, EntityKind, LastSentPosition, MinecraftEntityId, Physics,
- PlayerBundle, Position, WorldName,
+ set_rotation, Dead, EntityBundle, EntityKind, EntityUpdateSet, LastSentPosition,
+ MinecraftEntityId, Physics, PlayerBundle, Position, WorldName,
},
entity::{LoadedBy, RelativeEntityUpdate},
PartialWorld, WorldContainer,
};
+use bevy_app::{App, CoreSet, Plugin};
+use bevy_ecs::{
+ component::Component,
+ entity::Entity,
+ event::{EventReader, EventWriter, Events},
+ schedule::IntoSystemConfig,
+ system::{Commands, Query, ResMut, SystemState},
+ world::World,
+};
use log::{debug, error, trace, warn};
use parking_lot::Mutex;
use tokio::sync::mpsc;
@@ -46,7 +46,7 @@ use crate::{
/// ```
/// # use azalea_client::packet_handling::PacketEvent;
/// # use azalea_protocol::packets::game::ClientboundGamePacket;
-/// # use azalea_ecs::event::EventReader;
+/// # use bevy_ecs::event::EventReader;
///
/// fn handle_packets(mut events: EventReader<PacketEvent>) {
/// for PacketEvent {
@@ -72,25 +72,22 @@ pub struct PacketEvent {
pub struct PacketHandlerPlugin;
-#[derive(StageLabel)]
-pub struct SendPacketEventsStage;
-
impl Plugin for PacketHandlerPlugin {
fn build(&self, app: &mut App) {
- app.add_stage_before(
- CoreStage::PreUpdate,
- SendPacketEventsStage,
- SystemStage::parallel(),
- )
- .add_system_to_stage(SendPacketEventsStage, send_packet_events)
- .add_system_to_stage(CoreStage::PreUpdate, process_packet_events)
- .init_resource::<Events<PacketEvent>>()
- .add_event::<AddPlayerEvent>()
- .add_event::<RemovePlayerEvent>()
- .add_event::<UpdatePlayerEvent>()
- .add_event::<ChatReceivedEvent>()
- .add_event::<DeathEvent>()
- .add_event::<KeepAliveEvent>();
+ app.add_system(send_packet_events.in_base_set(CoreSet::First))
+ .add_system(
+ process_packet_events
+ .in_base_set(CoreSet::PreUpdate)
+ // we want to index and deindex right after
+ .before(EntityUpdateSet::Deindex),
+ )
+ .init_resource::<Events<PacketEvent>>()
+ .add_event::<AddPlayerEvent>()
+ .add_event::<RemovePlayerEvent>()
+ .add_event::<UpdatePlayerEvent>()
+ .add_event::<ChatReceivedEvent>()
+ .add_event::<DeathEvent>()
+ .add_event::<KeepAliveEvent>();
}
}
@@ -168,7 +165,7 @@ pub fn send_packet_events(
}
}
-fn process_packet_events(ecs: &mut Ecs) {
+fn process_packet_events(ecs: &mut World) {
let mut events_owned = Vec::new();
let mut system_state: SystemState<EventReader<PacketEvent>> = SystemState::new(ecs);
let mut events = system_state.get_mut(ecs);
@@ -715,8 +712,7 @@ fn process_packet_events(ecs: &mut Ecs) {
if let Some(entity) = entity {
let new_position = p.position;
- commands.add(RelativeEntityUpdate {
- entity,
+ commands.entity(entity).add(RelativeEntityUpdate {
partial_world: local_player.partial_world.clone(),
update: Box::new(move |entity| {
let mut position = entity.get_mut::<Position>().unwrap();
@@ -747,8 +743,7 @@ fn process_packet_events(ecs: &mut Ecs) {
if let Some(entity) = entity {
let delta = p.delta.clone();
- commands.add(RelativeEntityUpdate {
- entity,
+ commands.entity(entity).add(RelativeEntityUpdate {
partial_world: local_player.partial_world.clone(),
update: Box::new(move |entity_mut| {
let mut position = entity_mut.get_mut::<Position>().unwrap();
@@ -776,8 +771,7 @@ fn process_packet_events(ecs: &mut Ecs) {
if let Some(entity) = entity {
let delta = p.delta.clone();
- commands.add(RelativeEntityUpdate {
- entity,
+ commands.entity(entity).add(RelativeEntityUpdate {
partial_world: local_player.partial_world.clone(),
update: Box::new(move |entity_mut| {
let mut position = entity_mut.get_mut::<Position>().unwrap();
diff --git a/azalea-client/src/player.rs b/azalea-client/src/player.rs
index 3680e2d0..c2c8a94e 100755
--- a/azalea-client/src/player.rs
+++ b/azalea-client/src/player.rs
@@ -1,11 +1,11 @@
use azalea_auth::game_profile::GameProfile;
use azalea_chat::FormattedText;
use azalea_core::GameType;
-use azalea_ecs::{
+use azalea_world::entity::EntityInfos;
+use bevy_ecs::{
event::EventReader,
system::{Commands, Res},
};
-use azalea_world::entity::EntityInfos;
use uuid::Uuid;
use crate::{packet_handling::AddPlayerEvent, GameProfileComponent};
diff --git a/azalea-client/src/task_pool.rs b/azalea-client/src/task_pool.rs
index 59f70487..8df554f0 100644
--- a/azalea-client/src/task_pool.rs
+++ b/azalea-client/src/task_pool.rs
@@ -1,11 +1,16 @@
//! Borrowed from `bevy_core`.
-use azalea_ecs::{
- app::{App, Plugin},
- schedule::IntoSystemDescriptor,
- system::Resource,
+use std::marker::PhantomData;
+
+use bevy_app::{App, CoreSet, Plugin};
+use bevy_ecs::{
+ schedule::IntoSystemConfig,
+ system::{NonSend, Resource},
+};
+use bevy_tasks::{
+ tick_global_task_pools_on_main_thread, AsyncComputeTaskPool, ComputeTaskPool, IoTaskPool,
+ TaskPoolBuilder,
};
-use bevy_tasks::{AsyncComputeTaskPool, ComputeTaskPool, IoTaskPool, TaskPoolBuilder};
/// Setup of default task pools: `AsyncComputeTaskPool`, `ComputeTaskPool`,
/// `IoTaskPool`.
@@ -22,13 +27,16 @@ impl Plugin for TaskPoolPlugin {
self.task_pool_options.create_default_pools();
#[cfg(not(target_arch = "wasm32"))]
- app.add_system_to_stage(
- azalea_ecs::app::CoreStage::Last,
- bevy_tasks::tick_global_task_pools_on_main_thread.at_end(),
- );
+ app.add_system(tick_global_task_pools.in_base_set(CoreSet::Last));
}
}
+pub struct NonSendMarker(PhantomData<*mut ()>);
+#[cfg(not(target_arch = "wasm32"))]
+fn tick_global_task_pools(_main_thread_marker: Option<NonSend<NonSendMarker>>) {
+ tick_global_task_pools_on_main_thread();
+}
+
/// Helper for configuring and creating the default task pools. For end-users
/// who want full control, set up [`TaskPoolPlugin`](TaskPoolPlugin)
#[derive(Clone, Resource)]
diff --git a/azalea-core/Cargo.toml b/azalea-core/Cargo.toml
index 0baa40ac..e31351e8 100644
--- a/azalea-core/Cargo.toml
+++ b/azalea-core/Cargo.toml
@@ -9,10 +9,10 @@ version = "0.6.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-azalea-buf = {path = "../azalea-buf", version = "^0.6.0" }
-azalea-chat = {path = "../azalea-chat", version = "^0.6.0" }
-azalea-nbt = {path = "../azalea-nbt", version = "^0.6.0" }
-bevy_ecs = {version = "0.9.1", default-features = false, optional = true}
+azalea-buf = { path = "../azalea-buf", version = "^0.6.0" }
+azalea-chat = { path = "../azalea-chat", version = "^0.6.0" }
+azalea-nbt = { path = "../azalea-nbt", version = "^0.6.0" }
+bevy_ecs = { version = "0.10.0", default-features = false, optional = true }
uuid = "^1.1.2"
[features]
diff --git a/azalea-ecs/Cargo.toml b/azalea-ecs/Cargo.toml
deleted file mode 100644
index a596fd42..00000000
--- a/azalea-ecs/Cargo.toml
+++ /dev/null
@@ -1,14 +0,0 @@
-[package]
-description = "ECS stuff used in Azalea"
-edition = "2021"
-license = "MIT"
-name = "azalea-ecs"
-version = "0.6.0"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-azalea-ecs-macros = {path = "./azalea-ecs-macros", version = "^0.6.0"}
-bevy_app = "0.9.1"
-bevy_ecs = {version = "0.9.1", default-features = false}
-tokio = {version = "1.25.0", features = ["time"]}
diff --git a/azalea-ecs/azalea-ecs-macros/Cargo.toml b/azalea-ecs/azalea-ecs-macros/Cargo.toml
deleted file mode 100755
index cd7b2c8d..00000000
--- a/azalea-ecs/azalea-ecs-macros/Cargo.toml
+++ /dev/null
@@ -1,15 +0,0 @@
-[package]
-description = "Azalea ECS Macros"
-edition = "2021"
-license = "MIT OR Apache-2.0"
-name = "azalea-ecs-macros"
-version = "0.6.0"
-
-[lib]
-proc-macro = true
-
-[dependencies]
-proc-macro2 = "1.0"
-quote = "1.0"
-syn = "1.0"
-toml = "0.7.0"
diff --git a/azalea-ecs/azalea-ecs-macros/src/component.rs b/azalea-ecs/azalea-ecs-macros/src/component.rs
deleted file mode 100644
index e076bbe1..00000000
--- a/azalea-ecs/azalea-ecs-macros/src/component.rs
+++ /dev/null
@@ -1,125 +0,0 @@
-use crate::utils::{get_lit_str, Symbol};
-use proc_macro::TokenStream;
-use proc_macro2::{Span, TokenStream as TokenStream2};
-use quote::{quote, ToTokens};
-use syn::{parse_macro_input, parse_quote, DeriveInput, Error, Ident, Path, Result};
-
-use crate::utils;
-
-pub fn derive_resource(input: TokenStream) -> TokenStream {
- let mut ast = parse_macro_input!(input as DeriveInput);
- let azalea_ecs_path: Path = crate::azalea_ecs_path();
-
- ast.generics
- .make_where_clause()
- .predicates
- .push(parse_quote! { Self: Send + Sync + 'static });
-
- let struct_name = &ast.ident;
- let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl();
-
- TokenStream::from(quote! {
- impl #impl_generics #azalea_ecs_path::system::_BevyResource for #struct_name #type_generics #where_clause {
- }
- })
-}
-
-pub fn derive_component(input: TokenStream) -> TokenStream {
- let mut ast = parse_macro_input!(input as DeriveInput);
- let azalea_ecs_path: Path = crate::azalea_ecs_path();
-
- let attrs = match parse_component_attr(&ast) {
- Ok(attrs) => attrs,
- Err(e) => return e.into_compile_error().into(),
- };
-
- let storage = storage_path(&azalea_ecs_path, attrs.storage);
-
- ast.generics
- .make_where_clause()
- .predicates
- .push(parse_quote! { Self: Send + Sync + 'static });
-
- let struct_name = &ast.ident;
- let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl();
-
- TokenStream::from(quote! {
- impl #impl_generics #azalea_ecs_path::component::_BevyComponent for #struct_name #type_generics #where_clause {
- type Storage = #storage;
- }
- })
-}
-
-pub const COMPONENT: Symbol = Symbol("component");
-pub const STORAGE: Symbol = Symbol("storage");
-
-struct Attrs {
- storage: StorageTy,
-}
-
-#[derive(Clone, Copy)]
-enum StorageTy {
- Table,
- SparseSet,
-}
-
-// values for `storage` attribute
-const TABLE: &str = "Table";
-const SPARSE_SET: &str = "SparseSet";
-
-fn parse_component_attr(ast: &DeriveInput) -> Result<Attrs> {
- let meta_items = utils::parse_attrs(ast, COMPONENT)?;
-
- let mut attrs = Attrs {
- storage: StorageTy::Table,
- };
-
- for meta in meta_items {
- use syn::{
- Meta::NameValue,
- NestedMeta::{Lit, Meta},
- };
- match meta {
- Meta(NameValue(m)) if m.path == STORAGE => {
- attrs.storage = match get_lit_str(STORAGE, &m.lit)?.value().as_str() {
- TABLE => StorageTy::Table,
- SPARSE_SET => StorageTy::SparseSet,
- s => {
- return Err(Error::new_spanned(
- m.lit,
- format!(
- "Invalid storage type `{s}`, expected '{TABLE}' or '{SPARSE_SET}'."
- ),
- ))
- }
- };
- }
- Meta(meta_item) => {
- return Err(Error::new_spanned(
- meta_item.path(),
- format!(
- "unknown component attribute `{}`",
- meta_item.path().into_token_stream()
- ),
- ));
- }
- Lit(lit) => {
- return Err(Error::new_spanned(
- lit,
- "unexpected literal in component attribute",
- ))
- }
- }
- }
-
- Ok(attrs)
-}
-
-fn storage_path(azalea_ecs_path: &Path, ty: StorageTy) -> TokenStream2 {
- let typename = match ty {
- StorageTy::Table => Ident::new("TableStorage", Span::call_site()),
- StorageTy::SparseSet => Ident::new("SparseStorage", Span::call_site()),
- };
-
- quote! { #azalea_ecs_path::component::#typename }
-}
diff --git a/azalea-ecs/azalea-ecs-macros/src/fetch.rs b/azalea-ecs/azalea-ecs-macros/src/fetch.rs
deleted file mode 100644
index 8a6b93ba..00000000
--- a/azalea-ecs/azalea-ecs-macros/src/fetch.rs
+++ /dev/null
@@ -1,466 +0,0 @@
-use proc_macro::TokenStream;
-use proc_macro2::{Ident, Span};
-use quote::{quote, ToTokens};
-use syn::{
- parse::{Parse, ParseStream},
- parse_quote,
- punctuated::Punctuated,
- Attribute, Data, DataStruct, DeriveInput, Field, Fields,
-};
-
-use crate::azalea_ecs_path;
-
-#[derive(Default)]
-struct FetchStructAttributes {
- pub is_mutable: bool,
- pub derive_args: Punctuated<syn::NestedMeta, syn::token::Comma>,
-}
-
-static MUTABLE_ATTRIBUTE_NAME: &str = "mutable";
-static DERIVE_ATTRIBUTE_NAME: &str = "derive";
-
-mod field_attr_keywords {
- syn::custom_keyword!(ignore);
-}
-
-pub static WORLD_QUERY_ATTRIBUTE_NAME: &str = "world_query";
-
-pub fn derive_world_query_impl(ast: DeriveInput) -> TokenStream {
- let visibility = ast.vis;
-
- let mut fetch_struct_attributes = FetchStructAttributes::default();
- for attr in &ast.attrs {
- if !attr
- .path
- .get_ident()
- .map_or(false, |ident| ident == WORLD_QUERY_ATTRIBUTE_NAME)
- {
- continue;
- }
-
- attr.parse_args_with(|input: ParseStream| {
- let meta = input.parse_terminated::<syn::Meta, syn::token::Comma>(syn::Meta::parse)?;
- for meta in meta {
- let ident = meta.path().get_ident().unwrap_or_else(|| {
- panic!(
- "Unrecognized attribute: `{}`",
- meta.path().to_token_stream()
- )
- });
- if ident == MUTABLE_ATTRIBUTE_NAME {
- if let syn::Meta::Path(_) = meta {
- fetch_struct_attributes.is_mutable = true;
- } else {
- panic!(
- "The `{MUTABLE_ATTRIBUTE_NAME}` attribute is expected to have no value or arguments"
- );
- }
- } else if ident == DERIVE_ATTRIBUTE_NAME {
- if let syn::Meta::List(meta_list) = meta {
- fetch_struct_attributes
- .derive_args
- .extend(meta_list.nested.iter().cloned());
- } else {
- panic!(
- "Expected a structured list within the `{DERIVE_ATTRIBUTE_NAME}` attribute"
- );
- }
- } else {
- panic!(
- "Unrecognized attribute: `{}`",
- meta.path().to_token_stream()
- );
- }
- }
- Ok(())
- })
- .unwrap_or_else(|_| panic!("Invalid `{WORLD_QUERY_ATTRIBUTE_NAME}` attribute format"));
- }
-
- let path = azalea_ecs_path();
-
- let user_generics = ast.generics.clone();
- let (user_impl_generics, user_ty_generics, user_where_clauses) = user_generics.split_for_impl();
- let user_generics_with_world = {
- let mut generics = ast.generics.clone();
- generics.params.insert(0, parse_quote!('__w));
- generics
- };
- let (user_impl_generics_with_world, user_ty_generics_with_world, user_where_clauses_with_world) =
- user_generics_with_world.split_for_impl();
-
- let struct_name = ast.ident.clone();
- let read_only_struct_name = if fetch_struct_attributes.is_mutable {
- Ident::new(&format!("{struct_name}ReadOnly"), Span::call_site())
- } else {
- struct_name.clone()
- };
-
- let item_struct_name = Ident::new(&format!("{struct_name}Item"), Span::call_site());
- let read_only_item_struct_name = if fetch_struct_attributes.is_mutable {
- Ident::new(&format!("{struct_name}ReadOnlyItem"), Span::call_site())
- } else {
- item_struct_name.clone()
- };
-
- let fetch_struct_name = Ident::new(&format!("{struct_name}Fetch"), Span::call_site());
- let read_only_fetch_struct_name = if fetch_struct_attributes.is_mutable {
- Ident::new(&format!("{struct_name}ReadOnlyFetch"), Span::call_site())
- } else {
- fetch_struct_name.clone()
- };
-
- let state_struct_name = Ident::new(&format!("{struct_name}State"), Span::call_site());
-
- let fields = match &ast.data {
- Data::Struct(DataStruct {
- fields: Fields::Named(fields),
- ..
- }) => &fields.named,
- _ => panic!("Expected a struct with named fields"),
- };
-
- let mut ignored_field_attrs = Vec::new();
- let mut ignored_field_visibilities = Vec::new();
- let mut ignored_field_idents = Vec::new();
- let mut ignored_field_types = Vec::new();
- let mut field_attrs = Vec::new();
- let mut field_visibilities = Vec::new();
- let mut field_idents = Vec::new();
- let mut field_types = Vec::new();
- let mut read_only_field_types = Vec::new();
-
- for field in fields {
- let WorldQueryFieldInfo { is_ignored, attrs } = read_world_query_field_info(field);
-
- let field_ident = field.ident.as_ref().unwrap().clone();
- if is_ignored {
- ignored_field_attrs.push(attrs);
- ignored_field_visibilities.push(field.vis.clone());
- ignored_field_idents.push(field_ident.clone());
- ignored_field_types.push(field.ty.clone());
- } else {
- field_attrs.push(attrs);
- field_visibilities.push(field.vis.clone());
- field_idents.push(field_ident.clone());
- let field_ty = field.ty.clone();
- field_types.push(quote!(#field_ty));
- read_only_field_types.push(quote!(<#field_ty as #path::query::WorldQuery>::ReadOnly));
- }
- }
-
- let derive_args = &fetch_struct_attributes.derive_args;
- // `#[derive()]` is valid syntax
- let derive_macro_call = quote! { #[derive(#derive_args)] };
-
- let impl_fetch = |is_readonly: bool| {
- let struct_name = if is_readonly {
- &read_only_struct_name
- } else {
- &struct_name
- };
- let item_struct_name = if is_readonly {
- &read_only_item_struct_name
- } else {
- &item_struct_name
- };
- let fetch_struct_name = if is_readonly {
- &read_only_fetch_struct_name
- } else {
- &fetch_struct_name
- };
-
- let field_types = if is_readonly {
- &read_only_field_types
- } else {
- &field_types
- };
-
- quote! {
- #derive_macro_call
- #[doc = "Automatically generated [`WorldQuery`] item type for [`"]
- #[doc = stringify!(#struct_name)]
- #[doc = "`], returned when iterating over query results."]
- #[automatically_derived]
- #visibility struct #item_struct_name #user_impl_generics_with_world #user_where_clauses_with_world {
- #(#(#field_attrs)* #field_visibilities #field_idents: <#field_types as #path::query::WorldQuery>::Item<'__w>,)*
- #(#(#ignored_field_attrs)* #ignored_field_visibilities #ignored_field_idents: #ignored_field_types,)*
- }
-
- #[doc(hidden)]
- #[doc = "Automatically generated internal [`WorldQuery`] fetch type for [`"]
- #[doc = stringify!(#struct_name)]
- #[doc = "`], used to define the world data accessed by this query."]
- #[automatically_derived]
- #visibility struct #fetch_struct_name #user_impl_generics_with_world #user_where_clauses_with_world {
- #(#field_idents: <#field_types as #path::query::WorldQuery>::Fetch<'__w>,)*
- #(#ignored_field_idents: #ignored_field_types,)*
- }
-
- // SAFETY: `update_component_access` and `update_archetype_component_access` are called on every field
- unsafe impl #user_impl_generics #path::query::WorldQuery
- for #struct_name #user_ty_generics #user_where_clauses {
-
- type Item<'__w> = #item_struct_name #user_ty_generics_with_world;
- type Fetch<'__w> = #fetch_struct_name #user_ty_generics_with_world;
- type ReadOnly = #read_only_struct_name #user_ty_generics;
- type State = #state_struct_name #user_ty_generics;
-
- fn shrink<'__wlong: '__wshort, '__wshort>(
- item: <#struct_name #user_ty_generics as #path::query::WorldQuery>::Item<'__wlong>
- ) -> <#struct_name #user_ty_generics as #path::query::WorldQuery>::Item<'__wshort> {
- #item_struct_name {
- #(
- #field_idents: <#field_types>::shrink(item.#field_idents),
- )*
- #(
- #ignored_field_idents: item.#ignored_field_idents,
- )*
- }
- }
-
- unsafe fn init_fetch<'__w>(
- _world: &'__w #path::world::World,
- state: &Self::State,
- _last_change_tick: u32,
- _change_tick: u32
- ) -> <Self as #path::query::WorldQuery>::Fetch<'__w> {
- #fetch_struct_name {
- #(#field_idents:
- <#field_types>::init_fetch(
- _world,
- &state.#field_idents,
- _last_change_tick,
- _change_tick
- ),
- )*
- #(#ignored_field_idents: Default::default(),)*
- }
- }
-
- unsafe fn clone_fetch<'__w>(
- _fetch: &<Self as #path::query::WorldQuery>::Fetch<'__w>
- ) -> <Self as #path::query::WorldQuery>::Fetch<'__w> {
- #fetch_struct_name {
- #(
- #field_idents: <#field_types>::clone_fetch(& _fetch. #field_idents),
- )*
- #(
- #ignored_field_idents: Default::default(),
- )*
- }
- }
-
- const IS_DENSE: bool = true #(&& <#field_types>::IS_DENSE)*;
-
- const IS_ARCHETYPAL: bool = true #(&& <#field_types>::IS_ARCHETYPAL)*;
-
- /// SAFETY: we call `set_archetype` for each member that implements `Fetch`
- #[inline]
- unsafe fn set_archetype<'__w>(
- _fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
- _state: &Self::State,
- _archetype: &'__w #path::archetype::Archetype,
- _table: &'__w #path::storage::Table
- ) {
- #(<#field_types>::set_archetype(&mut _fetch.#field_idents, &_state.#field_idents, _archetype, _table);)*
- }
-
- /// SAFETY: we call `set_table` for each member that implements `Fetch`
- #[inline]
- unsafe fn set_table<'__w>(
- _fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
- _state: &Self::State,
- _table: &'__w #path::storage::Table
- ) {
- #(<#field_types>::set_table(&mut _fetch.#field_idents, &_state.#field_idents, _table);)*
- }
-
- /// SAFETY: we call `fetch` for each member that implements `Fetch`.
- #[inline(always)]
- unsafe fn fetch<'__w>(
- _fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
- _entity: Entity,
- _table_row: usize
- ) -> <Self as #path::query::WorldQuery>::Item<'__w> {
- Self::Item {
- #(#field_idents: <#field_types>::fetch(&mut _fetch.#field_idents, _entity, _table_row),)*
- #(#ignored_field_idents: Default::default(),)*
- }
- }
-
- #[allow(unused_variables)]
- #[inline(always)]
- unsafe fn filter_fetch<'__w>(
- _fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
- _entity: Entity,
- _table_row: usize
- ) -> bool {
- true #(&& <#field_types>::filter_fetch(&mut _fetch.#field_idents, _entity, _table_row))*
- }
-
- fn update_component_access(state: &Self::State, _access: &mut #path::query::FilteredAccess<#path::component::ComponentId>) {
- #( <#field_types>::update_component_access(&state.#field_idents, _access); )*
- }
-
- fn update_archetype_component_access(
- state: &Self::State,
- _archetype: &#path::archetype::Archetype,
- _access: &mut #path::query::Access<#path::archetype::ArchetypeComponentId>
- ) {
- #(
- <#field_types>::update_archetype_component_access(&state.#field_idents, _archetype, _access);
- )*
- }
-
- fn init_state(world: &mut #path::world::World) -> #state_struct_name #user_ty_generics {
- #state_struct_name {
- #(#field_idents: <#field_types>::init_state(world),)*
- #(#ignored_field_idents: Default::default(),)*
- }
- }
-
- fn matches_component_set(state: &Self::State, _set_contains_id: &impl Fn(#path::component::ComponentId) -> bool) -> bool {
- true #(&& <#field_types>::matches_component_set(&state.#field_idents, _set_contains_id))*
- }
- }
- }
- };
-
- let mutable_impl = impl_fetch(false);
- let readonly_impl = if fetch_struct_attributes.is_mutable {
- let world_query_impl = impl_fetch(true);
- quote! {
- #[doc(hidden)]
- #[doc = "Automatically generated internal [`WorldQuery`] type for [`"]
- #[doc = stringify!(#struct_name)]
- #[doc = "`], used for read-only access."]
- #[automatically_derived]
- #visibility struct #read_only_struct_name #user_impl_generics #user_where_clauses {
- #( #field_idents: #read_only_field_types, )*
- #(#(#ignored_field_attrs)* #ignored_field_visibilities #ignored_field_idents: #ignored_field_types,)*
- }
-
- #world_query_impl
- }
- } else {
- quote! {}
- };
-
- let read_only_asserts = if fetch_struct_attributes.is_mutable {
- quote! {
- // Double-check that the data fetched by `<_ as WorldQuery>::ReadOnly` is read-only.
- // This is technically unnecessary as `<_ as WorldQuery>::ReadOnly: ReadOnlyWorldQuery`
- // but to protect against future mistakes we assert the assoc type implements `ReadOnlyWorldQuery` anyway
- #( assert_readonly::<#read_only_field_types>(); )*
- }
- } else {
- quote! {
- // Statically checks that the safety guarantee of `ReadOnlyWorldQuery` for `$fetch_struct_name` actually holds true.
- // We need this to make sure that we don't compile `ReadOnlyWorldQuery` if our struct contains nested `WorldQuery`
- // members that don't implement it. I.e.:
- // ```
- // #[derive(WorldQuery)]
- // pub struct Foo { a: &'static mut MyComponent }
- // ```
- #( assert_readonly::<#field_types>(); )*
- }
- };
-
- TokenStream::from(quote! {
- #mutable_impl
-
- #readonly_impl
-
- #[doc(hidden)]
- #[doc = "Automatically generated internal [`WorldQuery`] state type for [`"]
- #[doc = stringify!(#struct_name)]
- #[doc = "`], used for caching."]
- #[automatically_derived]
- #visibility struct #state_struct_name #user_impl_generics #user_where_clauses {
- #(#field_idents: <#field_types as #path::query::WorldQuery>::State,)*
- #(#ignored_field_idents: #ignored_field_types,)*
- }
-
- /// SAFETY: we assert fields are readonly below
- unsafe impl #user_impl_generics #path::query::ReadOnlyWorldQuery
- for #read_only_struct_name #user_ty_generics #user_where_clauses {}
-
- #[allow(dead_code)]
- const _: () = {
- fn assert_readonly<T>()
- where
- T: #path::query::ReadOnlyWorldQuery,
- {
- }
-
- // We generate a readonly assertion for every struct member.
- fn assert_all #user_impl_generics_with_world () #user_where_clauses_with_world {
- #read_only_asserts
- }
- };
-
- // The original struct will most likely be left unused. As we don't want our users having
- // to specify `#[allow(dead_code)]` for their custom queries, we are using this cursed
- // workaround.
- #[allow(dead_code)]
- const _: () = {
- fn dead_code_workaround #user_impl_generics (
- q: #struct_name #user_ty_generics,
- q2: #read_only_struct_name #user_ty_generics
- ) #user_where_clauses {
- #(q.#field_idents;)*
- #(q.#ignored_field_idents;)*
- #(q2.#field_idents;)*
- #(q2.#ignored_field_idents;)*
-
- }
- };
- })
-}
-
-struct WorldQueryFieldInfo {
- /// Has `#[fetch(ignore)]` or `#[filter_fetch(ignore)]` attribute.
- is_ignored: bool,
- /// All field attributes except for `world_query` ones.
- attrs: Vec<Attribute>,
-}
-
-fn read_world_query_field_info(field: &Field) -> WorldQueryFieldInfo {
- let is_ignored = field
- .attrs
- .iter()
- .find(|attr| {
- attr.path
- .get_ident()
- .map_or(false, |ident| ident == WORLD_QUERY_ATTRIBUTE_NAME)
- })
- .map_or(false, |attr| {
- let mut is_ignored = false;
- attr.parse_args_with(|input: ParseStream| {
- if input
- .parse::<Option<field_attr_keywords::ignore>>()?
- .is_some()
- {
- is_ignored = true;
- }
- Ok(())
- })
- .unwrap_or_else(|_| panic!("Invalid `{WORLD_QUERY_ATTRIBUTE_NAME}` attribute format"));
-
- is_ignored
- });
-
- let attrs = field
- .attrs
- .iter()
- .filter(|attr| {
- attr.path
- .get_ident()
- .map_or(true, |ident| ident != WORLD_QUERY_ATTRIBUTE_NAME)
- })
- .cloned()
- .collect();
-
- WorldQueryFieldInfo { is_ignored, attrs }
-}
diff --git a/azalea-ecs/azalea-ecs-macros/src/lib.rs b/azalea-ecs/azalea-ecs-macros/src/lib.rs
deleted file mode 100755
index 9d4e9b2d..00000000
--- a/azalea-ecs/azalea-ecs-macros/src/lib.rs
+++ /dev/null
@@ -1,525 +0,0 @@
-//! A fork of bevy_ecs_macros that uses azalea_ecs instead of bevy_ecs.
-
-extern crate proc_macro;
-
-mod component;
-mod fetch;
-pub(crate) mod utils;
-
-use crate::fetch::derive_world_query_impl;
-use proc_macro::TokenStream;
-use proc_macro2::Span;
-use quote::{format_ident, quote};
-use syn::{
- parse::{Parse, ParseStream},
- parse_macro_input,
- punctuated::Punctuated,
- spanned::Spanned,
- token::Comma,
- DeriveInput, Field, GenericParam, Ident, Index, LitInt, Meta, MetaList, NestedMeta, Result,
- Token, TypeParam,
-};
-use utils::{derive_label, get_named_struct_fields, BevyManifest};
-
-struct AllTuples {
- macro_ident: Ident,
- start: usize,
- end: usize,
- idents: Vec<Ident>,
-}
-
-impl Parse for AllTuples {
- fn parse(input: ParseStream) -> Result<Self> {
- let macro_ident = input.parse::<Ident>()?;
- input.parse::<Comma>()?;
- let start = input.parse::<LitInt>()?.base10_parse()?;
- input.parse::<Comma>()?;
- let end = input.parse::<LitInt>()?.base10_parse()?;
- input.parse::<Comma>()?;
- let mut idents = vec![input.parse::<Ident>()?];
- while input.parse::<Comma>().is_ok() {
- idents.push(input.parse::<Ident>()?);
- }
-
- Ok(AllTuples {
- macro_ident,
- start,
- end,
- idents,
- })
- }
-}
-
-#[proc_macro]
-pub fn all_tuples(input: TokenStream) -> TokenStream {
- let input = parse_macro_input!(input as AllTuples);
- let len = input.end - input.start;
- let mut ident_tuples = Vec::with_capacity(len);
- for i in input.start..=input.end {
- let idents = input
- .idents
- .iter()
- .map(|ident| format_ident!("{}{}", ident, i));
- if input.idents.len() < 2 {
- ident_tuples.push(quote! {
- #(#idents)*
- });
- } else {
- ident_tuples.push(quote! {
- (#(#idents),*)
- });
- }
- }
-
- let macro_ident = &input.macro_ident;
- let invocations = (input.start..=input.end).map(|i| {
- let ident_tuples = &ident_tuples[..i];
- quote! {
- #macro_ident!(#(#ident_tuples),*);
- }
- });
- TokenStream::from(quote! {
- #(
- #invocations
- )*
- })
-}
-
-enum BundleFieldKind {
- Component,
- Ignore,
-}
-
-const BUNDLE_ATTRIBUTE_NAME: &str = "bundle";
-const BUNDLE_ATTRIBUTE_IGNORE_NAME: &str = "ignore";
-
-#[proc_macro_derive(Bundle, attributes(bundle))]
-pub fn derive_bundle(input: TokenStream) -> TokenStream {
- let ast = parse_macro_input!(input as DeriveInput);
- let ecs_path = azalea_ecs_path();
-
- let named_fields = match get_named_struct_fields(&ast.data) {
- Ok(fields) => &fields.named,
- Err(e) => return e.into_compile_error().into(),
- };
-
- let mut field_kind = Vec::with_capacity(named_fields.len());
-
- 'field_loop: for field in named_fields.iter() {
- for attr in &field.attrs {
- if attr.path.is_ident(BUNDLE_ATTRIBUTE_NAME) {
- if let Ok(Meta::List(MetaList { nested, .. })) = attr.parse_meta() {
- if let Some(&NestedMeta::Meta(Meta::Path(ref path))) = nested.first() {
- if path.is_ident(BUNDLE_ATTRIBUTE_IGNORE_NAME) {
- field_kind.push(BundleFieldKind::Ignore);
- continue 'field_loop;
- }
-
- return syn::Error::new(
- path.span(),
- format!(
- "Invalid bundle attribute. Use `{BUNDLE_ATTRIBUTE_IGNORE_NAME}`"
- ),
- )
- .into_compile_error()
- .into();
- }
-
- return syn::Error::new(attr.span(), format!("Invalid bundle attribute. Use `#[{BUNDLE_ATTRIBUTE_NAME}({BUNDLE_ATTRIBUTE_IGNORE_NAME})]`")).into_compile_error().into();
- }
- }
- }
-
- field_kind.push(BundleFieldKind::Component);
- }
-
- let field = named_fields
- .iter()
- .map(|field| field.ident.as_ref().unwrap())
- .collect::<Vec<_>>();
- let field_type = named_fields
- .iter()
- .map(|field| &field.ty)
- .collect::<Vec<_>>();
-
- let mut field_component_ids = Vec::new();
- let mut field_get_components = Vec::new();
- let mut field_from_components = Vec::new();
- for ((field_type, field_kind), field) in
- field_type.iter().zip(field_kind.iter()).zip(field.iter())
- {
- match field_kind {
- BundleFieldKind::Component => {
- field_component_ids.push(quote! {
- <#field_type as #ecs_path::bundle::_BevyBundle>::component_ids(components, storages, &mut *ids);
- });
- field_get_components.push(quote! {
- self.#field.get_components(&mut *func);
- });
- field_from_components.push(quote! {
- #field: <#field_type as #ecs_path::bundle::_BevyBundle>::from_components(ctx, &mut *func),
- });
- }
-
- BundleFieldKind::Ignore => {
- field_from_components.push(quote! {
- #field: ::std::default::Default::default(),
- });
- }
- }
- }
- let generics = ast.generics;
- let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
- let struct_name = &ast.ident;
-
- TokenStream::from(quote! {
- /// SAFETY: ComponentId is returned in field-definition-order. [from_components] and [get_components] use field-definition-order
- unsafe impl #impl_generics #ecs_path::bundle::_BevyBundle for #struct_name #ty_generics #where_clause {
- fn component_ids(
- components: &mut #ecs_path::component::Components,
- storages: &mut #ecs_path::storage::Storages,
- ids: &mut impl FnMut(#ecs_path::component::ComponentId)
- ){
- #(#field_component_ids)*
- }
-
- #[allow(unused_variables, non_snake_case)]
- unsafe fn from_components<__T, __F>(ctx: &mut __T, func: &mut __F) -> Self
- where
- __F: FnMut(&mut __T) -> #ecs_path::ptr::OwningPtr<'_>
- {
- Self {
- #(#field_from_components)*
- }
- }
-
- #[allow(unused_variables)]
- fn get_components(self, func: &mut impl FnMut(#ecs_path::ptr::OwningPtr<'_>)) {
- #(#field_get_components)*
- }
- }
- })
-}
-
-fn get_idents(fmt_string: fn(usize) -> String, count: usize) -> Vec<Ident> {
- (0..count)
- .map(|i| Ident::new(&fmt_string(i), Span::call_site()))
- .collect::<Vec<Ident>>()
-}
-
-#[proc_macro]
-pub fn impl_param_set(_input: TokenStream) -> TokenStream {
- let mut tokens = TokenStream::new();
- let max_params = 8;
- let params = get_idents(|i| format!("P{i}"), max_params);
- let params_fetch = get_idents(|i| format!("PF{i}"), max_params);
- let metas = get_idents(|i| format!("m{i}"), max_params);
- let mut param_fn_muts = Vec::new();
- for (i, param) in params.iter().enumerate() {
- let fn_name = Ident::new(&format!("p{i}"), Span::call_site());
- let index = Index::from(i);
- param_fn_muts.push(quote! {
- pub fn #fn_name<'a>(&'a mut self) -> <#param::Fetch as SystemParamFetch<'a, 'a>>::Item {
- // SAFETY: systems run without conflicts with other systems.
- // Conflicting params in ParamSet are not accessible at the same time
- // ParamSets are guaranteed to not conflict with other SystemParams
- unsafe {
- <#param::Fetch as SystemParamFetch<'a, 'a>>::get_param(&mut self.param_states.#index, &self.system_meta, self.world, self.change_tick)
- }
- }
- });
- }
-
- for param_count in 1..=max_params {
- let param = &params[0..param_count];
- let param_fetch = &params_fetch[0..param_count];
- let meta = &metas[0..param_count];
- let param_fn_mut = &param_fn_muts[0..param_count];
- tokens.extend(TokenStream::from(quote! {
- impl<'w, 's, #(#param: SystemParam,)*> SystemParam for ParamSet<'w, 's, (#(#param,)*)>
- {
- type Fetch = ParamSetState<(#(#param::Fetch,)*)>;
- }
-
- // SAFETY: All parameters are constrained to ReadOnlyFetch, so World is only read
-
- unsafe impl<#(#param_fetch: for<'w1, 's1> SystemParamFetch<'w1, 's1>,)*> ReadOnlySystemParamFetch for ParamSetState<(#(#param_fetch,)*)>
- where #(#param_fetch: ReadOnlySystemParamFetch,)*
- { }
-
- // SAFETY: Relevant parameter ComponentId and ArchetypeComponentId access is applied to SystemMeta. If any ParamState conflicts
- // with any prior access, a panic will occur.
-
- unsafe impl<#(#param_fetch: for<'w1, 's1> SystemParamFetch<'w1, 's1>,)*> SystemParamState for ParamSetState<(#(#param_fetch,)*)>
- {
- fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self {
- #(
- // Pretend to add each param to the system alone, see if it conflicts
- let mut #meta = system_meta.clone();
- #meta.component_access_set.clear();
- #meta.archetype_component_access.clear();
- #param_fetch::init(world, &mut #meta);
- let #param = #param_fetch::init(world, &mut system_meta.clone());
- )*
- #(
- system_meta
- .component_access_set
- .extend(#meta.component_access_set);
- system_meta
- .archetype_component_access
- .extend(&#meta.archetype_component_access);
- )*
- ParamSetState((#(#param,)*))
- }
-
- fn new_archetype(&mut self, archetype: &Archetype, system_meta: &mut SystemMeta) {
- let (#(#param,)*) = &mut self.0;
- #(
- #param.new_archetype(archetype, system_meta);
- )*
- }
-
- fn apply(&mut self, world: &mut World) {
- self.0.apply(world)
- }
- }
-
-
-
- impl<'w, 's, #(#param_fetch: for<'w1, 's1> SystemParamFetch<'w1, 's1>,)*> SystemParamFetch<'w, 's> for ParamSetState<(#(#param_fetch,)*)>
- {
- type Item = ParamSet<'w, 's, (#(<#param_fetch as SystemParamFetch<'w, 's>>::Item,)*)>;
-
- #[inline]
- unsafe fn get_param(
- state: &'s mut Self,
- system_meta: &SystemMeta,
- world: &'w World,
- change_tick: u32,
- ) -> Self::Item {
- ParamSet {
- param_states: &mut state.0,
- system_meta: system_meta.clone(),
- world,
- change_tick,
- }
- }
- }
-
- impl<'w, 's, #(#param: SystemParam,)*> ParamSet<'w, 's, (#(#param,)*)>
- {
-
- #(#param_fn_mut)*
- }
- }));
- }
-
- tokens
-}
-
-#[derive(Default)]
-struct SystemParamFieldAttributes {
- pub ignore: bool,
-}
-
-static SYSTEM_PARAM_ATTRIBUTE_NAME: &str = "system_param";
-
-/// Implement `SystemParam` to use a struct as a parameter in a system
-#[proc_macro_derive(SystemParam, attributes(system_param))]
-pub fn derive_system_param(input: TokenStream) -> TokenStream {
- let ast = parse_macro_input!(input as DeriveInput);
- let fields = match get_named_struct_fields(&ast.data) {
- Ok(fields) => &fields.named,
- Err(e) => return e.into_compile_error().into(),
- };
- let path = azalea_ecs_path();
-
- let field_attributes = fields
- .iter()
- .map(|field| {
- (
- field,
- field
- .attrs
- .iter()
- .find(|a| *a.path.get_ident().as_ref().unwrap() == SYSTEM_PARAM_ATTRIBUTE_NAME)
- .map_or_else(SystemParamFieldAttributes::default, |a| {
- syn::custom_keyword!(ignore);
- let mut attributes = SystemParamFieldAttributes::default();
- a.parse_args_with(|input: ParseStream| {
- if input.parse::<Option<ignore>>()?.is_some() {
- attributes.ignore = true;
- }
- Ok(())
- })
- .expect("Invalid 'system_param' attribute format.");
-
- attributes
- }),
- )
- })
- .collect::<Vec<(&Field, SystemParamFieldAttributes)>>();
- let mut fields = Vec::new();
- let mut field_indices = Vec::new();
- let mut field_types = Vec::new();
- let mut ignored_fields = Vec::new();
- let mut ignored_field_types = Vec::new();
- for (i, (field, attrs)) in field_attributes.iter().enumerate() {
- if attrs.ignore {
- ignored_fields.push(field.ident.as_ref().unwrap());
- ignored_field_types.push(&field.ty);
- } else {
- fields.push(field.ident.as_ref().unwrap());
- field_types.push(&field.ty);
- field_indices.push(Index::from(i));
- }
- }
-
- let generics = ast.generics;
- let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
-
- let lifetimeless_generics: Vec<_> = generics
- .params
- .iter()
- .filter(|g| matches!(g, GenericParam::Type(_)))
- .collect();
-
- let mut punctuated_generics = Punctuated::<_, Token![,]>::new();
- punctuated_generics.extend(lifetimeless_generics.iter().map(|g| match g {
- GenericParam::Type(g) => GenericParam::Type(TypeParam {
- default: None,
- ..g.clone()
- }),
- _ => unreachable!(),
- }));
-
- let mut punctuated_generic_idents = Punctuated::<_, Token![,]>::new();
- punctuated_generic_idents.extend(lifetimeless_generics.iter().map(|g| match g {
- GenericParam::Type(g) => &g.ident,
- _ => unreachable!(),
- }));
-
- let struct_name = &ast.ident;
- let fetch_struct_visibility = &ast.vis;
-
- TokenStream::from(quote! {
- // We define the FetchState struct in an anonymous scope to avoid polluting the user namespace.
- // The struct can still be accessed via SystemParam::Fetch, e.g. EventReaderState can be accessed via
- // <EventReader<'static, 'static, T> as SystemParam>::Fetch
- const _: () = {
- impl #impl_generics #path::system::SystemParam for #struct_name #ty_generics #where_clause {
- type Fetch = FetchState <(#(<#field_types as #path::system::SystemParam>::Fetch,)*), #punctuated_generic_idents>;
- }
-
- #[doc(hidden)]
- #fetch_struct_visibility struct FetchState <TSystemParamState, #punctuated_generic_idents> {
- state: TSystemParamState,
- marker: std::marker::PhantomData<fn()->(#punctuated_generic_idents)>
- }
-
- unsafe impl<TSystemParamState: #path::system::SystemParamState, #punctuated_generics> #path::system::SystemParamState for FetchState <TSystemParamState, #punctuated_generic_idents> #where_clause {
- fn init(world: &mut #path::world::World, system_meta: &mut #path::system::SystemMeta) -> Self {
- Self {
- state: TSystemParamState::init(world, system_meta),
- marker: std::marker::PhantomData,
- }
- }
-
- fn new_archetype(&mut self, archetype: &#path::archetype::Archetype, system_meta: &mut #path::system::SystemMeta) {
- self.state.new_archetype(archetype, system_meta)
- }
-
- fn apply(&mut self, world: &mut #path::world::World) {
- self.state.apply(world)
- }
- }
-
- impl #impl_generics #path::system::SystemParamFetch<'w, 's> for FetchState <(#(<#field_types as #path::system::SystemParam>::Fetch,)*), #punctuated_generic_idents> #where_clause {
- type Item = #struct_name #ty_generics;
- unsafe fn get_param(
- state: &'s mut Self,
- system_meta: &#path::system::SystemMeta,
- world: &'w #path::world::World,
- change_tick: u32,
- ) -> Self::Item {
- #struct_name {
- #(#fields: <<#field_types as #path::system::SystemParam>::Fetch as #path::system::SystemParamFetch>::get_param(&mut state.state.#field_indices, system_meta, world, change_tick),)*
- #(#ignored_fields: <#ignored_field_types>::default(),)*
- }
- }
- }
-
- // Safety: The `ParamState` is `ReadOnlySystemParamFetch`, so this can only read from the `World`
- unsafe impl<TSystemParamState: #path::system::SystemParamState + #path::system::ReadOnlySystemParamFetch, #punctuated_generics> #path::system::ReadOnlySystemParamFetch for FetchState <TSystemParamState, #punctuated_generic_idents> #where_clause {}
- };
- })
-}
-
-/// Implement `WorldQuery` to use a struct as a parameter in a query
-#[proc_macro_derive(WorldQuery, attributes(world_query))]
-pub fn derive_world_query(input: TokenStream) -> TokenStream {
- let ast = parse_macro_input!(input as DeriveInput);
- derive_world_query_impl(ast)
-}
-
-/// Generates an impl of the `SystemLabel` trait.
-///
-/// This works only for unit structs, or enums with only unit variants.
-/// You may force a struct or variant to behave as if it were fieldless with
-/// `#[system_label(ignore_fields)]`.
-#[proc_macro_derive(SystemLabel, attributes(system_label))]
-pub fn derive_system_label(input: TokenStream) -> TokenStream {
- let input = parse_macro_input!(input as DeriveInput);
- let mut trait_path = azalea_ecs_path();
- trait_path.segments.push(format_ident!("schedule").into());
- trait_path
- .segments
- .push(format_ident!("SystemLabel").into());
- derive_label(input, &trait_path, "system_label")
-}
-
-/// Generates an impl of the `StageLabel` trait.
-///
-/// This works only for unit structs, or enums with only unit variants.
-/// You may force a struct or variant to behave as if it were fieldless with
-/// `#[stage_label(ignore_fields)]`.
-#[proc_macro_derive(StageLabel, attributes(stage_label))]
-pub fn derive_stage_label(input: TokenStream) -> TokenStream {
- let input = parse_macro_input!(input as DeriveInput);
- let mut trait_path = azalea_ecs_path();
- trait_path.segments.push(format_ident!("schedule").into());
- trait_path
- .segments
- .push(format_ident!("_BevyStageLabel").into());
- derive_label(input, &trait_path, "stage_label")
-}
-
-/// Generates an impl of the `RunCriteriaLabel` trait.
-///
-/// This works only for unit structs, or enums with only unit variants.
-/// You may force a struct or variant to behave as if it were fieldless with
-/// `#[run_criteria_label(ignore_fields)]`.
-#[proc_macro_derive(RunCriteriaLabel, attributes(run_criteria_label))]
-pub fn derive_run_criteria_label(input: TokenStream) -> TokenStream {
- let input = parse_macro_input!(input as DeriveInput);
- let mut trait_path = azalea_ecs_path();
- trait_path.segments.push(format_ident!("schedule").into());
- trait_path
- .segments
- .push(format_ident!("RunCriteriaLabel").into());
- derive_label(input, &trait_path, "run_criteria_label")
-}
-
-pub(crate) fn azalea_ecs_path() -> syn::Path {
- BevyManifest::default().get_path("azalea_ecs")
-}
-
-#[proc_macro_derive(Resource)]
-pub fn derive_resource(input: TokenStream) -> TokenStream {
- component::derive_resource(input)
-}
-
-#[proc_macro_derive(Component, attributes(component))]
-pub fn derive_component(input: TokenStream) -> TokenStream {
- component::derive_component(input)
-}
diff --git a/azalea-ecs/azalea-ecs-macros/src/utils/attrs.rs b/azalea-ecs/azalea-ecs-macros/src/utils/attrs.rs
deleted file mode 100644
index 05f0712a..00000000
--- a/azalea-ecs/azalea-ecs-macros/src/utils/attrs.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-#![allow(dead_code)]
-
-use syn::DeriveInput;
-
-use super::symbol::Symbol;
-
-pub fn parse_attrs(ast: &DeriveInput, attr_name: Symbol) -> syn::Result<Vec<syn::NestedMeta>> {
- let mut list = Vec::new();
- for attr in ast.attrs.iter().filter(|a| a.path == attr_name) {
- match attr.parse_meta()? {
- syn::Meta::List(meta) => list.extend(meta.nested.into_iter()),
- other => {
- return Err(syn::Error::new_spanned(
- other,
- format!("expected #[{attr_name}(...)]"),
- ))
- }
- }
- }
- Ok(list)
-}
-
-pub fn get_lit_str(attr_name: Symbol, lit: &syn::Lit) -> syn::Result<&syn::LitStr> {
- if let syn::Lit::Str(lit) = lit {
- Ok(lit)
- } else {
- Err(syn::Error::new_spanned(
- lit,
- format!("expected {attr_name} attribute to be a string: `{attr_name} = \"...\"`"),
- ))
- }
-}
-
-pub fn get_lit_bool(attr_name: Symbol, lit: &syn::Lit) -> syn::Result<bool> {
- if let syn::Lit::Bool(lit) = lit {
- Ok(lit.value())
- } else {
- Err(syn::Error::new_spanned(
- lit,
- format!(
- "expected {attr_name} attribute to be a bool value, `true` or `false`: `{attr_name} = ...`"
- ),
- ))
- }
-}
diff --git a/azalea-ecs/azalea-ecs-macros/src/utils/mod.rs b/azalea-ecs/azalea-ecs-macros/src/utils/mod.rs
deleted file mode 100644
index c79e3efe..00000000
--- a/azalea-ecs/azalea-ecs-macros/src/utils/mod.rs
+++ /dev/null
@@ -1,227 +0,0 @@
-#![allow(dead_code)]
-
-extern crate proc_macro;
-
-mod attrs;
-mod shape;
-mod symbol;
-
-pub use attrs::*;
-pub use shape::*;
-pub use symbol::*;
-
-use proc_macro::TokenStream;
-use quote::{quote, quote_spanned};
-use std::{env, path::PathBuf};
-use syn::spanned::Spanned;
-use toml::{map::Map, Value};
-
-pub struct BevyManifest {
- manifest: Map<String, Value>,
-}
-
-impl Default for BevyManifest {
- fn default() -> Self {
- Self {
- manifest: env::var_os("CARGO_MANIFEST_DIR")
- .map(PathBuf::from)
- .map(|mut path| {
- path.push("Cargo.toml");
- let manifest = std::fs::read_to_string(path).unwrap();
- toml::from_str(&manifest).unwrap()
- })
- .unwrap(),
- }
- }
-}
-
-impl BevyManifest {
- pub fn maybe_get_path(&self, name: &str) -> Option<syn::Path> {
- const AZALEA: &str = "azalea";
- const AZALEA_ECS: &str = "azalea_ecs";
- const BEVY_ECS: &str = "bevy_ecs";
- const BEVY: &str = "bevy";
-
- fn dep_package(dep: &Value) -> Option<&str> {
- if dep.as_str().is_some() {
- None
- } else {
- dep.as_table()
- .unwrap()
- .get("package")
- .map(|name| name.as_str().unwrap())
- }
- }
-
- let find_in_deps = |deps: &Map<String, Value>| -> Option<syn::Path> {
- let package = if let Some(dep) = deps.get(name) {
- return Some(Self::parse_str(dep_package(dep).unwrap_or(name)));
- } else if let Some(dep) = deps.get(AZALEA) {
- dep_package(dep).unwrap_or(AZALEA)
- } else if let Some(dep) = deps.get(AZALEA_ECS) {
- dep_package(dep).unwrap_or(AZALEA_ECS)
- } else if let Some(dep) = deps.get(BEVY_ECS) {
- dep_package(dep).unwrap_or(BEVY_ECS)
- } else if let Some(dep) = deps.get(BEVY) {
- dep_package(dep).unwrap_or(BEVY)
- } else {
- return None;
- };
-
- let mut path = Self::parse_str::<syn::Path>(package);
- if let Some(module) = name.strip_prefix("azalea_") {
- path.segments.push(Self::parse_str(module));
- }
- Some(path)
- };
-
- let deps = self
- .manifest
- .get("dependencies")
- .map(|deps| deps.as_table().unwrap());
- let deps_dev = self
- .manifest
- .get("dev-dependencies")
- .map(|deps| deps.as_table().unwrap());
-
- deps.and_then(find_in_deps)
- .or_else(|| deps_dev.and_then(find_in_deps))
- }
-
- /// Returns the path for the crate with the given name.
- ///
- /// This is a convenience method for constructing a [manifest] and
- /// calling the [`get_path`] method.
- ///
- /// This method should only be used where you just need the path and can't
- /// cache the [manifest]. If caching is possible, it's recommended to create
- /// the [manifest] yourself and use the [`get_path`] method.
- ///
- /// [`get_path`]: Self::get_path
- /// [manifest]: Self
- pub fn get_path_direct(name: &str) -> syn::Path {
- Self::default().get_path(name)
- }
-
- pub fn get_path(&self, name: &str) -> syn::Path {
- self.maybe_get_path(name)
- .unwrap_or_else(|| Self::parse_str(name))
- }
-
- pub fn parse_str<T: syn::parse::Parse>(path: &str) -> T {
- syn::parse(path.parse::<TokenStream>().unwrap()).unwrap()
- }
-}
-
-/// Derive a label trait
-///
-/// # Args
-///
-/// - `input`: The [`syn::DeriveInput`] for struct that is deriving the label
-/// trait
-/// - `trait_path`: The path [`syn::Path`] to the label trait
-pub fn derive_label(
- input: syn::DeriveInput,
- trait_path: &syn::Path,
- attr_name: &str,
-) -> TokenStream {
- // return true if the variant specified is an `ignore_fields` attribute
- fn is_ignore(attr: &syn::Attribute, attr_name: &str) -> bool {
- if attr.path.get_ident().as_ref().unwrap() != &attr_name {
- return false;
- }
-
- syn::custom_keyword!(ignore_fields);
- attr.parse_args_with(|input: syn::parse::ParseStream| {
- let ignore = input.parse::<Option<ignore_fields>>()?.is_some();
- Ok(ignore)
- })
- .unwrap()
- }
-
- let ident = input.ident.clone();
-
- let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
- let mut where_clause = where_clause.cloned().unwrap_or_else(|| syn::WhereClause {
- where_token: Default::default(),
- predicates: Default::default(),
- });
- where_clause
- .predicates
- .push(syn::parse2(quote! { Self: 'static }).unwrap());
-
- let as_str = match input.data {
- syn::Data::Struct(d) => {
- // see if the user tried to ignore fields incorrectly
- if let Some(attr) = d
- .fields
- .iter()
- .flat_map(|f| &f.attrs)
- .find(|a| is_ignore(a, attr_name))
- {
- let err_msg = format!("`#[{attr_name}(ignore_fields)]` cannot be applied to fields individually: add it to the struct declaration");
- return quote_spanned! {
- attr.span() => compile_error!(#err_msg);
- }
- .into();
- }
- // Structs must either be fieldless, or explicitly ignore the fields.
- let ignore_fields = input.attrs.iter().any(|a| is_ignore(a, attr_name));
- if matches!(d.fields, syn::Fields::Unit) || ignore_fields {
- let lit = ident.to_string();
- quote! { #lit }
- } else {
- let err_msg = format!("Labels cannot contain data, unless explicitly ignored with `#[{attr_name}(ignore_fields)]`");
- return quote_spanned! {
- d.fields.span() => compile_error!(#err_msg);
- }
- .into();
- }
- }
- syn::Data::Enum(d) => {
- // check if the user put #[label(ignore_fields)] in the wrong place
- if let Some(attr) = input.attrs.iter().find(|a| is_ignore(a, attr_name)) {
- let err_msg = format!("`#[{attr_name}(ignore_fields)]` can only be applied to enum variants or struct declarations");
- return quote_spanned! {
- attr.span() => compile_error!(#err_msg);
- }
- .into();
- }
- let arms = d.variants.iter().map(|v| {
- // Variants must either be fieldless, or explicitly ignore the fields.
- let ignore_fields = v.attrs.iter().any(|a| is_ignore(a, attr_name));
- if matches!(v.fields, syn::Fields::Unit) | ignore_fields {
- let mut path = syn::Path::from(ident.clone());
- path.segments.push(v.ident.clone().into());
- let lit = format!("{ident}::{}", v.ident.clone());
- quote! { #path { .. } => #lit }
- } else {
- let err_msg = format!("Label variants cannot contain data, unless explicitly ignored with `#[{attr_name}(ignore_fields)]`");
- quote_spanned! {
- v.fields.span() => _ => { compile_error!(#err_msg); }
- }
- }
- });
- quote! {
- match self {
- #(#arms),*
- }
- }
- }
- syn::Data::Union(_) => {
- return quote_spanned! {
- input.span() => compile_error!("Unions cannot be used as labels.");
- }
- .into();
- }
- };
-
- (quote! {
- impl #impl_generics #trait_path for #ident #ty_generics #where_clause {
- fn as_str(&self) -> &'static str {
- #as_str
- }
- }
- })
- .into()
-}
diff --git a/azalea-ecs/azalea-ecs-macros/src/utils/shape.rs b/azalea-ecs/azalea-ecs-macros/src/utils/shape.rs
deleted file mode 100644
index 98230749..00000000
--- a/azalea-ecs/azalea-ecs-macros/src/utils/shape.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-use proc_macro::Span;
-use syn::{Data, DataStruct, Error, Fields, FieldsNamed};
-
-/// Get the fields of a data structure if that structure is a struct with named
-/// fields; otherwise, return a compile error that points to the site of the
-/// macro invocation.
-pub fn get_named_struct_fields(data: &syn::Data) -> syn::Result<&FieldsNamed> {
- match data {
- Data::Struct(DataStruct {
- fields: Fields::Named(fields),
- ..
- }) => Ok(fields),
- _ => Err(Error::new(
- // This deliberately points to the call site rather than the structure
- // body; marking the entire body as the source of the error makes it
- // impossible to figure out which `derive` has a problem.
- Span::call_site().into(),
- "Only structs with named fields are supported",
- )),
- }
-}
diff --git a/azalea-ecs/azalea-ecs-macros/src/utils/symbol.rs b/azalea-ecs/azalea-ecs-macros/src/utils/symbol.rs
deleted file mode 100644
index dc639f4d..00000000
--- a/azalea-ecs/azalea-ecs-macros/src/utils/symbol.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-use std::fmt::{self, Display};
-use syn::{Ident, Path};
-
-#[derive(Copy, Clone)]
-pub struct Symbol(pub &'static str);
-
-impl PartialEq<Symbol> for Ident {
- fn eq(&self, word: &Symbol) -> bool {
- self == word.0
- }
-}
-
-impl<'a> PartialEq<Symbol> for &'a Ident {
- fn eq(&self, word: &Symbol) -> bool {
- *self == word.0
- }
-}
-
-impl PartialEq<Symbol> for Path {
- fn eq(&self, word: &Symbol) -> bool {
- self.is_ident(word.0)
- }
-}
-
-impl<'a> PartialEq<Symbol> for &'a Path {
- fn eq(&self, word: &Symbol) -> bool {
- self.is_ident(word.0)
- }
-}
-
-impl Display for Symbol {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str(self.0)
- }
-}
diff --git a/azalea-ecs/src/lib.rs b/azalea-ecs/src/lib.rs
deleted file mode 100644
index bc374e45..00000000
--- a/azalea-ecs/src/lib.rs
+++ /dev/null
@@ -1,157 +0,0 @@
-#![feature(trait_alias)]
-
-//! Re-export important parts of [`bevy_ecs`] and [`bevy_app`] and make them
-//! more compatible with Azalea.
-//!
-//! This is completely compatible with `bevy_ecs`, so it won't cause issues if
-//! you use plugins meant for Bevy.
-//!
-//! Changes:
-//! - Add [`TickPlugin`], [`TickStage`] and [`AppTickExt`] (which adds
-//! `app.add_tick_system` and `app.add_tick_system_set`).
-//! - Change the macros to use azalea/azalea_ecs instead of bevy/bevy_ecs
-//! - Rename `world::World` to [`ecs::Ecs`]
-//! - Re-export `bevy_app` in the [`app`] module.
-//!
-//! [`bevy_ecs`]: https://docs.rs/bevy_ecs
-//! [`bevy_app`]: https://docs.rs/bevy_app
-
-use std::time::{Duration, Instant};
-
-pub mod ecs {
- pub use bevy_ecs::world::World as Ecs;
- pub use bevy_ecs::world::{EntityMut, EntityRef, Mut};
-}
-pub mod component {
- pub use azalea_ecs_macros::Component;
- pub use bevy_ecs::component::{ComponentId, ComponentStorage, Components, TableStorage};
-
- // we do this because re-exporting Component would re-export the macro as well,
- // which is bad (since we have our own Component macro)
- // instead, we have to do this so Component is a trait alias and the original
- // impl-able trait is still available as _BevyComponent
- pub trait Component = bevy_ecs::component::Component;
- pub use bevy_ecs::component::Component as _BevyComponent;
-}
-pub mod bundle {
- pub use azalea_ecs_macros::Bundle;
- pub trait Bundle = bevy_ecs::bundle::Bundle;
- pub use bevy_ecs::bundle::Bundle as _BevyBundle;
-}
-pub mod system {
- pub use azalea_ecs_macros::Resource;
- pub use bevy_ecs::system::{
- Command, Commands, EntityCommands, Query, Res, ResMut, SystemState,
- };
- pub trait Resource = bevy_ecs::system::Resource;
- pub use bevy_ecs::system::Resource as _BevyResource;
-}
-pub mod schedule {
- pub use azalea_ecs_macros::StageLabel;
- pub use bevy_ecs::schedule::{
- IntoRunCriteria, IntoSystemDescriptor, ReportExecutionOrderAmbiguities, Schedule, Stage,
- SystemSet, SystemStage,
- };
- pub trait StageLabel = bevy_ecs::schedule::StageLabel;
- pub use bevy_ecs::schedule::StageLabel as _BevyStageLabel;
-}
-pub use bevy_app as app;
-pub use bevy_ecs::{entity, event, ptr, query, storage};
-
-use app::{App, CoreStage, Plugin};
-use bevy_ecs::schedule::*;
-use ecs::Ecs;
-
-pub struct TickPlugin {
- /// How often a tick should happen. 50 milliseconds by default. Set to 0 to
- /// tick every update.
- pub tick_interval: Duration,
-}
-impl Plugin for TickPlugin {
- fn build(&self, app: &mut App) {
- app.add_stage_before(
- CoreStage::Update,
- TickLabel,
- TickStage {
- interval: self.tick_interval,
- next_tick: Instant::now(),
- stage: Box::new(SystemStage::parallel()),
- },
- );
- }
-}
-impl Default for TickPlugin {
- fn default() -> Self {
- Self {
- tick_interval: Duration::from_millis(50),
- }
- }
-}
-
-#[derive(StageLabel)]
-struct TickLabel;
-
-/// A [`Stage`] that runs every 50 milliseconds.
-pub struct TickStage {
- pub interval: Duration,
- pub next_tick: Instant,
- stage: Box<dyn Stage>,
-}
-
-impl Stage for TickStage {
- fn run(&mut self, ecs: &mut Ecs) {
- // if the interval is 0, that means it runs every tick
- if self.interval.is_zero() {
- self.stage.run(ecs);
- return;
- }
- // keep calling run until it's caught up
- // TODO: Minecraft bursts up to 10 ticks and then skips, we should too (but
- // check the source so we do it right)
- while Instant::now() > self.next_tick {
- self.next_tick += self.interval;
- self.stage.run(ecs);
- }
- }
-}
-
-pub trait AppTickExt {
- fn add_tick_system_set(&mut self, system_set: SystemSet) -> &mut App;
- fn add_tick_system<Params>(&mut self, system: impl IntoSystemDescriptor<Params>) -> &mut App;
-}
-
-impl AppTickExt for App {
- /// Adds a set of ECS systems that will run every 50 milliseconds.
- ///
- /// Note that you should NOT have `EventReader`s in tick systems, as this
- /// will make them sometimes be missed.
- fn add_tick_system_set(&mut self, system_set: SystemSet) -> &mut App {
- let tick_stage = self
- .schedule
- .get_stage_mut::<TickStage>(TickLabel)
- .expect("Tick Stage not found");
- let stage = tick_stage
- .stage
- .downcast_mut::<SystemStage>()
- .expect("Fixed Timestep sub-stage is not a SystemStage");
- stage.add_system_set(system_set);
- self
- }
-
- /// Adds a new ECS system that will run every 50 milliseconds.
- ///
- /// Note that you should NOT have `EventReader`s in tick systems, as this
- /// will make them sometimes be missed.
- fn add_tick_system<Params>(&mut self, system: impl IntoSystemDescriptor<Params>) -> &mut App {
- let tick_stage = self
- .schedule
- .get_stage_mut::<TickStage>(TickLabel)
- .expect("Tick Stage not found");
- let stage = tick_stage
- .stage
- .downcast_mut::<SystemStage>()
- .expect("Fixed Timestep sub-stage is not a SystemStage");
- stage.add_system(system);
- self
- }
-}
diff --git a/azalea-physics/Cargo.toml b/azalea-physics/Cargo.toml
index 9305080b..dd579471 100644
--- a/azalea-physics/Cargo.toml
+++ b/azalea-physics/Cargo.toml
@@ -9,13 +9,15 @@ version = "0.6.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-azalea-block = {path = "../azalea-block", version = "^0.6.0"}
-azalea-core = {path = "../azalea-core", version = "^0.6.0"}
-azalea-ecs = {version = "0.6.0", path = "../azalea-ecs"}
-azalea-registry = {path = "../azalea-registry", version = "^0.6.0"}
-azalea-world = {path = "../azalea-world", version = "^0.6.0"}
+azalea-block = { path = "../azalea-block", version = "^0.6.0" }
+azalea-core = { path = "../azalea-core", version = "^0.6.0" }
+azalea-registry = { path = "../azalea-registry", version = "^0.6.0" }
+azalea-world = { path = "../azalea-world", version = "^0.6.0" }
+bevy_app = "0.10.0"
+bevy_ecs = "0.10.0"
once_cell = "1.16.0"
parking_lot = "^0.12.1"
[dev-dependencies]
+bevy_time = "0.10.0"
uuid = "^1.1.2"
diff --git a/azalea-physics/src/collision/mod.rs b/azalea-physics/src/collision/mod.rs
index 7d934020..53efd2fe 100644
--- a/azalea-physics/src/collision/mod.rs
+++ b/azalea-physics/src/collision/mod.rs
@@ -7,7 +7,7 @@ mod world_collisions;
use azalea_core::{Axis, Vec3, AABB, EPSILON};
use azalea_world::{
entity::{self},
- MoveEntityError, World,
+ Instance, MoveEntityError,
};
pub use blocks::BlockWithShape;
pub use discrete_voxel_shape::*;
@@ -52,7 +52,7 @@ pub enum MoverType {
// return var4;
// }
-fn collide(movement: &Vec3, world: &World, physics: &entity::Physics) -> Vec3 {
+fn collide(movement: &Vec3, world: &Instance, physics: &entity::Physics) -> Vec3 {
let entity_bounding_box = physics.bounding_box;
// TODO: get_entity_collisions
// let entity_collisions = world.get_entity_collisions(self,
@@ -73,7 +73,7 @@ fn collide(movement: &Vec3, world: &World, physics: &entity::Physics) -> Vec3 {
pub fn move_colliding(
_mover_type: &MoverType,
movement: &Vec3,
- world: &World,
+ world: &Instance,
position: &mut entity::Position,
physics: &mut entity::Physics,
) -> Result<(), MoveEntityError> {
@@ -186,7 +186,7 @@ pub fn move_colliding(
fn collide_bounding_box(
movement: &Vec3,
entity_bounding_box: &AABB,
- world: &World,
+ world: &Instance,
entity_collisions: Vec<VoxelShape>,
) -> Vec3 {
let mut collision_boxes: Vec<VoxelShape> = Vec::with_capacity(entity_collisions.len() + 1);
diff --git a/azalea-physics/src/collision/world_collisions.rs b/azalea-physics/src/collision/world_collisions.rs
index 9ffc62a5..aa55150e 100644
--- a/azalea-physics/src/collision/world_collisions.rs
+++ b/azalea-physics/src/collision/world_collisions.rs
@@ -2,16 +2,16 @@ use super::Shapes;
use crate::collision::{BlockWithShape, VoxelShape, AABB};
use azalea_block::BlockState;
use azalea_core::{ChunkPos, ChunkSectionPos, Cursor3d, CursorIterationType, EPSILON};
-use azalea_world::{Chunk, World};
+use azalea_world::{Chunk, Instance};
use parking_lot::RwLock;
use std::sync::Arc;
-pub fn get_block_collisions(world: &World, aabb: AABB) -> BlockCollisions<'_> {
+pub fn get_block_collisions(world: &Instance, aabb: AABB) -> BlockCollisions<'_> {
BlockCollisions::new(world, aabb)
}
pub struct BlockCollisions<'a> {
- pub world: &'a World,
+ pub world: &'a Instance,
pub aabb: AABB,
pub entity_shape: VoxelShape,
pub cursor: Cursor3d,
@@ -19,7 +19,7 @@ pub struct BlockCollisions<'a> {
}
impl<'a> BlockCollisions<'a> {
- pub fn new(world: &'a World, aabb: AABB) -> Self {
+ pub fn new(world: &'a Instance, aabb: AABB) -> Self {
let origin_x = (aabb.min_x - EPSILON).floor() as i32 - 1;
let origin_y = (aabb.min_y - EPSILON).floor() as i32 - 1;
let origin_z = (aabb.min_z - EPSILON).floor() as i32 - 1;
diff --git a/azalea-physics/src/lib.rs b/azalea-physics/src/lib.rs
index 0a8f8a8b..e3954061 100644
--- a/azalea-physics/src/lib.rs
+++ b/azalea-physics/src/lib.rs
@@ -5,37 +5,38 @@ pub mod collision;
use azalea_block::{Block, BlockState};
use azalea_core::{BlockPos, Vec3};
-use azalea_ecs::{
- app::{App, Plugin},
- entity::Entity,
- event::{EventReader, EventWriter},
- query::With,
- schedule::IntoSystemDescriptor,
- system::{Query, Res},
- AppTickExt,
-};
use azalea_world::{
entity::{
metadata::Sprinting, move_relative, Attributes, Jumping, Local, Physics, Position,
WorldName,
},
- World, WorldContainer,
+ Instance, WorldContainer,
+};
+use bevy_app::{App, CoreSchedule, IntoSystemAppConfigs, Plugin};
+use bevy_ecs::{
+ entity::Entity,
+ event::{EventReader, EventWriter},
+ query::With,
+ schedule::{IntoSystemConfig, IntoSystemConfigs, SystemSet},
+ system::{Query, Res},
};
use collision::{move_colliding, MoverType};
+/// A Bevy [`SystemSet`] for running physics that makes entities do things.
+#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
+pub struct PhysicsSet;
+
pub struct PhysicsPlugin;
impl Plugin for PhysicsPlugin {
fn build(&self, app: &mut App) {
app.add_event::<ForceJumpEvent>()
- .add_system(
- force_jump_listener
- .label("force_jump_listener")
- .after("walk_listener")
- .after("sprint_listener")
- .before(azalea_world::entity::update_bounding_box),
- )
- .add_tick_system(travel.label("travel").after(ai_step))
- .add_tick_system(ai_step.label("ai_step"));
+ .add_system(force_jump_listener.before(azalea_world::entity::update_bounding_box))
+ .add_systems(
+ (ai_step, travel)
+ .chain()
+ .in_set(PhysicsSet)
+ .in_schedule(CoreSchedule::FixedUpdate),
+ );
}
}
@@ -156,7 +157,7 @@ pub fn ai_step(
/// Jump even if we aren't on the ground.
pub struct ForceJumpEvent(pub Entity);
-fn force_jump_listener(
+pub fn force_jump_listener(
mut query: Query<(&mut Physics, &Position, &Sprinting, &WorldName)>,
world_container: Res<WorldContainer>,
mut events: EventReader<ForceJumpEvent>,
@@ -201,7 +202,7 @@ fn get_block_pos_below_that_affects_movement(position: &Position) -> BlockPos {
fn handle_relative_friction_and_calculate_movement(
block_friction: f32,
- world: &World,
+ world: &Instance,
physics: &mut Physics,
position: &mut Position,
attributes: &Attributes,
@@ -251,7 +252,7 @@ fn get_friction_influenced_speed(physics: &Physics, attributes: &Attributes, fri
/// Returns the what the entity's jump should be multiplied by based on the
/// block they're standing on.
-fn block_jump_factor(world: &World, position: &Position) -> f32 {
+fn block_jump_factor(world: &Instance, position: &Position) -> f32 {
let block_at_pos = world.chunks.get_block_state(&position.into());
let block_below = world
.chunks
@@ -279,7 +280,7 @@ fn block_jump_factor(world: &World, position: &Position) -> f32 {
// public double getJumpBoostPower() {
// return this.hasEffect(MobEffects.JUMP) ? (double)(0.1F *
// (float)(this.getEffect(MobEffects.JUMP).getAmplifier() + 1)) : 0.0D; }
-fn jump_power(world: &World, position: &Position) -> f32 {
+fn jump_power(world: &Instance, position: &Position) -> f32 {
0.42 * block_jump_factor(world, position)
}
@@ -303,22 +304,21 @@ mod tests {
use super::*;
use azalea_core::{ChunkPos, ResourceLocation};
- use azalea_ecs::{app::App, TickPlugin};
use azalea_world::{
entity::{EntityBundle, EntityPlugin, MinecraftEntityId},
Chunk, PartialWorld,
};
+ use bevy_app::App;
+ use bevy_time::fixed_timestep::FixedTime;
use uuid::Uuid;
/// You need an app to spawn entities in the world and do updates.
fn make_test_app() -> App {
let mut app = App::new();
- app.add_plugin(TickPlugin {
- tick_interval: Duration::ZERO,
- })
- .add_plugin(PhysicsPlugin)
- .add_plugin(EntityPlugin)
- .init_resource::<WorldContainer>();
+ app.add_plugin(PhysicsPlugin)
+ .add_plugin(EntityPlugin)
+ .insert_resource(FixedTime::new(Duration::from_millis(50)))
+ .init_resource::<WorldContainer>();
app
}
@@ -353,6 +353,7 @@ mod tests {
// y should start at 70
assert_eq!(entity_pos.y, 70.);
}
+ app.world.run_schedule(CoreSchedule::FixedUpdate);
app.update();
{
let entity_pos = *app.world.get::<Position>(entity).unwrap();
@@ -361,6 +362,7 @@ mod tests {
let entity_physics = app.world.get::<Physics>(entity).unwrap().clone();
assert!(entity_physics.delta.y < 0.);
}
+ app.world.run_schedule(CoreSchedule::FixedUpdate);
app.update();
{
let entity_pos = *app.world.get::<Position>(entity).unwrap();
@@ -413,6 +415,7 @@ mod tests {
block_state.is_some(),
"Block state should exist, if this fails that means the chunk wasn't loaded and the block didn't get placed"
);
+ app.world.run_schedule(CoreSchedule::FixedUpdate);
app.update();
{
let entity_pos = *app.world.get::<Position>(entity).unwrap();
@@ -421,6 +424,7 @@ mod tests {
let entity_physics = app.world.get::<Physics>(entity).unwrap().clone();
assert!(entity_physics.delta.y < 0.);
}
+ app.world.run_schedule(CoreSchedule::FixedUpdate);
app.update();
{
let entity_pos = *app.world.get::<Position>(entity).unwrap();
@@ -476,6 +480,7 @@ mod tests {
);
// do a few steps so we fall on the slab
for _ in 0..20 {
+ app.world.run_schedule(CoreSchedule::FixedUpdate);
app.update();
}
let entity_pos = app.world.get::<Position>(entity).unwrap();
@@ -528,6 +533,7 @@ mod tests {
);
// do a few steps so we fall on the slab
for _ in 0..20 {
+ app.world.run_schedule(CoreSchedule::FixedUpdate);
app.update();
}
let entity_pos = app.world.get::<Position>(entity).unwrap();
@@ -584,6 +590,7 @@ mod tests {
);
// do a few steps so we fall on the wall
for _ in 0..20 {
+ app.world.run_schedule(CoreSchedule::FixedUpdate);
app.update();
}
@@ -645,6 +652,7 @@ mod tests {
);
// do a few steps so we fall on the wall
for _ in 0..20 {
+ app.world.run_schedule(CoreSchedule::FixedUpdate);
app.update();
}
diff --git a/azalea-protocol/Cargo.toml b/azalea-protocol/Cargo.toml
index fa669b2e..1bbda7eb 100644
--- a/azalea-protocol/Cargo.toml
+++ b/azalea-protocol/Cargo.toml
@@ -9,32 +9,39 @@ version = "0.6.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-async-compression = {version = "^0.3.8", features = ["tokio", "zlib"], optional = true}
+async-compression = { version = "^0.3.8", features = [
+ "tokio",
+ "zlib",
+], optional = true }
async-recursion = "1.0.0"
-azalea-auth = {path = "../azalea-auth", version = "^0.6.0" }
-azalea-block = {path = "../azalea-block", default-features = false, version = "^0.6.0" }
-azalea-brigadier = {path = "../azalea-brigadier", version = "^0.6.0", features = ["azalea-buf"]}
-azalea-buf = {path = "../azalea-buf", version = "^0.6.0" }
-azalea-chat = {path = "../azalea-chat", version = "^0.6.0" }
-azalea-core = {path = "../azalea-core", optional = true, version = "^0.6.0" }
-azalea-crypto = {path = "../azalea-crypto", version = "^0.6.0" }
-azalea-nbt = {path = "../azalea-nbt", version = "^0.6.0" }
-azalea-protocol-macros = {path = "./azalea-protocol-macros", version = "^0.6.0" }
-azalea-registry = {path = "../azalea-registry", version = "^0.6.0" }
-azalea-world = {path = "../azalea-world", version = "^0.6.0" }
-bevy_ecs = { version = "0.9.1", default-features = false }
+azalea-auth = { path = "../azalea-auth", version = "^0.6.0" }
+azalea-block = { path = "../azalea-block", default-features = false, version = "^0.6.0" }
+azalea-brigadier = { path = "../azalea-brigadier", version = "^0.6.0", features = [
+ "azalea-buf",
+] }
+azalea-buf = { path = "../azalea-buf", version = "^0.6.0" }
+azalea-chat = { path = "../azalea-chat", version = "^0.6.0" }
+azalea-core = { path = "../azalea-core", optional = true, version = "^0.6.0" }
+azalea-crypto = { path = "../azalea-crypto", version = "^0.6.0" }
+azalea-nbt = { path = "../azalea-nbt", version = "^0.6.0" }
+azalea-protocol-macros = { path = "./azalea-protocol-macros", version = "^0.6.0" }
+azalea-registry = { path = "../azalea-registry", version = "^0.6.0" }
+azalea-world = { path = "../azalea-world", version = "^0.6.0" }
+bevy_ecs = { version = "0.10.0", default-features = false }
byteorder = "^1.4.3"
bytes = "^1.1.0"
flate2 = "1.0.23"
futures = "0.3.24"
futures-util = "0.3.24"
log = "0.4.17"
-serde = {version = "1.0.130", features = ["serde_derive"]}
+serde = { version = "1.0.130", features = ["serde_derive"] }
serde_json = "^1.0.72"
thiserror = "1.0.37"
-tokio = {version = "^1.24.2", features = ["io-util", "net", "macros"]}
-tokio-util = {version = "0.7.4", features = ["codec"]}
-trust-dns-resolver = {version = "^0.22.0", default-features = false, features = ["tokio-runtime"]}
+tokio = { version = "^1.24.2", features = ["io-util", "net", "macros"] }
+tokio-util = { version = "0.7.4", features = ["codec"] }
+trust-dns-resolver = { version = "^0.22.0", default-features = false, features = [
+ "tokio-runtime",
+] }
uuid = "1.1.2"
[features]
diff --git a/azalea-world/Cargo.toml b/azalea-world/Cargo.toml
index 4d53cabd..113125a4 100644
--- a/azalea-world/Cargo.toml
+++ b/azalea-world/Cargo.toml
@@ -15,9 +15,10 @@ azalea-chat = { path = "../azalea-chat", version = "^0.6.0" }
azalea-core = { path = "../azalea-core", version = "^0.6.0", features = [
"bevy_ecs",
] }
-azalea-ecs = { version = "0.6.0", path = "../azalea-ecs" }
azalea-nbt = { path = "../azalea-nbt", version = "^0.6.0" }
azalea-registry = { path = "../azalea-registry", version = "^0.6.0" }
+bevy_app = "0.10.0"
+bevy_ecs = "0.10.0"
derive_more = { version = "0.99.17", features = ["deref", "deref_mut"] }
enum-as-inner = "0.5.1"
log = "0.4.17"
diff --git a/azalea-world/src/container.rs b/azalea-world/src/container.rs
index 74d70659..fdd89a75 100644
--- a/azalea-world/src/container.rs
+++ b/azalea-world/src/container.rs
@@ -1,5 +1,5 @@
use azalea_core::ResourceLocation;
-use azalea_ecs::system::Resource;
+use bevy_ecs::system::Resource;
use log::error;
use nohash_hasher::IntMap;
use parking_lot::RwLock;
@@ -8,7 +8,7 @@ use std::{
sync::{Arc, Weak},
};
-use crate::{ChunkStorage, World};
+use crate::{ChunkStorage, Instance};
/// A container of [`World`]s. Worlds are stored as a Weak pointer here, so
/// if no clients are using a world it will be forgotten.
@@ -26,7 +26,7 @@ pub struct WorldContainer {
// telling them apart. We hope most servers are nice and don't do that though. It's only an
// issue when there's multiple clients with the same WorldContainer in different worlds
// anyways.
- pub worlds: HashMap<ResourceLocation, Weak<RwLock<World>>>,
+ pub worlds: HashMap<ResourceLocation, Weak<RwLock<Instance>>>,
}
impl WorldContainer {
@@ -37,7 +37,7 @@ impl WorldContainer {
}
/// Get a world from the container.
- pub fn get(&self, name: &ResourceLocation) -> Option<Arc<RwLock<World>>> {
+ pub fn get(&self, name: &ResourceLocation) -> Option<Arc<RwLock<Instance>>> {
self.worlds.get(name).and_then(|world| world.upgrade())
}
@@ -49,7 +49,7 @@ impl WorldContainer {
name: ResourceLocation,
height: u32,
min_y: i32,
- ) -> Arc<RwLock<World>> {
+ ) -> Arc<RwLock<Instance>> {
if let Some(existing_lock) = self.worlds.get(&name).and_then(|world| world.upgrade()) {
let existing = existing_lock.read();
if existing.chunks.height != height {
@@ -66,7 +66,7 @@ impl WorldContainer {
}
existing_lock.clone()
} else {
- let world = Arc::new(RwLock::new(World {
+ let world = Arc::new(RwLock::new(Instance {
chunks: ChunkStorage::new(height, min_y),
entities_by_chunk: HashMap::new(),
entity_by_id: IntMap::default(),
diff --git a/azalea-world/src/entity/attributes.rs b/azalea-world/src/entity/attributes.rs
index 6b10a2b4..97b890dc 100644
--- a/azalea-world/src/entity/attributes.rs
+++ b/azalea-world/src/entity/attributes.rs
@@ -6,7 +6,7 @@ use std::{
};
use azalea_buf::{BufReadError, McBuf, McBufReadable, McBufWritable};
-use azalea_ecs::component::Component;
+use bevy_ecs::component::Component;
use thiserror::Error;
use uuid::{uuid, Uuid};
diff --git a/azalea-world/src/entity/data.rs b/azalea-world/src/entity/data.rs
index 346b277b..65988a19 100755
--- a/azalea-world/src/entity/data.rs
+++ b/azalea-world/src/entity/data.rs
@@ -6,7 +6,7 @@ use azalea_buf::{
};
use azalea_chat::FormattedText;
use azalea_core::{BlockPos, Direction, GlobalPos, Particle, Slot};
-use azalea_ecs::component::Component;
+use bevy_ecs::component::Component;
use derive_more::Deref;
use enum_as_inner::EnumAsInner;
use nohash_hasher::IntSet;
diff --git a/azalea-world/src/entity/dimensions.rs b/azalea-world/src/entity/dimensions.rs
index daf85432..5e716307 100755
--- a/azalea-world/src/entity/dimensions.rs
+++ b/azalea-world/src/entity/dimensions.rs
@@ -1,5 +1,5 @@
use azalea_core::{Vec3, AABB};
-use azalea_ecs::{query::Changed, system::Query};
+use bevy_ecs::{query::Changed, system::Query};
use super::{Physics, Position};
diff --git a/azalea-world/src/entity/info.rs b/azalea-world/src/entity/info.rs
index 8615ef81..19e87627 100644
--- a/azalea-world/src/entity/info.rs
+++ b/azalea-world/src/entity/info.rs
@@ -9,15 +9,14 @@ use crate::{
update_entity_by_id_index, update_uuid_index, PartialWorld, WorldContainer,
};
use azalea_core::ChunkPos;
-use azalea_ecs::{
- app::{App, CoreStage, Plugin},
+use bevy_app::{App, CoreSet, Plugin};
+use bevy_ecs::{
component::Component,
- ecs::Ecs,
- ecs::EntityMut,
entity::Entity,
query::{Added, Changed, With, Without},
- schedule::{IntoSystemDescriptor, SystemSet},
- system::{Command, Commands, Query, Res, ResMut, Resource},
+ schedule::{IntoSystemConfig, IntoSystemConfigs, SystemSet},
+ system::{Commands, EntityCommand, Query, Res, ResMut, Resource},
+ world::{EntityMut, World},
};
use derive_more::{Deref, DerefMut};
use log::{debug, warn};
@@ -32,6 +31,18 @@ use uuid::Uuid;
use super::Local;
+/// A Bevy [`SystemSet`] for various types of entity updates.
+#[derive(SystemSet, Debug, Hash, Eq, PartialEq, Clone)]
+pub enum EntityUpdateSet {
+ /// Remove ECS entities that refer to an entity that was already in the ECS
+ /// before.
+ Deduplicate,
+ /// Create search indexes for entities.
+ Index,
+ /// Remove despawned entities from search indexes.
+ Deindex,
+}
+
/// Plugin handling some basic entity functionality.
pub struct EntityPlugin;
impl Plugin for EntityPlugin {
@@ -40,30 +51,31 @@ impl Plugin for EntityPlugin {
// added to indexes during update (done by this plugin)
// modified during update
// despawned post-update (done by this plugin)
- app.add_system_set_to_stage(
- CoreStage::PreUpdate,
- SystemSet::new().with_system(remove_despawned_entities_from_indexes),
- )
- .add_system_set_to_stage(
- CoreStage::PostUpdate,
- SystemSet::new()
- .with_system(deduplicate_entities.label("deduplicate_entities"))
- .with_system(deduplicate_local_entities.label("deduplicate_entities")),
+ app.add_system(
+ remove_despawned_entities_from_indexes
+ .in_base_set(CoreSet::PreUpdate)
+ .in_set(EntityUpdateSet::Deindex),
)
- .add_system_set(
- SystemSet::new()
- .with_system(update_entity_chunk_positions)
- .with_system(update_uuid_index.label("update_indexes"))
- .with_system(update_entity_by_id_index.label("update_indexes")),
+ .add_systems(
+ (deduplicate_entities, deduplicate_local_entities)
+ .in_base_set(CoreSet::PostUpdate)
+ .in_set(EntityUpdateSet::Deduplicate),
)
- .add_system_set(
- SystemSet::new()
- .with_system(add_updates_received.label("add_updates_received"))
- .with_system(debug_new_entity)
- .with_system(debug_detect_updates_received_on_local_entities)
- .with_system(add_dead)
- .with_system(update_bounding_box),
+ .add_systems(
+ (
+ update_entity_chunk_positions,
+ update_uuid_index,
+ update_entity_by_id_index,
+ )
+ .in_set(EntityUpdateSet::Index),
)
+ .add_systems((
+ add_updates_received,
+ debug_new_entity,
+ debug_detect_updates_received_on_local_entities,
+ add_dead,
+ update_bounding_box,
+ ))
.init_resource::<EntityInfos>();
}
}
@@ -134,26 +146,24 @@ impl PartialEntityInfos {
/// other clients within render distance will get too. You usually don't need
/// this when the change isn't relative either.
pub struct RelativeEntityUpdate {
- pub entity: Entity,
pub partial_world: Arc<RwLock<PartialWorld>>,
// a function that takes the entity and updates it
pub update: Box<dyn FnOnce(&mut EntityMut) + Send + Sync>,
}
-impl Command for RelativeEntityUpdate {
- fn write(self, world: &mut Ecs) {
+impl EntityCommand for RelativeEntityUpdate {
+ fn write(self, entity: Entity, world: &mut World) {
let partial_entity_infos = &mut self.partial_world.write().entity_infos;
- let mut entity = world.entity_mut(self.entity);
+ let mut entity_mut = world.entity_mut(entity);
- if Some(self.entity) == partial_entity_infos.owner_entity {
+ if Some(entity) == partial_entity_infos.owner_entity {
// if the entity owns this partial world, it's always allowed to update itself
- (self.update)(&mut entity);
+ (self.update)(&mut entity_mut);
return;
};
- let entity_id = *entity.get::<MinecraftEntityId>().unwrap();
-
- let Some(updates_received) = entity.get_mut::<UpdatesReceived>() else {
+ let entity_id = *entity_mut.get::<MinecraftEntityId>().unwrap();
+ let Some(updates_received) = entity_mut.get_mut::<UpdatesReceived>() else {
// a client tried to update another client, which isn't allowed
return;
};
@@ -170,9 +180,9 @@ impl Command for RelativeEntityUpdate {
.updates_received
.insert(entity_id, new_updates_received);
- **entity.get_mut::<UpdatesReceived>().unwrap() = new_updates_received;
+ **entity_mut.get_mut::<UpdatesReceived>().unwrap() = new_updates_received;
- let mut entity = world.entity_mut(self.entity);
+ let mut entity = world.entity_mut(entity);
(self.update)(&mut entity);
}
}
diff --git a/azalea-world/src/entity/metadata.rs b/azalea-world/src/entity/metadata.rs
index 8960b045..0a0bddc8 100644
--- a/azalea-world/src/entity/metadata.rs
+++ b/azalea-world/src/entity/metadata.rs
@@ -7,7 +7,7 @@ use super::{EntityDataItem, EntityDataValue, OptionalUnsignedInt, Pose, Rotation
use azalea_block::BlockState;
use azalea_chat::FormattedText;
use azalea_core::{BlockPos, Direction, Particle, Slot};
-use azalea_ecs::{bundle::Bundle, component::Component};
+use bevy_ecs::{bundle::Bundle, component::Component};
use derive_more::{Deref, DerefMut};
use thiserror::Error;
use uuid::Uuid;
@@ -79,7 +79,7 @@ pub struct CanDuplicate(pub bool);
pub struct Allay;
impl Allay {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -160,7 +160,7 @@ pub struct Waiting(pub bool);
pub struct AreaEffectCloud;
impl AreaEffectCloud {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -245,7 +245,7 @@ pub struct RightLegPose(pub Rotations);
pub struct ArmorStand;
impl ArmorStand {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -356,7 +356,7 @@ pub struct ArrowEffectColor(pub i32);
pub struct Arrow;
impl Arrow {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -431,7 +431,7 @@ pub struct AxolotlFromBucket(pub bool);
pub struct Axolotl;
impl Axolotl {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -520,7 +520,7 @@ pub struct Resting(pub bool);
pub struct Bat;
impl Bat {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -596,7 +596,7 @@ pub struct BeeRemainingAngerTime(pub i32);
pub struct Bee;
impl Bee {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -687,7 +687,7 @@ pub struct Charged(pub bool);
pub struct Blaze;
impl Blaze {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -775,7 +775,7 @@ pub struct BubbleTime(pub i32);
pub struct Boat;
impl Boat {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -871,7 +871,7 @@ pub struct LastPoseChangeTick(pub i64);
pub struct Camel;
impl Camel {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -990,7 +990,7 @@ pub struct CatCollarColor(pub i32);
pub struct Cat;
impl Cat {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -1090,7 +1090,7 @@ pub struct Climbing(pub bool);
pub struct CaveSpider;
impl CaveSpider {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -1162,7 +1162,7 @@ impl Default for CaveSpiderMetadataBundle {
pub struct ChestBoat;
impl ChestBoat {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -1229,7 +1229,7 @@ pub struct CustomDisplay(pub bool);
pub struct ChestMinecart;
impl ChestMinecart {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -1283,7 +1283,7 @@ impl Default for ChestMinecartMetadataBundle {
pub struct Chicken;
impl Chicken {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -1357,7 +1357,7 @@ pub struct CodFromBucket(pub bool);
pub struct Cod;
impl Cod {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -1431,7 +1431,7 @@ pub struct LastOutput(pub FormattedText);
pub struct CommandBlockMinecart;
impl CommandBlockMinecart {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -1495,7 +1495,7 @@ impl Default for CommandBlockMinecartMetadataBundle {
pub struct Cow;
impl Cow {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -1573,7 +1573,7 @@ pub struct IsIgnited(pub bool);
pub struct Creeper;
impl Creeper {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -1662,7 +1662,7 @@ pub struct MoistnessLevel(pub i32);
pub struct Dolphin;
impl Dolphin {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -1756,7 +1756,7 @@ pub struct DonkeyChest(pub bool);
pub struct Donkey;
impl Donkey {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -1856,7 +1856,7 @@ impl Default for DonkeyMetadataBundle {
pub struct DragonFireball;
impl DragonFireball {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -1907,7 +1907,7 @@ pub struct DrownedConversion(pub bool);
pub struct Drowned;
impl Drowned {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -1983,7 +1983,7 @@ pub struct EggItemStack(pub Slot);
pub struct Egg;
impl Egg {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -2037,7 +2037,7 @@ pub struct AttackTarget(pub i32);
pub struct ElderGuardian;
impl ElderGuardian {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -2114,7 +2114,7 @@ pub struct ShowBottom(pub bool);
pub struct EndCrystal;
impl EndCrystal {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -2171,7 +2171,7 @@ pub struct Phase(pub i32);
pub struct EnderDragon;
impl EnderDragon {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -2240,7 +2240,7 @@ pub struct EnderPearlItemStack(pub Slot);
pub struct EnderPearl;
impl EnderPearl {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -2296,7 +2296,7 @@ pub struct StaredAt(pub bool);
pub struct Enderman;
impl Enderman {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -2379,7 +2379,7 @@ impl Default for EndermanMetadataBundle {
pub struct Endermite;
impl Endermite {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -2451,7 +2451,7 @@ pub struct EvokerSpellCasting(pub u8);
pub struct Evoker;
impl Evoker {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -2529,7 +2529,7 @@ impl Default for EvokerMetadataBundle {
pub struct EvokerFangs;
impl EvokerFangs {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -2576,7 +2576,7 @@ pub struct ExperienceBottleItemStack(pub Slot);
pub struct ExperienceBottle;
impl ExperienceBottle {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -2626,7 +2626,7 @@ impl Default for ExperienceBottleMetadataBundle {
pub struct ExperienceOrb;
impl ExperienceOrb {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -2673,7 +2673,7 @@ pub struct EyeOfEnderItemStack(pub Slot);
pub struct EyeOfEnder;
impl EyeOfEnder {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -2725,7 +2725,7 @@ pub struct StartPos(pub BlockPos);
pub struct FallingBlock;
impl FallingBlock {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -2777,7 +2777,7 @@ pub struct FireballItemStack(pub Slot);
pub struct Fireball;
impl Fireball {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -2833,7 +2833,7 @@ pub struct ShotAtAngle(pub bool);
pub struct FireworkRocket;
impl FireworkRocket {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -2897,7 +2897,7 @@ pub struct Biting(pub bool);
pub struct FishingBobber;
impl FishingBobber {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -2970,7 +2970,7 @@ pub struct TrustedId1(pub Option<Uuid>);
pub struct Fox;
impl Fox {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -3082,7 +3082,7 @@ pub struct TongueTarget(pub OptionalUnsignedInt);
pub struct Frog;
impl Frog {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -3166,7 +3166,7 @@ pub struct Fuel(pub bool);
pub struct FurnaceMinecart;
impl FurnaceMinecart {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -3227,7 +3227,7 @@ pub struct IsCharging(pub bool);
pub struct Ghast;
impl Ghast {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -3294,7 +3294,7 @@ impl Default for GhastMetadataBundle {
pub struct Giant;
impl Giant {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -3366,7 +3366,7 @@ pub struct Rotation(pub i32);
pub struct GlowItemFrame;
impl GlowItemFrame {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -3418,7 +3418,7 @@ pub struct DarkTicksRemaining(pub i32);
pub struct GlowSquid;
impl GlowSquid {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -3497,7 +3497,7 @@ pub struct HasRightHorn(pub bool);
pub struct Goat;
impl Goat {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -3584,7 +3584,7 @@ impl Default for GoatMetadataBundle {
pub struct Guardian;
impl Guardian {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -3664,7 +3664,7 @@ pub struct HoglinImmuneToZombification(pub bool);
pub struct Hoglin;
impl Hoglin {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -3741,7 +3741,7 @@ impl Default for HoglinMetadataBundle {
pub struct HopperMinecart;
impl HopperMinecart {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -3809,7 +3809,7 @@ pub struct HorseTypeVariant(pub i32);
pub struct Horse;
impl Horse {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -3909,7 +3909,7 @@ impl Default for HorseMetadataBundle {
pub struct Husk;
impl Husk {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -3987,7 +3987,7 @@ pub struct IllusionerSpellCasting(pub u8);
pub struct Illusioner;
impl Illusioner {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -4067,7 +4067,7 @@ pub struct PlayerCreated(pub bool);
pub struct IronGolem;
impl IronGolem {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -4140,7 +4140,7 @@ pub struct ItemItem(pub Slot);
pub struct Item;
impl Item {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -4190,7 +4190,7 @@ impl Default for ItemMetadataBundle {
pub struct ItemFrame;
impl ItemFrame {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -4245,7 +4245,7 @@ impl Default for ItemFrameMetadataBundle {
pub struct LeashKnot;
impl LeashKnot {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -4290,7 +4290,7 @@ impl Default for LeashKnotMetadataBundle {
pub struct LightningBolt;
impl LightningBolt {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -4355,7 +4355,7 @@ pub struct LlamaVariant(pub i32);
pub struct Llama;
impl Llama {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -4470,7 +4470,7 @@ impl Default for LlamaMetadataBundle {
pub struct LlamaSpit;
impl LlamaSpit {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -4517,7 +4517,7 @@ pub struct SlimeSize(pub i32);
pub struct MagmaCube;
impl MagmaCube {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -4583,7 +4583,7 @@ impl Default for MagmaCubeMetadataBundle {
pub struct Marker;
impl Marker {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -4628,7 +4628,7 @@ impl Default for MarkerMetadataBundle {
pub struct Minecart;
impl Minecart {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -4684,7 +4684,7 @@ pub struct MooshroomKind(pub String);
pub struct Mooshroom;
impl Mooshroom {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -4778,7 +4778,7 @@ pub struct MuleChest(pub bool);
pub struct Mule;
impl Mule {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -4880,7 +4880,7 @@ pub struct Trusting(pub bool);
pub struct Ocelot;
impl Ocelot {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -4959,7 +4959,7 @@ pub struct PaintingVariant(pub azalea_registry::PaintingVariant);
pub struct Painting;
impl Painting {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -5027,7 +5027,7 @@ pub struct PandaFlags(pub u8);
pub struct Panda;
impl Panda {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -5141,7 +5141,7 @@ pub struct ParrotVariant(pub i32);
pub struct Parrot;
impl Parrot {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -5226,7 +5226,7 @@ pub struct PhantomSize(pub i32);
pub struct Phantom;
impl Phantom {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -5297,7 +5297,7 @@ pub struct PigBoostTime(pub i32);
pub struct Pig;
impl Pig {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -5387,7 +5387,7 @@ pub struct IsDancing(pub bool);
pub struct Piglin;
impl Piglin {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -5477,7 +5477,7 @@ pub struct PiglinBruteImmuneToZombification(pub bool);
pub struct PiglinBrute;
impl PiglinBrute {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -5554,7 +5554,7 @@ pub struct PillagerIsChargingCrossbow(pub bool);
pub struct Pillager;
impl Pillager {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -5644,7 +5644,7 @@ pub struct ShoulderRight(pub azalea_nbt::Tag);
pub struct Player;
impl Player {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -5732,7 +5732,7 @@ pub struct PolarBearStanding(pub bool);
pub struct PolarBear;
impl PolarBear {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -5811,7 +5811,7 @@ pub struct PotionItemStack(pub Slot);
pub struct Potion;
impl Potion {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -5865,7 +5865,7 @@ pub struct PuffState(pub i32);
pub struct Pufferfish;
impl Pufferfish {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -5942,7 +5942,7 @@ pub struct RabbitKind(pub i32);
pub struct Rabbit;
impl Rabbit {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -6021,7 +6021,7 @@ pub struct RavagerIsCelebrating(pub bool);
pub struct Ravager;
impl Ravager {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -6096,7 +6096,7 @@ pub struct SalmonFromBucket(pub bool);
pub struct Salmon;
impl Salmon {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -6168,7 +6168,7 @@ pub struct Sheared(pub bool);
pub struct Sheep;
impl Sheep {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -6252,7 +6252,7 @@ pub struct ShulkerColor(pub u8);
pub struct Shulker;
impl Shulker {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -6332,7 +6332,7 @@ impl Default for ShulkerMetadataBundle {
pub struct ShulkerBullet;
impl ShulkerBullet {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -6377,7 +6377,7 @@ impl Default for ShulkerBulletMetadataBundle {
pub struct Silverfish;
impl Silverfish {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -6447,7 +6447,7 @@ pub struct StrayConversion(pub bool);
pub struct Skeleton;
impl Skeleton {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -6532,7 +6532,7 @@ pub struct SkeletonHorseOwnerUuid(pub Option<Uuid>);
pub struct SkeletonHorse;
impl SkeletonHorse {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -6627,7 +6627,7 @@ impl Default for SkeletonHorseMetadataBundle {
pub struct Slime;
impl Slime {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -6696,7 +6696,7 @@ pub struct SmallFireballItemStack(pub Slot);
pub struct SmallFireball;
impl SmallFireball {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -6748,7 +6748,7 @@ pub struct HasPumpkin(pub bool);
pub struct SnowGolem;
impl SnowGolem {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -6821,7 +6821,7 @@ pub struct SnowballItemStack(pub Slot);
pub struct Snowball;
impl Snowball {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -6871,7 +6871,7 @@ impl Default for SnowballMetadataBundle {
pub struct SpawnerMinecart;
impl SpawnerMinecart {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -6933,7 +6933,7 @@ pub struct SpectralArrowPierceLevel(pub u8);
pub struct SpectralArrow;
impl SpectralArrow {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -6995,7 +6995,7 @@ impl Default for SpectralArrowMetadataBundle {
pub struct Spider;
impl Spider {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -7069,7 +7069,7 @@ impl Default for SpiderMetadataBundle {
pub struct Squid;
impl Squid {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -7134,7 +7134,7 @@ impl Default for SquidMetadataBundle {
pub struct Stray;
impl Stray {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -7208,7 +7208,7 @@ pub struct StriderSaddle(pub bool);
pub struct Strider;
impl Strider {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -7297,7 +7297,7 @@ pub struct TadpoleFromBucket(pub bool);
pub struct Tadpole;
impl Tadpole {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -7369,7 +7369,7 @@ pub struct Fuse(pub i32);
pub struct Tnt;
impl Tnt {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -7419,7 +7419,7 @@ impl Default for TntMetadataBundle {
pub struct TntMinecart;
impl TntMinecart {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -7473,7 +7473,7 @@ impl Default for TntMinecartMetadataBundle {
pub struct TraderLlama;
impl TraderLlama {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -7570,7 +7570,7 @@ pub struct Foil(pub bool);
pub struct Trident;
impl Trident {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -7646,7 +7646,7 @@ pub struct TropicalFishTypeVariant(pub i32);
pub struct TropicalFish;
impl TropicalFish {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -7733,7 +7733,7 @@ pub struct Travelling(pub bool);
pub struct Turtle;
impl Turtle {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -7837,7 +7837,7 @@ pub struct VexFlags(pub u8);
pub struct Vex;
impl Vex {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -7914,7 +7914,7 @@ pub struct VillagerVillagerData(pub VillagerData);
pub struct Villager;
impl Villager {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -7999,7 +7999,7 @@ pub struct VindicatorIsCelebrating(pub bool);
pub struct Vindicator;
impl Vindicator {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -8074,7 +8074,7 @@ pub struct WanderingTraderUnhappyCounter(pub i32);
pub struct WanderingTrader;
impl WanderingTrader {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -8150,7 +8150,7 @@ pub struct ClientAngerLevel(pub i32);
pub struct Warden;
impl Warden {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -8227,7 +8227,7 @@ pub struct WitchUsingItem(pub bool);
pub struct Witch;
impl Witch {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -8313,7 +8313,7 @@ pub struct Inv(pub i32);
pub struct Wither;
impl Wither {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -8401,7 +8401,7 @@ impl Default for WitherMetadataBundle {
pub struct WitherSkeleton;
impl WitherSkeleton {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -8471,7 +8471,7 @@ pub struct Dangerous(pub bool);
pub struct WitherSkull;
impl WitherSkull {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -8527,7 +8527,7 @@ pub struct WolfRemainingAngerTime(pub i32);
pub struct Wolf;
impl Wolf {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -8622,7 +8622,7 @@ pub struct ZoglinBaby(pub bool);
pub struct Zoglin;
impl Zoglin {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -8695,7 +8695,7 @@ impl Default for ZoglinMetadataBundle {
pub struct Zombie;
impl Zombie {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -8790,7 +8790,7 @@ pub struct ZombieHorseOwnerUuid(pub Option<Uuid>);
pub struct ZombieHorse;
impl ZombieHorse {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -8889,7 +8889,7 @@ pub struct ZombieVillagerVillagerData(pub VillagerData);
pub struct ZombieVillager;
impl ZombieVillager {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -8977,7 +8977,7 @@ impl Default for ZombieVillagerMetadataBundle {
pub struct ZombifiedPiglin;
impl ZombifiedPiglin {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -9051,7 +9051,7 @@ impl Default for ZombifiedPiglinMetadataBundle {
pub struct AbstractAgeable;
impl AbstractAgeable {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -9121,7 +9121,7 @@ impl Default for AbstractAgeableMetadataBundle {
pub struct AbstractAnimal;
impl AbstractAnimal {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -9190,7 +9190,7 @@ impl Default for AbstractAnimalMetadataBundle {
pub struct AbstractCreature;
impl AbstractCreature {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -9252,7 +9252,7 @@ impl Default for AbstractCreatureMetadataBundle {
pub struct AbstractEntity;
impl AbstractEntity {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -9337,7 +9337,7 @@ impl Default for AbstractEntityMetadataBundle {
pub struct AbstractInsentient;
impl AbstractInsentient {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -9405,7 +9405,7 @@ impl Default for AbstractInsentientMetadataBundle {
pub struct AbstractLiving;
impl AbstractLiving {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -9489,7 +9489,7 @@ impl Default for AbstractLivingMetadataBundle {
pub struct AbstractMinecart;
impl AbstractMinecart {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -9564,7 +9564,7 @@ impl Default for AbstractMinecartMetadataBundle {
pub struct AbstractMonster;
impl AbstractMonster {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -9629,7 +9629,7 @@ impl Default for AbstractMonsterMetadataBundle {
pub struct AbstractTameable;
impl AbstractTameable {
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
d: EntityDataItem,
) -> Result<(), UpdateMetadataError> {
match d.index {
@@ -9712,7 +9712,7 @@ impl Default for AbstractTameableMetadataBundle {
}
pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
entity_kind: azalea_registry::EntityKind,
items: Vec<EntityDataItem>,
) -> Result<(), UpdateMetadataError> {
@@ -10317,7 +10317,7 @@ pub fn apply_metadata(
}
pub fn apply_default_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
kind: azalea_registry::EntityKind,
) {
match kind {
diff --git a/azalea-world/src/entity/mod.rs b/azalea-world/src/entity/mod.rs
index 9b1191fb..6f77f1be 100644
--- a/azalea-world/src/entity/mod.rs
+++ b/azalea-world/src/entity/mod.rs
@@ -12,7 +12,7 @@ use self::{attributes::AttributeInstance, metadata::Health};
pub use attributes::Attributes;
use azalea_block::BlockState;
use azalea_core::{BlockPos, ChunkPos, ResourceLocation, Vec3, AABB};
-use azalea_ecs::{
+use bevy_ecs::{
bundle::Bundle,
component::Component,
entity::Entity,
@@ -22,7 +22,9 @@ use azalea_ecs::{
pub use data::*;
use derive_more::{Deref, DerefMut};
pub use dimensions::{update_bounding_box, EntityDimensions};
-pub use info::{EntityInfos, EntityPlugin, LoadedBy, PartialEntityInfos, RelativeEntityUpdate};
+pub use info::{
+ EntityInfos, EntityPlugin, EntityUpdateSet, LoadedBy, PartialEntityInfos, RelativeEntityUpdate,
+};
use std::fmt::Debug;
use uuid::Uuid;
diff --git a/azalea-world/src/world.rs b/azalea-world/src/world.rs
index 8f1b2179..41d83082 100644
--- a/azalea-world/src/world.rs
+++ b/azalea-world/src/world.rs
@@ -5,7 +5,7 @@ use crate::{
ChunkStorage, PartialChunkStorage, WorldContainer,
};
use azalea_core::ChunkPos;
-use azalea_ecs::{
+use bevy_ecs::{
entity::Entity,
query::{Changed, With, Without},
system::{Commands, Query, Res, ResMut},
@@ -172,7 +172,7 @@ pub fn update_uuid_index(
/// A world where the chunks are stored as weak pointers. This is used for
/// shared worlds.
#[derive(Default, Debug)]
-pub struct World {
+pub struct Instance {
pub chunks: ChunkStorage,
/// An index of all the entities we know are in the chunks of the world
@@ -182,7 +182,7 @@ pub struct World {
pub entity_by_id: IntMap<MinecraftEntityId, Entity>,
}
-impl World {
+impl Instance {
/// Get an ECS [`Entity`] from a Minecraft entity ID.
pub fn entity_by_id(&self, entity_id: &MinecraftEntityId) -> Option<Entity> {
self.entity_by_id.get(entity_id).copied()
@@ -236,7 +236,7 @@ pub fn update_entity_by_id_index(
}
}
-impl From<ChunkStorage> for World {
+impl From<ChunkStorage> for Instance {
/// Make an empty world from this `ChunkStorage`. This is meant to be a
/// convenience function for tests.
fn from(chunks: ChunkStorage) -> Self {
diff --git a/azalea/Cargo.toml b/azalea/Cargo.toml
index f64959ed..dd2bb46c 100644
--- a/azalea/Cargo.toml
+++ b/azalea/Cargo.toml
@@ -8,31 +8,31 @@ version = "0.6.0"
[package.metadata.release]
pre-release-replacements = [
- {file = "README.md", search = "`azalea = \"[a-z0-9\\.-]+\"`", replace = "`azalea = \"{{version}}\"`"},
+ { file = "README.md", search = "`azalea = \"[a-z0-9\\.-]+\"`", replace = "`azalea = \"{{version}}\"`" },
]
[dependencies]
anyhow = "^1.0.65"
async-trait = "0.1.58"
-azalea-block = {version = "0.6.0", path = "../azalea-block"}
-azalea-chat = {version = "0.6.0", path = "../azalea-chat"}
-azalea-client = {version = "0.6.0", path = "../azalea-client"}
-azalea-core = {version = "0.6.0", path = "../azalea-core"}
-azalea-ecs = {version = "0.6.0", path = "../azalea-ecs"}
-azalea-physics = {version = "0.6.0", path = "../azalea-physics"}
-azalea-protocol = {version = "0.6.0", path = "../azalea-protocol"}
-azalea-registry = {version = "0.6.0", path = "../azalea-registry"}
-azalea-world = {version = "0.6.0", path = "../azalea-world"}
-bevy_tasks = "0.9.1"
-derive_more = {version = "0.99.17", features = ["deref", "deref_mut"]}
+azalea-block = { version = "0.6.0", path = "../azalea-block" }
+azalea-chat = { version = "0.6.0", path = "../azalea-chat" }
+azalea-client = { version = "0.6.0", path = "../azalea-client" }
+azalea-core = { version = "0.6.0", path = "../azalea-core" }
+azalea-physics = { version = "0.6.0", path = "../azalea-physics" }
+azalea-protocol = { version = "0.6.0", path = "../azalea-protocol" }
+azalea-registry = { version = "0.6.0", path = "../azalea-registry" }
+azalea-world = { version = "0.6.0", path = "../azalea-world" }
+bevy_app = "0.10.0"
+bevy_ecs = "0.10.0"
+bevy_tasks = "0.10.0"
+derive_more = { version = "0.99.17", features = ["deref", "deref_mut"] }
futures = "0.3.25"
futures-lite = "1.12.0"
log = "0.4.17"
nohash-hasher = "0.2.0"
num-traits = "0.2.15"
-parking_lot = {version = "^0.12.1", features = ["deadlock_detection"]}
+parking_lot = { version = "^0.12.1", features = ["deadlock_detection"] }
priority-queue = "1.3.0"
thiserror = "^1.0.37"
tokio = "^1.24.2"
uuid = "1.2.2"
-
diff --git a/azalea/examples/pvp.rs b/azalea/examples/pvp.rs
index 180b6577..fb5a768d 100755
--- a/azalea/examples/pvp.rs
+++ b/azalea/examples/pvp.rs
@@ -1,9 +1,9 @@
use std::time::Duration;
+use azalea::ecs::query::With;
use azalea::entity::metadata::Player;
use azalea::{pathfinder, Account, Client, Event, GameProfileComponent};
use azalea::{prelude::*, swarm::prelude::*};
-use azalea_ecs::query::With;
#[tokio::main]
async fn main() {
diff --git a/azalea/examples/testbot.rs b/azalea/examples/testbot.rs
index dd1629ae..7b7b32b0 100644
--- a/azalea/examples/testbot.rs
+++ b/azalea/examples/testbot.rs
@@ -52,17 +52,17 @@ async fn main() -> anyhow::Result<()> {
}
loop {
- let e = SwarmBuilder::new()
- .add_accounts(accounts.clone())
- .set_handler(handle)
- .set_swarm_handler(swarm_handle)
- .join_delay(Duration::from_millis(1000))
- .start("localhost")
- .await;
- // let e = azalea::ClientBuilder::new()
+ // let e = SwarmBuilder::new()
+ // .add_accounts(accounts.clone())
// .set_handler(handle)
- // .start(Account::offline("bot"), "localhost")
+ // .set_swarm_handler(swarm_handle)
+ // .join_delay(Duration::from_millis(1000))
+ // .start("localhost")
// .await;
+ let e = azalea::ClientBuilder::new()
+ .set_handler(handle)
+ .start(Account::offline("bot"), "localhost")
+ .await;
eprintln!("{e:?}");
}
}
diff --git a/azalea/src/bot.rs b/azalea/src/bot.rs
index ce5b9fdc..a45ae28d 100644
--- a/azalea/src/bot.rs
+++ b/azalea/src/bot.rs
@@ -1,14 +1,14 @@
-use azalea_core::Vec3;
-use azalea_ecs::{
- app::{App, Plugin, PluginGroup, PluginGroupBuilder},
+use crate::app::{App, CoreSchedule, IntoSystemAppConfig, Plugin, PluginGroup, PluginGroupBuilder};
+use crate::ecs::{
component::Component,
entity::Entity,
event::EventReader,
query::{With, Without},
- schedule::IntoSystemDescriptor,
+ schedule::IntoSystemConfig,
system::{Commands, Query},
- AppTickExt,
};
+use azalea_core::Vec3;
+use azalea_physics::{force_jump_listener, PhysicsSet};
use azalea_world::entity::{metadata::Player, set_rotation, Jumping, Local, Physics, Position};
use std::f64::consts::PI;
@@ -20,14 +20,14 @@ impl Plugin for BotPlugin {
fn build(&self, app: &mut App) {
app.add_event::<LookAtEvent>()
.add_event::<JumpEvent>()
- .add_system(insert_bot)
- .add_system(
- look_at_listener
- .before("force_jump_listener")
- .before(azalea_world::entity::update_bounding_box),
- )
- .add_system(jump_listener.label("jump_listener"))
- .add_tick_system(stop_jumping.after("ai_step"));
+ .add_systems((
+ insert_bot,
+ look_at_listener.before(force_jump_listener),
+ jump_listener,
+ stop_jumping
+ .in_schedule(CoreSchedule::FixedUpdate)
+ .after(PhysicsSet),
+ ));
}
}
diff --git a/azalea/src/lib.rs b/azalea/src/lib.rs
index 827c3904..c58ca7b1 100644
--- a/azalea/src/lib.rs
+++ b/azalea/src/lib.rs
@@ -6,18 +6,15 @@ pub mod pathfinder;
pub mod prelude;
pub mod swarm;
+use app::{App, Plugin, PluginGroup};
pub use azalea_block as blocks;
pub use azalea_client::*;
pub use azalea_core::{BlockPos, Vec3};
-use azalea_ecs::{
- app::{App, Plugin},
- component::Component,
-};
pub use azalea_protocol as protocol;
pub use azalea_registry::EntityKind;
-pub use azalea_world::{entity, World};
+pub use azalea_world::{entity, Instance};
use bot::DefaultBotPlugins;
-use ecs::app::PluginGroup;
+use ecs::component::Component;
use futures::Future;
use protocol::{
resolver::{self, ResolverError},
@@ -26,7 +23,10 @@ use protocol::{
use thiserror::Error;
use tokio::sync::mpsc;
-pub type HandleFn<Fut, S> = fn(Client, Event, S) -> Fut;
+pub use bevy_app as app;
+pub use bevy_ecs as ecs;
+
+pub type HandleFn<Fut, S> = fn(Client, azalea_client::Event, S) -> Fut;
#[derive(Error, Debug)]
pub enum StartError {
@@ -142,6 +142,7 @@ where
// An event that causes the schedule to run. This is only used internally.
let (run_schedule_sender, run_schedule_receiver) = mpsc::unbounded_channel();
+
let ecs_lock = start_ecs(self.app, run_schedule_receiver, run_schedule_sender.clone());
let (bot, mut rx) = Client::start_client(
diff --git a/azalea/src/pathfinder/mod.rs b/azalea/src/pathfinder/mod.rs
index 8289d9c4..61a92038 100644
--- a/azalea/src/pathfinder/mod.rs
+++ b/azalea/src/pathfinder/mod.rs
@@ -4,18 +4,18 @@ mod mtdstarlite;
use crate::bot::{JumpEvent, LookAtEvent};
use crate::{SprintDirection, WalkDirection};
-use azalea_client::{StartSprintEvent, StartWalkEvent};
-use azalea_core::{BlockPos, CardinalDirection};
-use azalea_ecs::{
- app::{App, Plugin},
+use crate::app::{App, CoreSchedule, IntoSystemAppConfig, Plugin};
+use crate::ecs::{
component::Component,
entity::Entity,
event::{EventReader, EventWriter},
query::{With, Without},
- schedule::IntoSystemDescriptor,
+ schedule::IntoSystemConfig,
system::{Commands, Query, Res},
- AppTickExt,
};
+use azalea_client::{StartSprintEvent, StartWalkEvent};
+use azalea_core::{BlockPos, CardinalDirection};
+use azalea_physics::PhysicsSet;
use azalea_world::entity::metadata::Player;
use azalea_world::entity::Local;
use azalea_world::{
@@ -36,7 +36,13 @@ impl Plugin for PathfinderPlugin {
fn build(&self, app: &mut App) {
app.add_event::<GotoEvent>()
.add_event::<PathFoundEvent>()
- .add_tick_system(tick_execute_path.before("ai_step"))
+ .add_system(
+ // Adding `.in_schedule(CoreSchedule::FixedUpdate)` makes a system run every
+ // Minecraft tick (every 50 milliseconds).
+ tick_execute_path
+ .in_schedule(CoreSchedule::FixedUpdate)
+ .before(PhysicsSet),
+ )
.add_system(goto_listener)
.add_system(add_default_pathfinder)
.add_system(handle_tasks.before(path_found_listener))
diff --git a/azalea/src/pathfinder/moves.rs b/azalea/src/pathfinder/moves.rs
index 011d8349..3639c091 100644
--- a/azalea/src/pathfinder/moves.rs
+++ b/azalea/src/pathfinder/moves.rs
@@ -1,10 +1,10 @@
use super::{Node, VerticalVel};
use azalea_core::{BlockPos, CardinalDirection};
use azalea_physics::collision::{self, BlockWithShape};
-use azalea_world::World;
+use azalea_world::Instance;
/// whether this block is passable
-fn is_block_passable(pos: &BlockPos, world: &World) -> bool {
+fn is_block_passable(pos: &BlockPos, world: &Instance) -> bool {
if let Some(block) = world.chunks.get_block_state(pos) {
block.shape() == &collision::empty_shape()
} else {
@@ -13,7 +13,7 @@ fn is_block_passable(pos: &BlockPos, world: &World) -> bool {
}
/// whether this block has a solid hitbox (i.e. we can stand on it)
-fn is_block_solid(pos: &BlockPos, world: &World) -> bool {
+fn is_block_solid(pos: &BlockPos, world: &Instance) -> bool {
if let Some(block) = world.chunks.get_block_state(pos) {
block.shape() == &collision::block_shape()
} else {
@@ -22,14 +22,14 @@ fn is_block_solid(pos: &BlockPos, world: &World) -> bool {
}
/// Whether this block and the block above are passable
-fn is_passable(pos: &BlockPos, world: &World) -> bool {
+fn is_passable(pos: &BlockPos, world: &Instance) -> bool {
is_block_passable(pos, world) && is_block_passable(&pos.up(1), world)
}
/// Whether we can stand in this position. Checks if the block below is solid,
/// and that the two blocks above that are passable.
-fn is_standable(pos: &BlockPos, world: &World) -> bool {
+fn is_standable(pos: &BlockPos, world: &Instance) -> bool {
is_block_solid(&pos.down(1), world) && is_passable(pos, world)
}
@@ -37,7 +37,7 @@ const JUMP_COST: f32 = 0.5;
const WALK_ONE_BLOCK_COST: f32 = 1.0;
pub trait Move: Send + Sync {
- fn cost(&self, world: &World, node: &Node) -> f32;
+ fn cost(&self, world: &Instance, node: &Node) -> f32;
/// Returns by how much the entity's position should be changed when this
/// move is executed.
fn offset(&self) -> BlockPos;
@@ -51,7 +51,7 @@ pub trait Move: Send + Sync {
pub struct ForwardMove(pub CardinalDirection);
impl Move for ForwardMove {
- fn cost(&self, world: &World, node: &Node) -> f32 {
+ fn cost(&self, world: &Instance, node: &Node) -> f32 {
if is_standable(&(node.pos + self.offset()), world)
&& node.vertical_vel == VerticalVel::None
{
@@ -67,7 +67,7 @@ impl Move for ForwardMove {
pub struct AscendMove(pub CardinalDirection);
impl Move for AscendMove {
- fn cost(&self, world: &World, node: &Node) -> f32 {
+ fn cost(&self, world: &Instance, node: &Node) -> f32 {
if node.vertical_vel == VerticalVel::None
&& is_block_passable(&node.pos.up(2), world)
&& is_standable(&(node.pos + self.offset()), world)
@@ -89,7 +89,7 @@ impl Move for AscendMove {
}
pub struct DescendMove(pub CardinalDirection);
impl Move for DescendMove {
- fn cost(&self, world: &World, node: &Node) -> f32 {
+ fn cost(&self, world: &Instance, node: &Node) -> f32 {
// check whether 3 blocks vertically forward are passable
if node.vertical_vel == VerticalVel::None
&& is_standable(&(node.pos + self.offset()), world)
@@ -112,7 +112,7 @@ impl Move for DescendMove {
}
pub struct DiagonalMove(pub CardinalDirection);
impl Move for DiagonalMove {
- fn cost(&self, world: &World, node: &Node) -> f32 {
+ fn cost(&self, world: &Instance, node: &Node) -> f32 {
if node.vertical_vel != VerticalVel::None {
return f32::INFINITY;
}
diff --git a/azalea/src/prelude.rs b/azalea/src/prelude.rs
index a9ae6093..b1a1fed3 100644
--- a/azalea/src/prelude.rs
+++ b/azalea/src/prelude.rs
@@ -3,4 +3,6 @@
pub use crate::{bot::BotClientExt, pathfinder::PathfinderClientExt, ClientBuilder};
pub use azalea_client::{Account, Client, Event};
-pub use azalea_ecs::{component::Component, system::Resource};
+// this is necessary to make the macros that reference bevy_ecs work
+pub use crate::ecs as bevy_ecs;
+pub use crate::ecs::{component::Component, system::Resource};
diff --git a/azalea/src/swarm/chat.rs b/azalea/src/swarm/chat.rs
index 18c27cd6..303ce35b 100644
--- a/azalea/src/swarm/chat.rs
+++ b/azalea/src/swarm/chat.rs
@@ -13,14 +13,14 @@
// in Swarm that's set to the smallest index of all the bots, and we remove all
// messages from the queue that are before that index.
-use azalea_client::chat::{ChatPacket, ChatReceivedEvent};
-use azalea_ecs::{
- app::{App, Plugin},
+use crate::ecs::{
component::Component,
event::{EventReader, EventWriter},
- schedule::IntoSystemDescriptor,
+ schedule::IntoSystemConfigs,
system::{Commands, Query, Res, ResMut, Resource},
};
+use azalea_client::chat::{ChatPacket, ChatReceivedEvent};
+use bevy_app::{App, Plugin};
use std::collections::VecDeque;
use super::{Swarm, SwarmEvent};
@@ -30,8 +30,7 @@ pub struct SwarmChatPlugin;
impl Plugin for SwarmChatPlugin {
fn build(&self, app: &mut App) {
app.add_event::<NewChatMessageEvent>()
- .add_system(chat_listener.label("chat_listener"))
- .add_system(update_min_index_and_shrink_queue.after("chat_listener"))
+ .add_systems((chat_listener, update_min_index_and_shrink_queue).chain())
.insert_resource(GlobalChatState {
chat_queue: VecDeque::new(),
chat_min_index: 0,
@@ -151,7 +150,7 @@ fn update_min_index_and_shrink_queue(
#[cfg(test)]
mod tests {
- use azalea_ecs::{ecs::Ecs, event::Events, system::SystemState};
+ use bevy_ecs::{event::Events, prelude::World, system::SystemState};
use super::*;
@@ -161,8 +160,7 @@ mod tests {
// event mangement in drain_events
app.init_resource::<Events<ChatReceivedEvent>>()
.init_resource::<Events<NewChatMessageEvent>>()
- .add_system(chat_listener.label("chat_listener"))
- .add_system(update_min_index_and_shrink_queue.after("chat_listener"))
+ .add_systems((chat_listener, update_min_index_and_shrink_queue).chain())
.insert_resource(GlobalChatState {
chat_queue: VecDeque::new(),
chat_min_index: 0,
@@ -170,7 +168,7 @@ mod tests {
app
}
- fn drain_events(ecs: &mut Ecs) -> Vec<ChatPacket> {
+ fn drain_events(ecs: &mut World) -> Vec<ChatPacket> {
let mut system_state: SystemState<ResMut<Events<NewChatMessageEvent>>> =
SystemState::new(ecs);
let mut events = system_state.get_mut(ecs);
diff --git a/azalea/src/swarm/events.rs b/azalea/src/swarm/events.rs
index 81d8c731..62593029 100644
--- a/azalea/src/swarm/events.rs
+++ b/azalea/src/swarm/events.rs
@@ -1,11 +1,7 @@
use azalea_client::LocalPlayer;
-use azalea_ecs::{
- app::{App, Plugin},
- event::EventWriter,
- query::With,
- system::{Query, ResMut, Resource},
-};
use azalea_world::entity::MinecraftEntityId;
+use bevy_app::{App, Plugin};
+use bevy_ecs::prelude::*;
use derive_more::{Deref, DerefMut};
pub struct SwarmPlugin;
diff --git a/azalea/src/swarm/mod.rs b/azalea/src/swarm/mod.rs
index c0d9cb56..97020153 100644
--- a/azalea/src/swarm/mod.rs
+++ b/azalea/src/swarm/mod.rs
@@ -6,19 +6,14 @@ pub mod prelude;
use crate::{bot::DefaultBotPlugins, HandleFn};
use azalea_client::{chat::ChatPacket, init_ecs_app, start_ecs, Account, Client, Event, JoinError};
-use azalea_ecs::{
- app::{App, Plugin, PluginGroup, PluginGroupBuilder},
- component::Component,
- ecs::Ecs,
- entity::Entity,
- system::Resource,
-};
use azalea_protocol::{
connect::ConnectionError,
resolver::{self, ResolverError},
ServerAddress,
};
use azalea_world::WorldContainer;
+use bevy_app::{App, Plugin, PluginGroup, PluginGroupBuilder};
+use bevy_ecs::{component::Component, entity::Entity, system::Resource, world::World};
use futures::future::join_all;
use log::error;
use parking_lot::{Mutex, RwLock};
@@ -35,7 +30,7 @@ use tokio::sync::mpsc;
/// It's used to make the [`Swarm::add`] function work.
#[derive(Clone, Resource)]
pub struct Swarm {
- pub ecs_lock: Arc<Mutex<Ecs>>,
+ pub ecs_lock: Arc<Mutex<World>>,
bots: Arc<Mutex<HashMap<Entity, Client>>>,
diff --git a/codegen/lib/code/entity.py b/codegen/lib/code/entity.py
index 250b7e70..e3e88edf 100644
--- a/codegen/lib/code/entity.py
+++ b/codegen/lib/code/entity.py
@@ -46,7 +46,7 @@ use super::{EntityDataItem, EntityDataValue, OptionalUnsignedInt, Pose, Rotation
use azalea_block::BlockState;
use azalea_chat::FormattedText;
use azalea_core::{BlockPos, Direction, Particle, Slot};
-use azalea_ecs::{bundle::Bundle, component::Component};
+use bevy_ecs::{bundle::Bundle, component::Component};
use derive_more::{Deref, DerefMut};
use thiserror::Error;
use uuid::Uuid;
@@ -183,7 +183,7 @@ impl From<EntityDataValue> for UpdateMetadataError {
# impl Allay {
# pub fn apply_metadata(
- # entity: &mut azalea_ecs::system::EntityCommands,
+ # entity: &mut bevy_ecs::system::EntityCommands,
# d: EntityDataItem,
# ) -> Result<(), UpdateMetadataError> {
# match d.index {
@@ -196,7 +196,7 @@ impl From<EntityDataValue> for UpdateMetadataError {
# }
code.append(f'impl {struct_name} {{')
code.append(
- f' pub fn apply_metadata(entity: &mut azalea_ecs::system::EntityCommands, d: EntityDataItem) -> Result<(), UpdateMetadataError> {{')
+ f' pub fn apply_metadata(entity: &mut bevy_ecs::system::EntityCommands, d: EntityDataItem) -> Result<(), UpdateMetadataError> {{')
code.append(f' match d.index {{')
parent_last_index = -1
@@ -400,7 +400,7 @@ impl From<EntityDataValue> for UpdateMetadataError {
# and now make the main apply_metadata
# pub fn apply_metadata(
- # entity: &mut azalea_ecs::system::EntityCommands,
+ # entity: &mut bevy_ecs::system::EntityCommands,
# items: Vec<EntityDataItem>,
# ) -> Result<(), UpdateMetadataError> {
# if entity.contains::<Allay>() {
@@ -414,7 +414,7 @@ impl From<EntityDataValue> for UpdateMetadataError {
# }
code.append(
f'''pub fn apply_metadata(
- entity: &mut azalea_ecs::system::EntityCommands,
+ entity: &mut bevy_ecs::system::EntityCommands,
entity_kind: azalea_registry::EntityKind,
items: Vec<EntityDataItem>,
) -> Result<(), UpdateMetadataError> {{
@@ -436,7 +436,7 @@ impl From<EntityDataValue> for UpdateMetadataError {
code.append('}')
code.append('')
- # pub fn apply_default_metadata(entity: &mut azalea_ecs::system::EntityCommands, kind: azalea_registry::EntityKind) {
+ # pub fn apply_default_metadata(entity: &mut bevy_ecs::system::EntityCommands, kind: azalea_registry::EntityKind) {
# match kind {
# azalea_registry::EntityKind::AreaEffectCloud => {
# entity.insert(AreaEffectCloudMetadataBundle::default());
@@ -444,7 +444,7 @@ impl From<EntityDataValue> for UpdateMetadataError {
# }
# }
code.append(
- 'pub fn apply_default_metadata(entity: &mut azalea_ecs::system::EntityCommands, kind: azalea_registry::EntityKind) {')
+ 'pub fn apply_default_metadata(entity: &mut bevy_ecs::system::EntityCommands, kind: azalea_registry::EntityKind) {')
code.append(' match kind {')
for entity_id in burger_entity_data:
if entity_id.startswith('~'):