Make CSS and SSS reach a match

This commit is contained in:
2026-09-11 22:01:16 +02:00
parent f3701bd8b0
commit 74a635785e
16 changed files with 487 additions and 531 deletions
Generated
+40 -380
View File
@@ -24,8 +24,6 @@ version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3b7f7f85a7e5f68090000ed7622545829afd484d210358702ae4cb97dd0c320" checksum = "d3b7f7f85a7e5f68090000ed7622545829afd484d210358702ae4cb97dd0c320"
dependencies = [ dependencies = [
"enumn",
"serde",
"uuid", "uuid",
] ]
@@ -133,9 +131,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]] [[package]]
name = "alsa" name = "alsa"
version = "0.11.0" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "812947049edcd670a82cd5c73c3661d2e58468577ba8489de58e1a73c04cbd5d" checksum = "7c88dbbce13b232b26250e1e2e6ac18b6a891a646b8148285036ebce260ac5c3"
dependencies = [ dependencies = [
"alsa-sys", "alsa-sys",
"bitflags 2.13.1", "bitflags 2.13.1",
@@ -145,9 +143,9 @@ dependencies = [
[[package]] [[package]]
name = "alsa-sys" name = "alsa-sys"
version = "0.4.0" version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad7569085a265dd3f607ebecce7458eaab2132a84393534c95b18dcbc3f31e04" checksum = "db8fee663d06c4e303404ef5f40488a53e062f89ba8bfed81f42325aafad1527"
dependencies = [ dependencies = [
"libc", "libc",
"pkg-config", "pkg-config",
@@ -308,15 +306,6 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b"
[[package]]
name = "ascii-canvas"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef1e3e699d84ab1b0911a1010c5c106aa34ae89aeac103be5ce0c3859db1e891"
dependencies = [
"term",
]
[[package]] [[package]]
name = "ash" name = "ash"
version = "0.38.0+1.3.281" version = "0.38.0+1.3.281"
@@ -596,7 +585,6 @@ dependencies = [
"bevy_derive", "bevy_derive",
"bevy_ecs", "bevy_ecs",
"bevy_reflect", "bevy_reflect",
"serde",
] ]
[[package]] [[package]]
@@ -632,7 +620,7 @@ dependencies = [
"downcast-rs 2.0.2", "downcast-rs 2.0.2",
"either", "either",
"petgraph", "petgraph",
"ron 0.12.2", "ron",
"serde", "serde",
"smallvec", "smallvec",
"thiserror 2.0.19", "thiserror 2.0.19",
@@ -729,7 +717,7 @@ dependencies = [
"futures-util", "futures-util",
"js-sys", "js-sys",
"notify-debouncer-full", "notify-debouncer-full",
"ron 0.12.2", "ron",
"serde", "serde",
"stackfuture", "stackfuture",
"thiserror 2.0.19", "thiserror 2.0.19",
@@ -873,21 +861,6 @@ dependencies = [
"wgpu-types", "wgpu-types",
] ]
[[package]]
name = "bevy_common_assets"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b9a9509ff29e5db89e1697c047fbbdc55208c8c3d07a494b013cc96814fcddb"
dependencies = [
"anyhow",
"bevy_app",
"bevy_asset",
"bevy_reflect",
"ron 0.11.0",
"serde",
"thiserror 2.0.19",
]
[[package]] [[package]]
name = "bevy_core_pipeline" name = "bevy_core_pipeline"
version = "0.19.0" version = "0.19.0"
@@ -1311,7 +1284,6 @@ dependencies = [
"bevy_reflect", "bevy_reflect",
"derive_more", "derive_more",
"log", "log",
"serde",
"smol_str", "smol_str",
"thiserror 2.0.19", "thiserror 2.0.19",
] ]
@@ -1527,7 +1499,6 @@ dependencies = [
"glam 0.32.1", "glam 0.32.1",
"half", "half",
"hexasphere", "hexasphere",
"serde",
"thiserror 2.0.19", "thiserror 2.0.19",
"tracing", "tracing",
"wgpu-types", "wgpu-types",
@@ -2026,7 +1997,6 @@ dependencies = [
"bevy_window", "bevy_window",
"derive_more", "derive_more",
"parley", "parley",
"serde",
"smallvec", "smallvec",
"swash", "swash",
"taffy", "taffy",
@@ -2181,7 +2151,7 @@ dependencies = [
"bevy_transform", "bevy_transform",
"bevy_utils", "bevy_utils",
"derive_more", "derive_more",
"ron 0.12.2", "ron",
"serde", "serde",
"thiserror 2.0.19", "thiserror 2.0.19",
"uuid", "uuid",
@@ -2294,16 +2264,7 @@ dependencies = [
"cc", "cc",
"cfg-if", "cfg-if",
"constant_time_eq", "constant_time_eq",
"cpufeatures 0.3.0", "cpufeatures",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
] ]
[[package]] [[package]]
@@ -2471,16 +2432,6 @@ dependencies = [
"shlex", "shlex",
] ]
[[package]]
name = "cdt"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b91b872294f63ef586b32aa94141561681aa35ca2d703960cca4f661f4e18184"
dependencies = [
"geometry-predicates",
"thiserror 1.0.69",
]
[[package]] [[package]]
name = "cesu8" name = "cesu8"
version = "1.1.0" version = "1.1.0"
@@ -2767,11 +2718,11 @@ dependencies = [
[[package]] [[package]]
name = "coreaudio-rs" name = "coreaudio-rs"
version = "0.14.2" version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d5d7dca3ebcf65a035582c9ad4385371a9d9ee6537474d2a278f4e1e475bb58" checksum = "1aae284fbaf7d27aa0e292f7677dfbe26503b0d555026f702940805a630eac17"
dependencies = [ dependencies = [
"bitflags 2.13.1", "bitflags 1.3.2",
"libc", "libc",
"objc2-audio-toolbox", "objc2-audio-toolbox",
"objc2-core-audio", "objc2-core-audio",
@@ -2781,9 +2732,9 @@ dependencies = [
[[package]] [[package]]
name = "cpal" name = "cpal"
version = "0.17.3" version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8942da362c0f0d895d7cac616263f2f9424edc5687364dfd1d25ef7eba506d7" checksum = "5b1f9c7312f19fc2fa12fd7acaf38de54e8320ba10d1a02dcbe21038def51ccb"
dependencies = [ dependencies = [
"alsa", "alsa",
"coreaudio-rs", "coreaudio-rs",
@@ -2809,15 +2760,6 @@ dependencies = [
"windows", "windows",
] ]
[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.3.0" version = "0.3.0"
@@ -2927,16 +2869,6 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
[[package]]
name = "crypto-common"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
dependencies = [
"generic-array",
"typenum",
]
[[package]] [[package]]
name = "ctrlc" name = "ctrlc"
version = "3.5.2" version = "3.5.2"
@@ -2989,16 +2921,6 @@ dependencies = [
"unicode-xid", "unicode-xid",
] ]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]] [[package]]
name = "dispatch" name = "dispatch"
version = "0.2.0" version = "0.2.0"
@@ -3070,16 +2992,6 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76"
[[package]]
name = "earcutr"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afc28d89ac6cb489f679fcf51aaa62b4667bb0fb73a30f1d4d23949069707c07"
dependencies = [
"itertools 0.14.0",
"num-traits",
]
[[package]] [[package]]
name = "ecolor" name = "ecolor"
version = "0.34.3" version = "0.34.3"
@@ -3180,17 +3092,6 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "enumn"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.119",
]
[[package]] [[package]]
name = "epaint" name = "epaint"
version = "0.34.3" version = "0.34.3"
@@ -3542,7 +3443,6 @@ dependencies = [
"bevy", "bevy",
"bevy-inspector-egui", "bevy-inspector-egui",
"bevy_asset_loader", "bevy_asset_loader",
"bevy_common_assets",
"bevy_egui", "bevy_egui",
"bevy_ggrs", "bevy_ggrs",
"bevy_wind_waker_shader", "bevy_wind_waker_shader",
@@ -3554,13 +3454,14 @@ dependencies = [
"fixed", "fixed",
"gc-adapter-neo", "gc-adapter-neo",
"gltf", "gltf",
"jackdaw_runtime",
"rhai", "rhai",
"ron 0.12.2", "ron",
"ron_asset_manager",
"serde", "serde",
"serde_json", "serde_json",
"strum", "strum",
"strum_macros", "strum_macros",
"thiserror 2.0.19",
] ]
[[package]] [[package]]
@@ -3574,22 +3475,6 @@ dependencies = [
"rusb", "rusb",
] ]
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "geometry-predicates"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8dba84198cf199c11b83f1cb9243eaeb70dc50b719d2835ebf34bf2481bca010"
[[package]] [[package]]
name = "gethostname" name = "gethostname"
version = "1.1.0" version = "1.1.0"
@@ -3872,7 +3757,6 @@ dependencies = [
"cfg-if", "cfg-if",
"crunchy", "crunchy",
"num-traits", "num-traits",
"serde",
"zerocopy", "zerocopy",
] ]
@@ -4249,89 +4133,6 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "jackdaw_avian_integration"
version = "0.19.0"
dependencies = [
"avian3d",
"bevy",
"jackdaw_geometry",
"jackdaw_scene_types",
]
[[package]]
name = "jackdaw_bsn"
version = "0.19.0"
dependencies = [
"bevy",
"lalrpop",
"lalrpop-util",
"log",
"nom",
"pathdiff",
"thiserror 2.0.19",
]
[[package]]
name = "jackdaw_geometry"
version = "0.19.0"
dependencies = [
"bevy",
"bitflags 2.13.1",
"cdt",
"earcutr",
"glam 0.32.1",
"serde",
"slotmap",
]
[[package]]
name = "jackdaw_runtime"
version = "0.19.0"
dependencies = [
"avian3d",
"bevy",
"jackdaw_avian_integration",
"jackdaw_bsn",
"jackdaw_geometry",
"jackdaw_scene_types",
"jackdaw_schema",
"jackdaw_ui",
"serde",
"serde_json",
"thiserror 2.0.19",
]
[[package]]
name = "jackdaw_scene_types"
version = "0.19.0"
dependencies = [
"bevy",
"glam 0.32.1",
"jackdaw_geometry",
"rand 0.9.5",
"serde",
"serde_json",
]
[[package]]
name = "jackdaw_schema"
version = "0.19.0"
dependencies = [
"bevy",
"jackdaw_scene_types",
"serde",
"serde_json",
]
[[package]]
name = "jackdaw_ui"
version = "0.19.0"
dependencies = [
"bevy",
"bevy_scene",
]
[[package]] [[package]]
name = "jni" name = "jni"
version = "0.21.1" version = "0.21.1"
@@ -4427,15 +4228,6 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "keccak"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653"
dependencies = [
"cpufeatures 0.2.17",
]
[[package]] [[package]]
name = "khronos-egl" name = "khronos-egl"
version = "6.0.0" version = "6.0.0"
@@ -4494,37 +4286,6 @@ dependencies = [
"smallvec", "smallvec",
] ]
[[package]]
name = "lalrpop"
version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98a80a963123205c7157323c99611bc4abb65dcbd62ef46dc4bac74a3941bc75"
dependencies = [
"ascii-canvas",
"bit-set",
"ena",
"itertools 0.14.0",
"lalrpop-util",
"petgraph",
"pico-args",
"regex",
"regex-syntax",
"sha3",
"string_cache",
"term",
"unicode-xid",
"walkdir",
]
[[package]]
name = "lalrpop-util"
version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "884f3e747ed2dcee867cda1b0c31a048f9e20de2d916a248949319921a2e666e"
dependencies = [
"regex-automata",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.5.0" version = "1.5.0"
@@ -4831,12 +4592,6 @@ dependencies = [
"jni-sys 0.3.1", "jni-sys 0.3.1",
] ]
[[package]]
name = "new_debug_unreachable"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
[[package]] [[package]]
name = "nix" name = "nix"
version = "0.31.3" version = "0.31.3"
@@ -4855,15 +4610,6 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
[[package]]
name = "nom"
version = "8.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "nonmax" name = "nonmax"
version = "0.5.5" version = "0.5.5"
@@ -5607,12 +5353,6 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42"
[[package]]
name = "pathdiff"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
[[package]] [[package]]
name = "peniko" name = "peniko"
version = "0.6.1" version = "0.6.1"
@@ -5645,21 +5385,6 @@ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]]
name = "phf_shared"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266"
dependencies = [
"siphasher",
]
[[package]]
name = "pico-args"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
[[package]] [[package]]
name = "pin-project" name = "pin-project"
version = "1.1.13" version = "1.1.13"
@@ -5817,12 +5542,6 @@ dependencies = [
"zerocopy", "zerocopy",
] ]
[[package]]
name = "precomputed-hash"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]] [[package]]
name = "presser" name = "presser"
version = "0.3.1" version = "0.3.1"
@@ -5930,20 +5649,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a" checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a"
dependencies = [ dependencies = [
"libc", "libc",
"rand_chacha 0.3.1", "rand_chacha",
"rand_core 0.6.4", "rand_core 0.6.4",
] ]
[[package]]
name = "rand"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41"
dependencies = [
"rand_chacha 0.9.0",
"rand_core 0.9.5",
]
[[package]] [[package]]
name = "rand" name = "rand"
version = "0.10.2" version = "0.10.2"
@@ -5964,16 +5673,6 @@ dependencies = [
"rand_core 0.6.4", "rand_core 0.6.4",
] ]
[[package]]
name = "rand_chacha"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core 0.9.5",
]
[[package]] [[package]]
name = "rand_core" name = "rand_core"
version = "0.6.4" version = "0.6.4"
@@ -5983,15 +5682,6 @@ dependencies = [
"getrandom 0.2.17", "getrandom 0.2.17",
] ]
[[package]]
name = "rand_core"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
dependencies = [
"getrandom 0.3.4",
]
[[package]] [[package]]
name = "rand_core" name = "rand_core"
version = "0.10.1" version = "0.10.1"
@@ -6219,19 +5909,6 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "ron"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db09040cc89e461f1a265139777a2bde7f8d8c67c4936f700c63ce3e2904d468"
dependencies = [
"base64 0.22.1",
"bitflags 2.13.1",
"serde",
"serde_derive",
"unicode-ident",
]
[[package]] [[package]]
name = "ron" name = "ron"
version = "0.12.2" version = "0.12.2"
@@ -6246,6 +5923,29 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "ron_asset_derive"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdb312bdc83344894927694f5549e55c358a34d94c0d2262f241015413cb7cbb"
dependencies = [
"quote",
"syn 2.0.119",
]
[[package]]
name = "ron_asset_manager"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f08cf385fe993fb4002dcb90e39e0d081c49db07a5a96a40d631d88080602df3"
dependencies = [
"bevy",
"ron",
"ron_asset_derive",
"serde",
"thiserror 1.0.69",
]
[[package]] [[package]]
name = "rstar" name = "rstar"
version = "0.12.2" version = "0.12.2"
@@ -6442,16 +6142,6 @@ dependencies = [
"serde_core", "serde_core",
] ]
[[package]]
name = "sha3"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874"
dependencies = [
"digest",
"keccak",
]
[[package]] [[package]]
name = "sharded-slab" name = "sharded-slab"
version = "0.1.7" version = "0.1.7"
@@ -6502,12 +6192,6 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
[[package]]
name = "siphasher"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649"
[[package]] [[package]]
name = "skrifa" name = "skrifa"
version = "0.40.0" version = "0.40.0"
@@ -6558,9 +6242,6 @@ name = "smallvec"
version = "1.15.2" version = "1.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "smartstring" name = "smartstring"
@@ -6702,18 +6383,6 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
[[package]]
name = "string_cache"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901"
dependencies = [
"new_debug_unreachable",
"parking_lot",
"phf_shared",
"precomputed-hash",
]
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.11.1" version = "0.11.1"
@@ -6845,15 +6514,6 @@ dependencies = [
"xattr", "xattr",
] ]
[[package]]
name = "term"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8c27177b12a6399ffc08b98f76f7c9a1f4fe9fc967c784c5a071fa8d93cf7e1"
dependencies = [
"windows-sys 0.61.2",
]
[[package]] [[package]]
name = "termcolor" name = "termcolor"
version = "1.4.1" version = "1.4.1"
+2 -10
View File
@@ -4,14 +4,6 @@ version = "0.1.0"
edition = "2024" edition = "2024"
authors = [""] authors = [""]
# A normal Bevy project. jackdaw builds its own editor artifacts in
# .jackdaw/ and never changes this manifest; `cargo run` works with or
# without the editor installed.
# Stand this project on its own even when it is created inside another
# cargo workspace, which would otherwise adopt it and refuse to build
# ("current package believes it's in a workspace when it's not").
# Delete this to make it a member of the surrounding workspace instead.
[workspace] [workspace]
[dependencies] [dependencies]
@@ -19,7 +11,7 @@ bevy = { version = "0.19", features = ["asset_processor", "dynamic_linking", "fr
# Loads the scenes you author in the editor (assets/*.bsn) and builds # Loads the scenes you author in the editor (assets/*.bsn) and builds
# physics colliders from them. An ordinary dependency; remove it if you # physics colliders from them. An ordinary dependency; remove it if you
# stop using authored scenes. # stop using authored scenes.
jackdaw_runtime = { version = "0.19", features = ["physics"], path="../jackdaw/crates/jackdaw_runtime" } thiserror = "2"
avian3d = "0.7" avian3d = "0.7"
arrayvec = "0.7.8" arrayvec = "0.7.8"
bevy-inspector-egui = "0.37.0" bevy-inspector-egui = "0.37.0"
@@ -36,8 +28,8 @@ bevy_wind_waker_shader = { git = "https://github.com/lavaeater/bevy_wind_waker_s
fixed = { version = "1.31.0", features = ["serde", "serde-str"] } fixed = { version = "1.31.0", features = ["serde", "serde-str"] }
strum = "0.28.0" strum = "0.28.0"
strum_macros = "0.28.0" strum_macros = "0.28.0"
bevy_common_assets = { version = "0.17.0", features = ["ron"] }
bevy_asset_loader = "0.27.0" bevy_asset_loader = "0.27.0"
ron_asset_manager = "0.9.0"
gc-adapter-neo = { version = "1.0.0", features = ["libusb"] } gc-adapter-neo = { version = "1.0.0", features = ["libusb"] }
rhai = "1.26.0" rhai = "1.26.0"
enum_cycling = "0.2.1" enum_cycling = "0.2.1"
+47 -12
View File
@@ -1,11 +1,20 @@
use bevy::{input_focus::InputFocus, picking::{hover::PickingInteraction, Pickable}, prelude::*, text::FontSourceTemplate, ui::auto_directional_navigation::AutoDirectionalNavigation}; use bevy::{
input_focus::InputFocus,
picking::{Pickable, hover::PickingInteraction},
prelude::*,
text::FontSourceTemplate,
ui::auto_directional_navigation::AutoDirectionalNavigation,
};
use crate::{game_settings::CommonAssets, menus::style::{FGUiButtonType, FGUiStyle}}; use crate::{
game_settings::CommonAssets,
menus::style::{FGUiButtonType, FGUiStyle},
};
#[derive(Component, Default, Clone)] #[derive(Component, Default, Clone)]
#[require(Button)] #[require(Button)]
pub struct FGUiButton { pub struct FGUiButton {
pub button_type: FGUiButtonType pub button_type: FGUiButtonType,
} }
pub fn menu_button(label: &str) -> impl Scene { pub fn menu_button(label: &str) -> impl Scene {
@@ -37,15 +46,34 @@ pub fn menu_button(label: &str) -> impl Scene {
} }
} }
pub fn button_setup(query: Query<(Entity, &FGUiButton, &mut Node), Added<FGUiButton>>, common_assets: Res<CommonAssets>, styles: Res<Assets<FGUiStyle>>, mut commands: Commands) { pub fn button_setup(
let styles = styles.get(&common_assets.ui_style).expect("UI styles should be loaded"); query: Query<(Entity, &FGUiButton, &mut Node), Added<FGUiButton>>,
common_assets: Res<CommonAssets>,
styles: Res<Assets<FGUiStyle>>,
mut commands: Commands,
) {
let styles = styles
.get(&common_assets.ui_style)
.expect("UI styles should be loaded");
for (entity, button, mut node) in query { for (entity, button, mut node) in query {
styles.button_styles[&button.button_type].normal.apply(&mut commands, entity, &mut node); styles.button_styles[&button.button_type]
.normal
.apply(&mut commands, entity, &mut node);
} }
} }
pub fn button_style_system(query: Query<(Entity, &FGUiButton, &PickingInteraction, &mut Node), Changed<PickingInteraction>>, common_assets: Res<CommonAssets>, styles: Res<Assets<FGUiStyle>>, mut commands: Commands) { pub fn button_style_system(
let styles = styles.get(&common_assets.ui_style).expect("UI styles should be loaded"); query: Query<
(Entity, &FGUiButton, &PickingInteraction, &mut Node),
Changed<PickingInteraction>,
>,
common_assets: Res<CommonAssets>,
styles: Res<Assets<FGUiStyle>>,
mut commands: Commands,
) {
let styles = styles
.get(&common_assets.ui_style)
.expect("UI styles should be loaded");
for (entity, button, interaction, mut node) in query { for (entity, button, interaction, mut node) in query {
let button_style_to_use = match interaction { let button_style_to_use = match interaction {
@@ -57,14 +85,21 @@ pub fn button_style_system(query: Query<(Entity, &FGUiButton, &PickingInteractio
} }
} }
pub fn button_focus_style_system(query: Query<(Entity, &FGUiButton)>, focus: Res<InputFocus>, mut commands: Commands, common_assets: Res<CommonAssets>, styles: Res<Assets<FGUiStyle>>) { pub fn button_focus_style_system(
query: Query<(Entity, &FGUiButton)>,
focus: Res<InputFocus>,
mut commands: Commands,
common_assets: Res<CommonAssets>,
styles: Res<Assets<FGUiStyle>>,
) {
if let Some(focused_entity) = focus.get() { if let Some(focused_entity) = focus.get() {
if !query.contains(focused_entity) { if !query.contains(focused_entity) {
return; return;
} }
let styles = styles.get(&common_assets.ui_style).expect("UI styles should be loaded"); let styles = styles
.get(&common_assets.ui_style)
.expect("UI styles should be loaded");
for (entity, button) in query { for (entity, button) in query {
if focused_entity == entity { if focused_entity == entity {
@@ -72,7 +107,7 @@ pub fn button_focus_style_system(query: Query<(Entity, &FGUiButton)>, focus: Res
commands.entity(focused_entity).insert(Outline { commands.entity(focused_entity).insert(Outline {
width: px(style.focus_outline_width_px), width: px(style.focus_outline_width_px),
offset: px(style.focus_outline_offset_px), offset: px(style.focus_outline_offset_px),
color: style.focus_outline_color color: style.focus_outline_color,
}); });
} else { } else {
commands.entity(entity).remove::<Outline>(); commands.entity(entity).remove::<Outline>();
+31 -29
View File
@@ -6,15 +6,7 @@ use bevy_egui::egui::accesskit::TextAlign;
use crate::{ use crate::{
AppState, fighter::manifest::{FighterManifest, FighterManifestRegistry}, game_settings::CommonAssets, input::{LocalInputAssignments, LocalInputSource}, menus::{ AppState, fighter::manifest::{FighterManifest, FighterManifestRegistry}, game_settings::CommonAssets, input::{LocalInputAssignments, LocalInputSource}, menus::{
MenuMarker, build_menu_with_props, MenuMarker, build_menu_with_props, button::FGUiButton, character_select::{character_box::CharacterBox, token::CharacterSelectToken}, cursor::{FGMenuCursor, MenuCursorInputSource}, errors::MenuErrors::{self, FighterManifestNotFound}, match_config::{MenuMatchConfig, MenuMatchPlayerSlot}, scaling, spawn_menu, style::{FGUiButtonType, FGUiStyle}, wrap_menu,
button::FGUiButton,
character_select::character_box::CharacterBox,
cursor::{FGMenuCursor, MenuCursorInputSource},
errors::MenuErrors::{self, FighterManifestNotFound},
match_config::{MenuMatchConfig, MenuMatchPlayerSlot},
scaling, spawn_menu,
style::{FGUiButtonType, FGUiStyle},
wrap_menu,
}, },
}; };
@@ -67,6 +59,17 @@ pub fn setup_character_select(
} }
Children [ Children [
{character_boxes}, {character_boxes},
]
),
(
#PortraitContainer
Node {
flex_direction: FlexDirection::Row,
width: percent(100),
min_height: px(400),
justify_content: JustifyContent::Center
}
),
( (
// Start banner thingy // Start banner thingy
StartButtonBanner StartButtonBanner
@@ -79,7 +82,7 @@ pub fn setup_character_select(
FGUiButton { FGUiButton {
button_type: FGUiButtonType::CharacterSelectStartBanner button_type: FGUiButtonType::CharacterSelectStartBanner
} }
Text::new("Peenids") Text::new("Start poetry")
Visibility::Hidden Visibility::Hidden
TextLayout { TextLayout {
justify: Justify::Center justify: Justify::Center
@@ -93,17 +96,6 @@ pub fn setup_character_select(
on(|_ev: On<Pointer<Press>>, mut next_state: ResMut<NextState<AppState>>| next_state.set(AppState::StageSelect)) on(|_ev: On<Pointer<Press>>, mut next_state: ResMut<NextState<AppState>>| next_state.set(AppState::StageSelect))
) )
] ]
),
(
#PortraitContainer
Node {
flex_direction: FlexDirection::Row,
width: percent(100),
height: px(400),
justify_content: JustifyContent::Center
}
)
]
}; };
commands.init_resource::<MenuMatchConfig>(); commands.init_resource::<MenuMatchConfig>();
@@ -113,7 +105,7 @@ pub fn setup_character_select(
pub fn create_portrait( pub fn create_portrait(
player_slot: usize, player_slot: usize,
container: Entity, container: Entity,
mut commands: Commands, commands: &mut Commands,
style: &FGUiStyle, style: &FGUiStyle,
input_source: &LocalInputSource, input_source: &LocalInputSource,
) { ) {
@@ -123,7 +115,7 @@ pub fn create_portrait(
commands.entity(container).add_child(entity); commands.entity(container).add_child(entity);
let cursor = commands let cursor = commands
.spawn(FGMenuCursor::create_cursor( .spawn(FGMenuCursor::create_player_cursor(
player_slot, player_slot,
style, style,
input_source, input_source,
@@ -137,24 +129,26 @@ pub fn create_portrait(
commands.entity(container).add_child(entity); commands.entity(container).add_child(entity);
} }
#[derive(Event)] #[derive(Message)]
pub struct PlayerSlotAssigned { pub struct PlayerSlotAssigned {
pub slot: usize, pub slot: usize,
pub input_source: LocalInputSource, pub input_source: LocalInputSource,
} }
pub fn handle_fighter_slot_addition( pub fn handle_fighter_slot_addition(
addition: On<PlayerSlotAssigned>, mut addition: MessageReader<PlayerSlotAssigned>,
query: Single<&CharacterSelectScreen>, query: Single<&CharacterSelectScreen>,
commands: Commands, mut commands: Commands,
common_assets: Res<CommonAssets>, common_assets: Res<CommonAssets>,
styles: Res<Assets<FGUiStyle>>, styles: Res<Assets<FGUiStyle>>,
) { ) {
for addition in addition.read() {
let slot = addition.slot; let slot = addition.slot;
create_portrait( create_portrait(
slot, slot,
query.fighter_portait_container, query.fighter_portait_container,
commands, &mut commands,
styles styles
.get(&common_assets.ui_style) .get(&common_assets.ui_style)
.expect("UI Style should be loaded by now"), .expect("UI Style should be loaded by now"),
@@ -162,11 +156,13 @@ pub fn handle_fighter_slot_addition(
); );
} }
}
pub fn css_auto_assign_slots( pub fn css_auto_assign_slots(
menu_inputs: Res<crate::menus::input::MenuInputState>, menu_inputs: Res<crate::menus::input::MenuInputState>,
mut assignments: ResMut<LocalInputAssignments>, mut assignments: ResMut<LocalInputAssignments>,
mut match_config: ResMut<MenuMatchConfig>, mut match_config: ResMut<MenuMatchConfig>,
mut commands: Commands, mut ev_assigned: MessageWriter<PlayerSlotAssigned>,
) { ) {
for (source, input) in &menu_inputs.inputs { for (source, input) in &menu_inputs.inputs {
if input.movement != Vec2::ZERO { if input.movement != Vec2::ZERO {
@@ -178,7 +174,7 @@ pub fn css_auto_assign_slots(
fighter: None, fighter: None,
}); });
info!("New input assignment"); info!("New input assignment");
commands.trigger(PlayerSlotAssigned { ev_assigned.write(PlayerSlotAssigned {
slot: free_idx, slot: free_idx,
input_source: source.clone(), input_source: source.clone(),
}); });
@@ -268,3 +264,9 @@ pub fn copy_cursor_transform_to_token(
} }
Ok(()) Ok(())
} }
pub fn despawn_tokens(tokens: Query<Entity, With<CharacterSelectToken>>, mut commands: Commands) {
for token in tokens {
commands.entity(token).despawn();
}
}
+1
View File
@@ -26,6 +26,7 @@ impl CharacterSelectToken {
}, },
ImageNode { ImageNode {
image: style.css_token.handle.handle.clone(), image: style.css_token.handle.handle.clone(),
color: style.player_colors.get(slot).copied().unwrap_or(Color::WHITE),
..default() ..default()
} }
) )
+28 -7
View File
@@ -28,20 +28,21 @@ pub struct FGMenuCursor {
impl FGMenuCursor { impl FGMenuCursor {
pub fn create_cursor( pub fn create_cursor(
player_slot: usize, input_source: MenuCursorInputSource,
style: &FGUiStyle, style: &FGUiStyle,
input_source: &LocalInputSource, pointer_id: PointerId
) -> impl Bundle { ) -> impl Bundle {
let pointer_id = if matches!(input_source, LocalInputSource::Keyboard) {PointerId::Mouse} else {PointerId::Custom(Uuid::new_v4())};
let circle_icon = style.cursor.handle().clone(); let circle_icon = style.cursor.handle().clone();
( (
FGMenuCursor { FGMenuCursor {
input_source: super::cursor::MenuCursorInputSource::Player(player_slot), input_source: input_source,
..default() ..default()
}, },
Node { Node {
width: px(64), width: px(64),
height: px(64), height: px(64),
left: percent(50),
top: percent(50),
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
..default() ..default()
}, },
@@ -55,6 +56,25 @@ impl FGMenuCursor {
Pickable::IGNORE, Pickable::IGNORE,
) )
} }
pub fn create_shared_cursor(style: &FGUiStyle) -> impl Bundle {
Self::create_cursor(
MenuCursorInputSource::Any,
style,
PointerId::Mouse
)
}
pub fn create_player_cursor(
player_slot: usize,
style: &FGUiStyle,
input_source: &LocalInputSource,
) -> impl Bundle {
let pointer_id = if matches!(input_source, LocalInputSource::Keyboard) {PointerId::Mouse} else {PointerId::Custom(Uuid::new_v4())};
Self::create_cursor(
MenuCursorInputSource::Player(player_slot),
style,
pointer_id
)
}
} }
/// The player using the keyboard can input things with the mouse, so we should copy their movement input /// The player using the keyboard can input things with the mouse, so we should copy their movement input
@@ -159,14 +179,15 @@ pub fn cursor_input(
pub fn update_cursor_transform( pub fn update_cursor_transform(
camera: Single<&Camera, With<IsDefaultUiCamera>>, camera: Single<&Camera, With<IsDefaultUiCamera>>,
query: Query<(&mut UiTransform, &PointerLocation), With<FGMenuCursor>>, query: Query<(&mut Node, &PointerLocation), With<FGMenuCursor>>,
ui_scale: Res<UiScale>, ui_scale: Res<UiScale>,
) { ) {
let camera = camera.into_inner(); let camera = camera.into_inner();
for (mut ui_trf, location) in query { for (mut node, location) in query {
let ui_pos = scaling::logical_to_ui_position(location.location.as_ref().map(|d| d.position).unwrap_or_default(), camera, &ui_scale); let ui_pos = scaling::logical_to_ui_position(location.location.as_ref().map(|d| d.position).unwrap_or_default(), camera, &ui_scale);
ui_trf.translation = Val2::new(px(ui_pos.x), px(ui_pos.y)); node.left = px(ui_pos.x);
node.top = px(ui_pos.y);
} }
} }
+58 -9
View File
@@ -1,37 +1,86 @@
use bevy::prelude::*; use bevy::prelude::*;
use thiserror::Error; use thiserror::Error;
use crate::fighter::FighterId; use crate::{
fighter::FighterId,
match_loading::{MatchPlayer, PendingMatch},
stage::manifest::StageId,
};
pub struct MenuMatchPlayerSlot { pub struct MenuMatchPlayerSlot {
pub slot: usize, pub slot: usize,
pub fighter: Option<FighterId> pub fighter: Option<FighterId>,
} }
#[derive(Resource, Default)] #[derive(Resource, Default)]
pub struct MenuMatchConfig { pub struct MenuMatchConfig {
pub players: Vec<MenuMatchPlayerSlot> pub stage: Option<StageId>,
pub players: Vec<MenuMatchPlayerSlot>,
} }
#[derive(Error, Debug, Reflect)] #[derive(Error, Debug, Reflect)]
pub enum MenuMatchConfigErrors { pub enum MenuMatchConfigErrors {
#[error("Fighter slot {0} was invalid!")] #[error("Fighter slot {0} was invalid!")]
PlayerSlotInvalid(usize) PlayerSlotInvalid(usize),
#[error("Invalid configuration: Slot {0} doesn't have a fighter selected")]
FighterNotSelectedForSlot(usize),
#[error("Invalid configuration: No stage selected")]
StageNotSelected,
} }
impl MenuMatchConfig { impl MenuMatchConfig {
pub fn set_player_fighter(&mut self, player_slot: usize, fighter_id: Option<FighterId>) -> Result<(), MenuMatchConfigErrors> { pub fn set_player_fighter(
let slot = self.players.get_mut(player_slot).ok_or(MenuMatchConfigErrors::PlayerSlotInvalid(player_slot))?; &mut self,
player_slot: usize,
fighter_id: Option<FighterId>,
) -> Result<(), MenuMatchConfigErrors> {
let slot = self
.players
.get_mut(player_slot)
.ok_or(MenuMatchConfigErrors::PlayerSlotInvalid(player_slot))?;
slot.fighter = fighter_id; slot.fighter = fighter_id;
Ok(()) Ok(())
} }
pub fn get_player_fighter(&self, player_slot: usize) -> Result<Option<FighterId>, MenuMatchConfigErrors> { pub fn get_player_fighter(
let slot = self.players.get(player_slot).ok_or(MenuMatchConfigErrors::PlayerSlotInvalid(player_slot))?; &self,
player_slot: usize,
) -> Result<Option<FighterId>, MenuMatchConfigErrors> {
let slot = self
.players
.get(player_slot)
.ok_or(MenuMatchConfigErrors::PlayerSlotInvalid(player_slot))?;
Ok(slot.fighter) Ok(slot.fighter)
} }
pub fn all_players_ready(&self) -> bool { pub fn all_players_ready(&self) -> bool {
let has_unselected_fighter = self.players.iter().any(|player_slot| player_slot.fighter.is_none()); let has_unselected_fighter = self
.players
.iter()
.any(|player_slot| player_slot.fighter.is_none());
!has_unselected_fighter !has_unselected_fighter
} }
pub fn to_pending_match(&self) -> Result<PendingMatch, MenuMatchConfigErrors> {
let mut match_players = vec![];
let stage = self.stage.ok_or(MenuMatchConfigErrors::StageNotSelected)?;
for player in self.players.iter() {
let fighter_id =
player
.fighter
.ok_or(MenuMatchConfigErrors::FighterNotSelectedForSlot(
player.slot,
))?;
match_players.push(MatchPlayer {
fighter: fighter_id,
handle: player.slot,
});
}
Ok(PendingMatch {
players: match_players,
stage,
})
}
} }
+66 -20
View File
@@ -17,14 +17,14 @@ use crate::{
pub mod button; pub mod button;
pub mod character_select; pub mod character_select;
pub mod cursor; pub mod cursor;
pub mod errors;
pub mod input; pub mod input;
pub mod main_menu; pub mod main_menu;
pub mod match_config;
pub mod navigation; pub mod navigation;
pub mod scaling; pub mod scaling;
pub mod style;
pub mod match_config;
pub mod errors;
pub mod stage_select; pub mod stage_select;
pub mod style;
#[derive(Component, Clone, Default)] #[derive(Component, Clone, Default)]
pub struct MenuMarker {} pub struct MenuMarker {}
@@ -66,6 +66,19 @@ pub fn wrap_menu(menu: impl Scene) -> impl Scene {
} }
} }
pub fn despawn_menu(
existing_menu: Option<Single<Entity, With<MenuMarker>>>,
mut commands: Commands,
) {
if let Some(entity) = existing_menu {
commands
.entity(entity.into_inner())
.remove::<Camera2d>()
.remove::<Camera>()
.despawn();
}
}
pub fn spawn_menu( pub fn spawn_menu(
existing_menu: Option<Single<Entity, With<MenuMarker>>>, existing_menu: Option<Single<Entity, With<MenuMarker>>>,
mut commands: Commands, mut commands: Commands,
@@ -116,10 +129,7 @@ impl Plugin for MenuPlugin {
)); ));
}), }),
) )
.add_systems( .add_message::<character_select::PlayerSlotAssigned>()
OnEnter(AppState::CharacterSelect),
character_select::setup_character_select,
)
.init_resource::<navigation::UINavigationActionState>() .init_resource::<navigation::UINavigationActionState>()
.init_resource::<navigation::UINavigationRepeat>() .init_resource::<navigation::UINavigationRepeat>()
.init_resource::<input::MenuInputState>() .init_resource::<input::MenuInputState>()
@@ -150,35 +160,71 @@ impl Plugin for MenuPlugin {
.run_if(resource_exists::<CommonAssets>), .run_if(resource_exists::<CommonAssets>),
) )
.add_systems(Startup, scaling::ui_update_scale_on_startup) .add_systems(Startup, scaling::ui_update_scale_on_startup)
// CURSOR
.add_systems(
PreUpdate,
(cursor::cursor_input).before(bevy::picking::PickingSystems::ProcessInput),
)
.add_systems(
Update,
(cursor::copy_mouse_input, cursor::update_cursor_transform),
)
.add_systems( .add_systems(
PreUpdate, PreUpdate,
input::sample_menu_inputs input::sample_menu_inputs
.before(cursor::cursor_input) .before(cursor::cursor_input)
.run_if(resource_exists::<crate::input::MenuInputMap>), .run_if(resource_exists::<crate::input::MenuInputMap>),
) )
//---------
// CHARACTER SELECT START
//---------
.add_systems( .add_systems(
PreUpdate, OnEnter(AppState::CharacterSelect),
cursor::cursor_input character_select::setup_character_select,
.before(bevy::picking::PickingSystems::ProcessInput) )
.add_systems(
PostUpdate,
character_select::copy_cursor_transform_to_token
.run_if(in_state(AppState::CharacterSelect)) .run_if(in_state(AppState::CharacterSelect))
.run_if(any_with_component::<CharacterSelectScreen>), .run_if(any_with_component::<CharacterSelectScreen>),
) )
.add_systems( .add_systems(
PostUpdate, PreUpdate,
( (character_select::css_auto_assign_slots, character_select::handle_fighter_slot_addition)
character_select::css_auto_assign_slots,
cursor::copy_mouse_input,
cursor::update_cursor_transform,
character_select::copy_cursor_transform_to_token,
)
.chain() .chain()
.run_if(in_state(AppState::CharacterSelect)) .run_if(in_state(AppState::CharacterSelect))
.run_if(any_with_component::<CharacterSelectScreen>), .run_if(any_with_component::<CharacterSelectScreen>),
) )
.add_systems(OnExit(AppState::CharacterSelect), cursor::despawn_cursors) .add_systems(
.add_observer(character_select::handle_fighter_slot_addition) OnExit(AppState::CharacterSelect),
(cursor::despawn_cursors, character_select::despawn_tokens),
)
.add_observer(character_select::select_fighter.run_if(in_state(AppState::CharacterSelect))) .add_observer(character_select::select_fighter.run_if(in_state(AppState::CharacterSelect)))
.add_observer(character_select::update_start_banner_visibility.run_if(in_state(AppState::CharacterSelect))) .add_observer(
character_select::update_start_banner_visibility
.run_if(in_state(AppState::CharacterSelect)),
)
//---------
// CHARACTER SELECT END
//---------
//---------
// STAGE SELECT START
//---------
.add_systems(
OnEnter(AppState::StageSelect),
stage_select::setup_stage_select,
)
.add_observer(stage_select::stage_selected.run_if(in_state(AppState::StageSelect)),
)
.add_systems(
OnExit(AppState::StageSelect),
(cursor::despawn_cursors, despawn_menu),
)
//---------
// STAGE SELECT END
//---------
.add_plugins(RonAssetPlugin::<FGUiStyle>::create("stylesheet.ron")) .add_plugins(RonAssetPlugin::<FGUiStyle>::create("stylesheet.ron"))
.add_systems( .add_systems(
Update, Update,
+75
View File
@@ -0,0 +1,75 @@
use bevy::prelude::*;
use crate::{
AppState, game_settings::CommonAssets, match_loading::initiate_match, menus::{
MenuMarker, button::FGUiButton, cursor, match_config::MenuMatchConfig, spawn_menu, stage_select::stage_box::StageBox, style::{FGUiButtonType, FGUiStyle},
}, stage::manifest::{StageManifest, StageManifestRegistry},
};
pub mod stage_box;
#[derive(Component, FromTemplate)]
pub struct StageSelectScreen {
pub stage_icons_container: Entity,
}
pub fn setup_stage_select(
existing_menu: Option<Single<Entity, With<MenuMarker>>>,
mut commands: Commands,
manifest_registry: Res<StageManifestRegistry>,
manifests: Res<Assets<StageManifest>>,
common_assets: Res<CommonAssets>,
styles: Res<Assets<FGUiStyle>>,
) {
let style = styles
.get(&common_assets.ui_style)
.expect("UI style should be loaded");
let stage_boxes = manifest_registry
.iter()
.map(|(_, v)| stage_box::StageBox::scene(v.clone(), &manifests))
.collect::<Vec<_>>();
let menu = bsn! {
// Characters
StageSelectScreen {
stage_icons_container: #PortraitContainer
}
Node {
flex_direction: FlexDirection::Column
}
Children [
(
Node {
flex_direction: FlexDirection::Column,
width: percent(100),
height: percent(100),
justify_content: JustifyContent::Center,
align_items: AlignItems::Center
}
Children [
{stage_boxes},
]
)
]
};
commands.spawn(cursor::FGMenuCursor::create_shared_cursor(style));
spawn_menu(existing_menu, commands, menu);
}
pub fn stage_selected(
ev: On<Pointer<Press>>,
query: Query<&StageBox>,
mut commands: Commands,
mut next_state: ResMut<NextState<AppState>>,
mut match_config: ResMut<MenuMatchConfig>
) -> Result {
let stage_box = query.get(ev.event_target());
if let Ok(stage_box) = stage_box {
match_config.stage = Some(stage_box.stage_id);
initiate_match(&mut commands, &mut next_state, match_config.to_pending_match()?);
}
Ok(())
}
+55
View File
@@ -0,0 +1,55 @@
use bevy::{picking::Pickable, prelude::*, text::FontSourceTemplate, ui::widget::ImageNodeSize};
use crate::{
fighter::{FighterId, manifest::FighterManifest}, menus::{button::FGUiButton, style::FGUiButtonType}, stage::manifest::{StageId, StageManifest},
};
#[derive(Component, Clone, FromTemplate)]
pub struct StageBox {
pub stage_manifest: Handle<StageManifest>,
pub stage_id: StageId
}
impl StageBox {
pub fn scene(
manifest_handle: Handle<StageManifest>,
manifests: &Res<Assets<StageManifest>>,
) -> impl Scene {
let manifest = manifests
.get(&manifest_handle)
.expect("Stage manifest should be valid");
let fighter_icon = manifest.icon.handle().clone();
let stage_id = manifest.id;
bsn! {
Node {
width: px(256),
height: px(256),
flex_direction: FlexDirection::Column,
justify_content: JustifyContent::FlexEnd
}
ImageNode {
image: fighter_icon
}
FGUiButton {
button_type: FGUiButtonType::StageSelectIcon
}
StageBox {
stage_manifest: manifest_handle,
stage_id: stage_id
}
BackgroundColor(Color::srgb(1.0, 1.0, 1.0))
Children [
Pickable::IGNORE
Node {
width: percent(100)
}
TextFont {
font: FontSourceTemplate::Handle("fonts/roboto.ttf"),
font_size: px(crate::menus::style::TEXT_SIZE),
}
TextColor(Color::srgb(0.9, 0.9, 0.9))
BackgroundColor(Color::srgb(0.0, 0.0, 1.0))
]
}
}
}
+5 -1
View File
@@ -26,6 +26,7 @@ pub struct BoxShadowStyle {
pub struct ButtonStyle { pub struct ButtonStyle {
background_color: Color, background_color: Color,
border_color: Color, border_color: Color,
border_radius: f32,
text_color: Color, text_color: Color,
box_shadow: BoxShadowStyle, box_shadow: BoxShadowStyle,
border_size: i32, border_size: i32,
@@ -44,9 +45,10 @@ pub struct ButtonStyles {
impl ButtonStyle { impl ButtonStyle {
pub fn apply(&self, commands: &mut Commands, entity: Entity, node: &mut Node) { pub fn apply(&self, commands: &mut Commands, entity: Entity, node: &mut Node) {
node.border = UiRect::all(px(self.border_size)); node.border = UiRect::all(px(self.border_size));
node.border_radius = BorderRadius::all(px(self.border_radius));
commands.entity(entity).insert(( commands.entity(entity).insert((
BackgroundColor(self.background_color), BackgroundColor(self.background_color),
BorderColor::all(self.background_color), BorderColor::all(self.border_color),
BoxShadow::new( BoxShadow::new(
self.box_shadow.color, self.box_shadow.color,
px(self.box_shadow.offset_px_x), px(self.box_shadow.offset_px_x),
@@ -64,6 +66,7 @@ pub enum FGUiButtonType {
MainMenu, MainMenu,
CharacterSelectCharacter, CharacterSelectCharacter,
CharacterSelectStartBanner, CharacterSelectStartBanner,
StageSelectIcon,
} }
#[derive(Asset, Resource, Reflect, Deserialize, RonAsset)] #[derive(Asset, Resource, Reflect, Deserialize, RonAsset)]
@@ -77,4 +80,5 @@ pub struct FGUiStyle {
#[dependency] #[dependency]
#[reflect(ignore)] #[reflect(ignore)]
pub css_token: TextureReference, pub css_token: TextureReference,
pub player_colors: Vec<Color>,
} }
+28 -12
View File
@@ -3,7 +3,9 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc};
use rhai::EvalAltResult; use rhai::EvalAltResult;
use crate::{ use crate::{
fighter::attack::{self, AttackAngle, FighterDamage, Knockback, KnockbackType}, math::{int::FGi32, vec::FGVec2, vec3::FGVec3}, scripting::FighterAttackScript, fighter::attack::{self, AttackAngle, FighterDamage, Knockback, KnockbackType},
math::{int::FGi32, vec::FGVec2, vec3::FGVec3},
scripting::FighterAttackScript,
}; };
#[derive(Debug, Default)] #[derive(Debug, Default)]
@@ -61,9 +63,17 @@ impl MoveCompiler {
Ok(()) Ok(())
} }
fn set_wont_autocancel_window(&mut self, start: u32, end: u32) -> Result<(), Box<EvalAltResult>> { fn set_wont_autocancel_window(
&mut self,
start: u32,
end: u32,
) -> Result<(), Box<EvalAltResult>> {
if end < start { if end < start {
return Err(format!("Couldn't set won't autocancel window, end frame {} is smaller than start frame {}", end, start).into()); return Err(format!(
"Couldn't set won't autocancel window, end frame {} is smaller than start frame {}",
end, start
)
.into());
} }
self.wont_autocancel_window = Some((start, end)); self.wont_autocancel_window = Some((start, end));
@@ -77,13 +87,17 @@ impl MoveCompiler {
fn into_attack_script(mut self) -> Result<FighterAttackScript, String> { fn into_attack_script(mut self) -> Result<FighterAttackScript, String> {
self.remove_all_hitboxes().map_err(|err| err.to_string())?; self.remove_all_hitboxes().map_err(|err| err.to_string())?;
let hitboxes = self.hitboxes.into_iter().map(|(_, hitbox)| hitbox).collect(); let hitboxes = self
.hitboxes
.into_iter()
.map(|(_, hitbox)| hitbox)
.collect();
let iasa_frame = self.iasa_frame.unwrap_or(100000); let iasa_frame = self.iasa_frame.unwrap_or(100000);
let wont_autocancel_window = self.wont_autocancel_window.unwrap_or((0, 100000)); let wont_autocancel_window = self.wont_autocancel_window.unwrap_or((0, 100000));
Ok(FighterAttackScript { Ok(FighterAttackScript {
hitboxes, hitboxes,
iasa_frame, iasa_frame,
wont_autocancel_window wont_autocancel_window,
}) })
} }
} }
@@ -166,13 +180,10 @@ pub fn compile_script(text: &str) -> Result<FighterAttackScript, String> {
{ {
let mc = mc.clone(); let mc = mc.clone();
engine.register_fn( engine.register_fn("set_iasa_frame", move |frame: i64| {
"set_iasa_frame",
move |frame: i64| {
let mut b = mc.borrow_mut(); let mut b = mc.borrow_mut();
b.set_iasa_frame(frame as u32); b.set_iasa_frame(frame as u32);
}, });
);
} }
{ {
@@ -222,7 +233,12 @@ pub fn compile_script(text: &str) -> Result<FighterAttackScript, String> {
engine.run(&text) engine.run(&text)
}; };
result
result.map(|_| Rc::into_inner(mc).unwrap().into_inner().into_attack_script()) .map(|_| {
Rc::into_inner(mc)
.unwrap()
.into_inner()
.into_attack_script()
})
.map_err(|err| err.to_string())? .map_err(|err| err.to_string())?
} }
-1
View File
@@ -1,6 +1,5 @@
//! Stage collision geometry. //! Stage collision geometry.
use bevy::prelude::*; use bevy::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
+11 -8
View File
@@ -1,18 +1,16 @@
use std::collections::HashMap; use std::collections::HashMap;
use bevy_asset_loader::asset_collection::AssetCollection; use bevy_asset_loader::asset_collection::AssetCollection;
use ron_asset_manager::prelude::RonAsset;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use strum_macros::EnumIter; use strum_macros::EnumIter;
use crate::{ use crate::{
AppState, AppState, game_settings::GameSettings, math::vec::FGVec2, stage::{
game_settings::GameSettings,
math::vec::FGVec2,
stage::{
StagePoly, StagePoly,
line::{StageCollision, StagePolyLineSegmentType, StagePolyType}, line::{StageCollision, StagePolyLineSegmentType, StagePolyType},
}, }, texture_reference::TextureReference,
}; };
use bevy::prelude::*; use bevy::prelude::*;
@@ -60,8 +58,9 @@ pub struct StageCameraProfile {
pub max_downward_pan_degrees: f32, pub max_downward_pan_degrees: f32,
} }
#[derive(Reflect, Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Hash, Debug, EnumIter)] #[derive(Reflect, Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Hash, Debug, EnumIter, Default)]
pub enum StageId { pub enum StageId {
#[default]
TestStage, TestStage,
} }
@@ -72,10 +71,14 @@ pub struct StagePolyDefinition {
lines: Vec<(FGVec2, StagePolyLineSegmentType)>, lines: Vec<(FGVec2, StagePolyLineSegmentType)>,
} }
#[derive(Serialize, Deserialize, Clone, Asset, Reflect)] #[derive(Deserialize, Clone, Asset, Reflect, RonAsset)]
pub struct StageManifest { pub struct StageManifest {
pub id: StageId, pub id: StageId,
pub model_path: String, pub model_path: String,
#[asset]
#[dependency]
#[reflect(ignore)]
pub icon: TextureReference,
pub camera: StageCameraProfile, pub camera: StageCameraProfile,
pub polygons: Vec<StagePolyDefinition>, pub polygons: Vec<StagePolyDefinition>,
} }
@@ -112,7 +115,7 @@ impl AssetCollection for StageManifestAssets {
} }
} }
#[derive(Resource)] #[derive(Resource, Deref)]
pub struct StageManifestRegistry(HashMap<StageId, Handle<StageManifest>>); pub struct StageManifestRegistry(HashMap<StageId, Handle<StageManifest>>);
impl StageManifestRegistry { impl StageManifestRegistry {
+2 -2
View File
@@ -5,12 +5,12 @@ use bevy::prelude::*;
pub mod debug; pub mod debug;
pub mod line; pub mod line;
pub mod scene;
pub mod manifest; pub mod manifest;
pub mod scene;
pub use line::{StagePlaneIntersectResult, StagePoly}; pub use line::{StagePlaneIntersectResult, StagePoly};
use crate::{stage::{line::StageCollision, manifest::StageCameraProfile}}; use crate::stage::{line::StageCollision, manifest::StageCameraProfile};
/// Owns the stage geometry: which scene gets spawned and how it is drawn. /// Owns the stage geometry: which scene gets spawned and how it is drawn.
#[derive(Default)] #[derive(Default)]
+1 -3
View File
@@ -4,9 +4,7 @@ use std::f32::consts::PI;
use bevy::prelude::*; use bevy::prelude::*;
use crate::{ use crate::{camera::MatchCamera, stage::line::StageCollision};
camera::MatchCamera, stage::line::StageCollision,
};
pub fn spawn_stage_support( pub fn spawn_stage_support(
commands: &mut Commands, commands: &mut Commands,