From af191cc46e88ae80f3e1226b39e8dfc5bf4cb2cb Mon Sep 17 00:00:00 2001 From: Jovan Gerodetti Date: Wed, 22 Nov 2023 23:13:07 +0100 Subject: [PATCH] Introduce Godot Rust Script --- .github/workflows/build.yml | 3 +- native/Cargo.lock | 566 +++++++++++++++++- native/Cargo.toml | 14 +- native/scripts/Cargo.toml | 12 + native/scripts/src/lib.rs | 5 + .../scripts/src/particles/dust_particles.rs | 68 +++ native/scripts/src/particles/mod.rs | 1 + native/scripts/src/scene_object_registry.rs | 461 ++++++++++++++ native/scripts/src/spawner/car_spawner.rs | 112 ++++ native/scripts/src/spawner/mod.rs | 1 + native/src/lib.rs | 33 +- native/src/terrain_builder.rs | 18 +- resources/Objects/Spawner/CarSpawner.tscn | 7 +- resources/main.tscn | 1 + src/Objects/Helicopters/Helicopter.gd | 1 - src/Objects/World/Networks.gd | 1 - src/native.gdextension | 3 +- 17 files changed, 1274 insertions(+), 33 deletions(-) create mode 100644 native/scripts/Cargo.toml create mode 100644 native/scripts/src/lib.rs create mode 100644 native/scripts/src/particles/dust_particles.rs create mode 100644 native/scripts/src/particles/mod.rs create mode 100644 native/scripts/src/scene_object_registry.rs create mode 100644 native/scripts/src/spawner/car_spawner.rs create mode 100644 native/scripts/src/spawner/mod.rs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4db242c..fed708e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,6 +38,7 @@ jobs: env: TARGET_TRIPLET: ${{ matrix.arch }}-${{ matrix.vendor }}-${{ matrix.platform }}${{ matrix.env }} CARGO_BUILD: cargo build --target + CARGO_BUILD_RUSTFLAGS: ${{ startsWith(matrix.os, 'windows') && '-Ccodegen-units=1' || '' }} steps: - name: checkout @@ -62,7 +63,7 @@ jobs: if: inputs.release run: | cd native/ - ${{ env.CARGO_BUILD}} ${{ env.TARGET_TRIPLET}} --release + ${{ env.CARGO_BUILD }} ${{ env.TARGET_TRIPLET}} --release - name: Artifacts uses: actions/upload-artifact@v3 with: diff --git a/native/Cargo.lock b/native/Cargo.lock index 3b83ca7..1f074a9 100644 --- a/native/Cargo.lock +++ b/native/Cargo.lock @@ -2,6 +2,52 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "abi_stable" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69d6512d3eb05ffe5004c59c206de7f99c34951504056ce23fc953842f12c445" +dependencies = [ + "abi_stable_derive", + "abi_stable_shared", + "const_panic", + "core_extensions", + "generational-arena", + "libloading", + "lock_api", + "parking_lot", + "paste", + "repr_offset", + "rustc_version", + "serde", + "serde_derive", +] + +[[package]] +name = "abi_stable_derive" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7178468b407a4ee10e881bc7a328a65e739f0863615cca4429d43916b05e898" +dependencies = [ + "abi_stable_shared", + "as_derive_utils", + "core_extensions", + "proc-macro2", + "quote", + "rustc_version", + "syn 1.0.109", + "typed-arena", +] + +[[package]] +name = "abi_stable_shared" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b5df7688c123e63f4d4d649cba63f2967ba7f7861b1664fca3f77d3dad2b63" +dependencies = [ + "core_extensions", +] + [[package]] name = "addr2line" version = "0.17.0" @@ -17,6 +63,18 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "as_derive_utils" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff3c96645900a44cf11941c111bd08a6573b0e2f9f69bc9264b179d8fae753c4" +dependencies = [ + "core_extensions", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -38,6 +96,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "cc" version = "1.0.72" @@ -50,6 +114,27 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "const_panic" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6051f239ecec86fde3410901ab7860d458d160371533842974fc61f96d15879b" + +[[package]] +name = "core_extensions" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92c71dc07c9721607e7a16108336048ee978c3a8b129294534272e8bac96c0ee" +dependencies = [ + "core_extensions_proc_macros", +] + +[[package]] +name = "core_extensions_proc_macros" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f3b219d28b6e3b4ac87bc1fc522e0803ab22e055da177bff0068c4150c61a6" + [[package]] name = "crossbeam-channel" version = "0.5.4" @@ -95,12 +180,79 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "darling" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.38", +] + +[[package]] +name = "darling_macro" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.38", +] + [[package]] name = "either" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "generational-arena" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877e94aff08e743b651baaea359664321055749b398adff8740a7399af7796e7" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "gimli" version = "0.26.1" @@ -116,7 +268,7 @@ checksum = "8e4afd9ad95555081e109fe1d21f2a30c691b5f0919c67dfa690a2e1eb6bd51c" [[package]] name = "godot" version = "0.1.0" -source = "git+https://github.com/godot-rust/gdext?rev=b4e6fd6c9c23e0fd3a124c2893a9592c861ab780#b4e6fd6c9c23e0fd3a124c2893a9592c861ab780" +source = "git+https://github.com/titannano/gdext?rev=a5d17342b7b47e8af652a6a733f497c468bbd59a#a5d17342b7b47e8af652a6a733f497c468bbd59a" dependencies = [ "godot-core", "godot-macros", @@ -125,7 +277,7 @@ dependencies = [ [[package]] name = "godot-bindings" version = "0.1.0" -source = "git+https://github.com/godot-rust/gdext?rev=b4e6fd6c9c23e0fd3a124c2893a9592c861ab780#b4e6fd6c9c23e0fd3a124c2893a9592c861ab780" +source = "git+https://github.com/titannano/gdext?rev=a5d17342b7b47e8af652a6a733f497c468bbd59a#a5d17342b7b47e8af652a6a733f497c468bbd59a" dependencies = [ "godot4-prebuilt", ] @@ -133,7 +285,7 @@ dependencies = [ [[package]] name = "godot-codegen" version = "0.1.0" -source = "git+https://github.com/godot-rust/gdext?rev=b4e6fd6c9c23e0fd3a124c2893a9592c861ab780#b4e6fd6c9c23e0fd3a124c2893a9592c861ab780" +source = "git+https://github.com/titannano/gdext?rev=a5d17342b7b47e8af652a6a733f497c468bbd59a#a5d17342b7b47e8af652a6a733f497c468bbd59a" dependencies = [ "godot-bindings", "godot-fmt", @@ -147,7 +299,7 @@ dependencies = [ [[package]] name = "godot-core" version = "0.1.0" -source = "git+https://github.com/godot-rust/gdext?rev=b4e6fd6c9c23e0fd3a124c2893a9592c861ab780#b4e6fd6c9c23e0fd3a124c2893a9592c861ab780" +source = "git+https://github.com/titannano/gdext?rev=a5d17342b7b47e8af652a6a733f497c468bbd59a#a5d17342b7b47e8af652a6a733f497c468bbd59a" dependencies = [ "glam", "godot-bindings", @@ -158,7 +310,7 @@ dependencies = [ [[package]] name = "godot-ffi" version = "0.1.0" -source = "git+https://github.com/godot-rust/gdext?rev=b4e6fd6c9c23e0fd3a124c2893a9592c861ab780#b4e6fd6c9c23e0fd3a124c2893a9592c861ab780" +source = "git+https://github.com/titannano/gdext?rev=a5d17342b7b47e8af652a6a733f497c468bbd59a#a5d17342b7b47e8af652a6a733f497c468bbd59a" dependencies = [ "godot-bindings", "godot-codegen", @@ -168,7 +320,7 @@ dependencies = [ [[package]] name = "godot-fmt" version = "0.1.0" -source = "git+https://github.com/godot-rust/gdext?rev=b4e6fd6c9c23e0fd3a124c2893a9592c861ab780#b4e6fd6c9c23e0fd3a124c2893a9592c861ab780" +source = "git+https://github.com/titannano/gdext?rev=a5d17342b7b47e8af652a6a733f497c468bbd59a#a5d17342b7b47e8af652a6a733f497c468bbd59a" dependencies = [ "proc-macro2", ] @@ -176,17 +328,48 @@ dependencies = [ [[package]] name = "godot-macros" version = "0.1.0" -source = "git+https://github.com/godot-rust/gdext?rev=b4e6fd6c9c23e0fd3a124c2893a9592c861ab780#b4e6fd6c9c23e0fd3a124c2893a9592c861ab780" +source = "git+https://github.com/titannano/gdext?rev=a5d17342b7b47e8af652a6a733f497c468bbd59a#a5d17342b7b47e8af652a6a733f497c468bbd59a" dependencies = [ + "godot-bindings", "proc-macro2", "quote", "venial", ] +[[package]] +name = "godot-rust-script" +version = "0.1.0" +source = "git+https://github.com/titannano/godot-rust-script?rev=928159e6f6a73a249d5504ca6c136809b5ed07c0#928159e6f6a73a249d5504ca6c136809b5ed07c0" +dependencies = [ + "abi_stable", + "cfg-if", + "godot", + "godot-rust-script-derive", + "itertools", + "rand", +] + +[[package]] +name = "godot-rust-script-derive" +version = "0.1.0" +source = "git+https://github.com/titannano/godot-rust-script?rev=928159e6f6a73a249d5504ca6c136809b5ed07c0#928159e6f6a73a249d5504ca6c136809b5ed07c0" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.38", +] + [[package]] name = "godot4-prebuilt" version = "0.0.0" -source = "git+https://github.com/godot-rust/godot4-prebuilt?branch=4.1#23477b8096a90c3798ab3558b776e9743e59ea2a" +source = "git+https://github.com/godot-rust/godot4-prebuilt?branch=4.1.1#fca6897dbfb1a2d9387f81491acd77f6f091b8c4" + +[[package]] +name = "hashbrown" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" [[package]] name = "heck" @@ -203,6 +386,22 @@ dependencies = [ "libc", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "itertools" version = "0.10.3" @@ -229,15 +428,35 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.117" +version = "0.2.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "lock_api" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] [[package]] name = "memchr" -version = "2.4.1" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memoffset" @@ -279,10 +498,12 @@ version = "0.4.0" dependencies = [ "backtrace", "godot", + "godot-rust-script", "itertools", "lerp", "num", "rayon", + "scripts", ] [[package]] @@ -371,6 +592,27 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683751d591e6d81200c39fb0d1032608b77724f34114db54f571ff1317b337c0" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c11e44798ad209ccdd91fc192f0526a369a01234f7373e1b141c96d7cee4f0e" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.38", +] + [[package]] name = "object" version = "0.27.1" @@ -380,17 +622,55 @@ dependencies = [ "memchr", ] +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + [[package]] name = "paste" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro-crate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -404,6 +684,36 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "rayon" version = "1.5.2" @@ -428,6 +738,15 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags", +] + [[package]] name = "regex" version = "1.8.4" @@ -443,18 +762,143 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +[[package]] +name = "repr_offset" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb1070755bd29dffc19d0971cab794e607839ba2ef4b69a9e6fbc8733c1b72ea" +dependencies = [ + "tstr", +] + [[package]] name = "rustc-demangle" version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "scripts" +version = "0.1.0" +dependencies = [ + "backtrace", + "godot-rust-script", + "num_enum", +] + +[[package]] +name = "semver" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" + +[[package]] +name = "serde" +version = "1.0.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "smallvec" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tstr" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cca3264971090dec0feef3b455a3c178f02762f7550cf4592991ac64b3be2d7e" +dependencies = [ + "tstr_proc_macros", +] + +[[package]] +name = "tstr_proc_macros" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78122066b0cb818b8afd08f7ed22f7fdbc3e90815035726f0840d0d26c0747a" + +[[package]] +name = "typed-arena" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" + [[package]] name = "unicode-ident" version = "1.0.6" @@ -470,3 +914,97 @@ dependencies = [ "proc-macro2", "quote", ] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "winnow" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b" +dependencies = [ + "memchr", +] diff --git a/native/Cargo.toml b/native/Cargo.toml index ef27fe8..eb3a545 100644 --- a/native/Cargo.toml +++ b/native/Cargo.toml @@ -1,3 +1,13 @@ +[workspace] +resolver = "2" + +members = [ + "scripts", +] + +[workspace.dependencies] +godot-rust-script = { git = "https://github.com/titannano/godot-rust-script", rev = "928159e6f6a73a249d5504ca6c136809b5ed07c0", default-features = false } + [package] name = "native" version = "0.4.0" @@ -7,9 +17,11 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -godot = { git = "https://github.com/godot-rust/gdext", rev = "b4e6fd6c9c23e0fd3a124c2893a9592c861ab780" } +godot = { git = "https://github.com/titannano/gdext", rev = "a5d17342b7b47e8af652a6a733f497c468bbd59a" } lerp = "0.4.0" backtrace = "0.3.64" num = "0.4.0" rayon = "1.5.1" itertools = "0.10.3" +godot-rust-script = { workspace = true, features = ["runtime"] } +scripts = { path = "./scripts" } diff --git a/native/scripts/Cargo.toml b/native/scripts/Cargo.toml new file mode 100644 index 0000000..22abe60 --- /dev/null +++ b/native/scripts/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "scripts" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["dylib", "rlib"] + +[dependencies] +godot-rust-script = { workspace = true, features = ["scripts"] } +backtrace = "0.3.64" +num_enum = "0.7.1" diff --git a/native/scripts/src/lib.rs b/native/scripts/src/lib.rs new file mode 100644 index 0000000..5152bc8 --- /dev/null +++ b/native/scripts/src/lib.rs @@ -0,0 +1,5 @@ +mod particles; +mod scene_object_registry; +mod spawner; + +godot_rust_script::setup_library!(); diff --git a/native/scripts/src/particles/dust_particles.rs b/native/scripts/src/particles/dust_particles.rs new file mode 100644 index 0000000..e11664e --- /dev/null +++ b/native/scripts/src/particles/dust_particles.rs @@ -0,0 +1,68 @@ +use godot_rust_script::{ + godot::{ + engine::{GpuParticles3D, PrimitiveMesh, StandardMaterial3D}, + prelude::{godot_error, Gd}, + }, + godot_script_impl, GodotScript, +}; + +/// Dust Particle behavior for a particle system. +/// This is used for the rotor effects +#[derive(GodotScript, Debug)] +#[script(base = GpuParticles3D)] +struct DustParticles { + /// The strength of the emitted dust. + /// This is used for the rotor effects + /** + * This is more documentation + * please read it carefully + */ + #[prop(get = Self::strength, set = Self::set_strength)] + #[export(range(min = 0.1, max = 1.5, step = 0.05))] + strength: f64, + base: Gd, +} + +#[godot_script_impl] +impl DustParticles { + pub fn _ready(&mut self) { + self.set_strength(0.0); + } + + /// get effect strength + fn strength(&self) -> f64 { + self.strength + } + + pub fn set_strength(&mut self, value: f64) { + self.strength = value; + + let is_emitting = value > 0.0; + + if self.base.is_emitting() != is_emitting { + self.base.set_emitting(is_emitting); + } + + if !self.base.is_emitting() { + return; + } + + let Some(mesh) = self.base.get_draw_pass_mesh(1) else { + godot_error!("Draw pass 1 does not exist!"); + return; + }; + + let mesh: Gd = mesh.cast(); + + let Some(material) = mesh.get_material() else { + godot_error!("mesh has no material!"); + return; + }; + + let mut material: Gd = material.cast(); + + let distance = (100.0 * (1.0 - value)).max(2.0); + + material.set_proximity_fade_distance(distance as f32); + } +} diff --git a/native/scripts/src/particles/mod.rs b/native/scripts/src/particles/mod.rs new file mode 100644 index 0000000..6617696 --- /dev/null +++ b/native/scripts/src/particles/mod.rs @@ -0,0 +1 @@ +mod dust_particles; diff --git a/native/scripts/src/scene_object_registry.rs b/native/scripts/src/scene_object_registry.rs new file mode 100644 index 0000000..7b2efed --- /dev/null +++ b/native/scripts/src/scene_object_registry.rs @@ -0,0 +1,461 @@ +use num_enum::TryFromPrimitive; + +#[derive(TryFromPrimitive)] +#[repr(u8)] +enum Powerlines { + LeftRight = 0x0E, + TopBottom = 0x0F, + HighTopBottom = 0x10, + LeftHighRight = 0x11, + TopHighBottom = 0x12, + HighLeftRight = 0x13, + BottomRight = 0x14, + BottomLeft = 0x15, + TopLeft = 0x16, + TopRight = 0x17, + RightTopBottom = 0x18, + LeftBottomRight = 0x19, + TopLeftBottom = 0x1A, + LeftTopRight = 0x1B, + LeftTopBottomRight = 0x1C, + BridgeTopBottom = 0x5C, +} + +impl Powerlines { + fn as_str(&self) -> &'static str { + match self { + Powerlines::LeftRight => "res://resources/Objects/Networks/Powerline/left_right.tscn", + Powerlines::TopBottom => "res://resources/Objects/Networks/Powerline/top_bottom.tscn", + Powerlines::HighTopBottom => { + "res://resources/Objects/Networks/Powerline/high_top_bottom.tscn" + } + Powerlines::LeftHighRight => { + "res://resources/Objects/Networks/Powerline/left_high_right.tscn" + } + Powerlines::TopHighBottom => { + "res://resources/Objects/Networks/Powerline/top_high_bottom.tscn" + } + Powerlines::HighLeftRight => { + "res://resources/Objects/Networks/Powerline/high_left_right.tscn" + } + Powerlines::BottomRight => { + "res://resources/Objects/Networks/Powerline/bottom_right.tscn" + } + Powerlines::BottomLeft => "res://resources/Objects/Networks/Powerline/bottom_left.tscn", + Powerlines::TopLeft => "res://resources/Objects/Networks/Powerline/top_left.tscn", + Powerlines::TopRight => "res://resources/Objects/Networks/Powerline/top_right.tscn", + Powerlines::RightTopBottom => { + "res://resources/Objects/Networks/Powerline/right_top_bottom.tscn" + } + Powerlines::LeftBottomRight => { + "res://resources/Objects/Networks/Powerline/left_bottom_right.tscn" + } + Powerlines::TopLeftBottom => { + "res://resources/Objects/Networks/Powerline/top_left_bottom.tscn" + } + Powerlines::LeftTopRight => { + "res://resources/Objects/Networks/Powerline/left_top_right.tscn" + } + Powerlines::LeftTopBottomRight => { + "res://resources/Objects/Networks/Powerline/left_top_bottom_right.tscn" + } + Powerlines::BridgeTopBottom => { + "res://resources/Objects/Networks/Powerline/bridge_top_bottom.tscn" + } + } + } +} + +#[derive(TryFromPrimitive)] +#[repr(u8)] +enum Road { + LeftRight = 0x1D, + TopBottom = 0x1E, + HighTopBottom = 0x1F, + LeftHighRight = 0x20, + TopHighBottom = 0x21, + HighLeftRight = 0x22, + TopRight = 0x23, + BottomRight = 0x24, + BottomLeft = 0x25, + TopLeft = 0x26, + RightTopBottom = 0x27, + LeftBottomRight = 0x28, + TopLeftBottom = 0x29, + LeftTopRight = 0x2A, + LeftTopBottomRight = 0x2B, + LeftRightPowerTopBottom = 0x43, + TopBottomPowerLeftRight = 0x44, +} + +impl Road { + fn as_str(&self) -> &'static str { + match self { + Self::LeftRight => "res://resources/Objects/Networks/Road/left_right.tscn", + Self::TopBottom => "res://resources/Objects/Networks/Road/top_bottom.tscn", + Self::HighTopBottom => "res://resources/Objects/Networks/Road/high_top_bottom.tscn", + Self::LeftHighRight => "res://resources/Objects/Networks/Road/left_high_right.tscn", + Self::TopHighBottom => "res://resources/Objects/Networks/Road/top_high_bottom.tscn", + Self::HighLeftRight => "res://resources/Objects/Networks/Road/high_left_right.tscn", + Self::TopRight => "res://resources/Objects/Networks/Road/top_right.tscn", + Self::BottomRight => "res://resources/Objects/Networks/Road/bottom_right.tscn", + Self::BottomLeft => "res://resources/Objects/Networks/Road/bottom_left.tscn", + Self::TopLeft => "res://resources/Objects/Networks/Road/top_left.tscn", + Self::RightTopBottom => "res://resources/Objects/Networks/Road/right_top_bottom.tscn", + Self::LeftBottomRight => "res://resources/Objects/Networks/Road/left_bottom_right.tscn", + Self::TopLeftBottom => "res://resources/Objects/Networks/Road/top_left_bottom.tscn", + Self::LeftTopRight => "res://resources/Objects/Networks/Road/left_top_right.tscn", + Self::LeftTopBottomRight => { + "res://resources/Objects/Networks/Road/left_top_bottom_right.tscn" + } + Self::LeftRightPowerTopBottom => { + "res://resources/Objects/Networks/Road/left_right_power_top_bottom.tscn" + } + Self::TopBottomPowerLeftRight => { + "res://resources/Objects/Networks/Road/top_bottom_power_left_right.tscn" + } + } + } +} + +#[derive(TryFromPrimitive)] +#[repr(u8)] +enum SuspensionBridge { + StartBottom = 0x51, + MiddleBottom = 0x52, + Center = 0x53, + MiddleTop = 0x54, + EndTop = 0x55, +} + +impl SuspensionBridge { + fn as_str(&self) -> &'static str { + match self { + Self::StartBottom => { + "res://resources/Objects/Networks/Bridge/bridge_suspension_start_bottom.tscn" + } + Self::MiddleBottom => { + "res://resources/Objects/Networks/Bridge/bridge_suspension_middle_bottom.tscn" + } + Self::Center => "res://resources/Objects/Networks/Bridge/bridge_suspension_center.tscn", + Self::MiddleTop => { + "res://resources/Objects/Networks/Bridge/bridge_suspension_middle_top.tscn" + } + Self::EndTop => { + "res://resources/Objects/Networks/Bridge/bridge_suspension_end_top.tscn" + } + } + } +} + +#[derive(TryFromPrimitive)] +#[repr(u8)] +enum PylonBridge { + RaisingTowerTopBottom = 0x56, + BridgeTopA = 0x57, + BridgeTopB = 0x58, +} + +impl PylonBridge { + fn as_str(&self) -> &'static str { + match self { + Self::RaisingTowerTopBottom => { + "res://resources/Objects/Networks/Bridge/bridge_raising_tower_top_bottom.tscn" + } + Self::BridgeTopA => "res://resources/Objects/Networks/Bridge/bridge_top.tscn", + Self::BridgeTopB => "res://resources/Objects/Networks/Bridge/bridge_top.tscn", + } + } +} + +pub fn networks(id: u8) -> Option<&'static str> { + // Powerlines + Powerlines::try_from_primitive(id) + .ok() + .as_ref() + .map(Powerlines::as_str) + .or_else(|| Road::try_from_primitive(id).ok().as_ref().map(Road::as_str)) + .or_else(|| { + SuspensionBridge::try_from_primitive(id) + .ok() + .as_ref() + .map(SuspensionBridge::as_str) + }) + .or_else(|| { + PylonBridge::try_from_primitive(id) + .ok() + .as_ref() + .map(PylonBridge::as_str) + }) +} + +#[derive(TryFromPrimitive)] +#[repr(u8)] +enum Buildings { + ParkSmall = 0x0D, + TreeSingle = 0x06, + HomeMiddleClass1 = 0x73, + HomeMiddleClass2 = 0x74, + HomeMiddleClass3 = 0x75, + HomeMiddleClass4 = 0x76, + HomeMiddleClass5 = 0x77, + Church = 0xF7, + OfficeBuildingMedium1 = 0x96, + OfficeBuildingMedium2 = 0x98, + OfficeBuildingMedium3 = 0x9A, + OfficeBuildingMedium4 = 0x9B, + OfficeBuildingMedium5 = 0x9C, + OfficeBuildingMedium6 = 0x9D, + AbandonedBuilding1 = 0x8A, + AbandonedBuilding2 = 0x8B, + AbandonedBuilding3 = 0xAA, + AbandonedBuilding4 = 0xAB, + AbandonedBuilding5 = 0xAC, + AbandonedBuilding6 = 0xAD, + HomeUpperClass1 = 0x78, + HomeUpperClass2 = 0x79, + HomeUpperClass3 = 0x7A, + HomeUpperClass4 = 0x7B, + Tarmac = 0xE6, + TarmacRadar = 0xEA, + Construction1 = 0xC2, + Construction2 = 0xC3, + Construction3 = 0xA6, + Construction4 = 0xA7, + Construction5 = 0xA8, + Construction6 = 0xA9, + Construction7 = 0x88, + Construction8 = 0x89, + AirportWarehouse = 0xE3, + AirportBuilding1 = 0xE4, + AirportBuilding2 = 0xE5, + AirportHangar1 = 0xE8, + AirportRunway = 0xDD, + AirportRunwayIntersection = 0xDF, + Hangar2 = 0xF6, + CondominiumsMedium1 = 0x91, + CondominiumsMedium2 = 0x92, + CondominiumsMedium3 = 0x93, + CondominiumsLarge1 = 0xB0, + CondominiumsLarge2 = 0xB1, + FactorySmall1 = 0xA0, + FactorySmall2 = 0xA1, + FactorySmall3 = 0xA2, + FactorySmall4 = 0xA3, + FactorySmall5 = 0xA4, + FactorySmall6 = 0xA5, + StationPolice = 0xD2, + ApartmentsMedium1 = 0x8F, + ApartmentsMedium2 = 0x90, + ToyStore = 0x83, + IndustrialSubstation = 0x87, + OfficesSmall1 = 0x80, + OfficesSmall2 = 0x81, + OfficesHistoric = 0xBA, + WaterPump = 0xDC, + StationHospital = 0xD1, + ConvenienceStore = 0x7E, + StationGas1 = 0x7C, + StationGas2 = 0x7F, + HomeLowerClass1 = 0x70, + HomeLowerClass2 = 0x71, + HomeLowerClass3 = 0x72, + Warehouse = 0x82, + AirportCivilianControlTower = 0xE1, + StationFire = 0xD3, + PowerplantMicrowave = 0xCD, + ResortHotel = 0x97, + ApartmentsLarge1 = 0xAE, + ApartmentsLarge2 = 0xAF, + ApartmentsSmall1 = 0x8C, + ApartmentsSmall2 = 0x8D, + ApartmentsSmall3 = 0x8E, + TreeCouple = 0x07, + ChemicalStorage = 0x85, + ChemicalProcessing1 = 0xBC, + ChemicalProcessing2 = 0x9F, + School = 0xD6, + Library = 0xF5, + Marina = 0xF8, + WarehouseLarge1 = 0xC0, + WarehouseLarge2 = 0xC1, + WarehouseSmall1 = 0x84, + WarehouseSmall2 = 0x86, + WarehouseMedium = 0x9E, + BbInn = 0x7D, + College = 0xD9, + ArcologyPlymouth = 0xFB, + ArcologyForest = 0xFC, + ArcologyDarco = 0xFD, + ArcologyLaunch = 0xFE, + MayorsHouse = 0xF3, + Museum = 0xD4, + OfficeRetail = 0x99, + ParkingLot = 0xB9, + ShoppingCentre = 0x94, + Theatre = 0xB5, + WaterTreatment = 0xF4, +} + +impl Buildings { + fn as_str(&self) -> &'static str { + match self { + Self::ParkSmall => "res://resources/Objects/Buildings/park_small.tscn", + Self::TreeSingle => "res://resources/Objects/Buildings/tree_single.tscn", + Self::HomeMiddleClass1 => "res://resources/Objects/Buildings/home_middle_class_1.tscn", + Self::HomeMiddleClass2 => "res://resources/Objects/Buildings/home_middle_class_2.tscn", + Self::HomeMiddleClass3 => "res://resources/Objects/Buildings/home_middle_class_3.tscn", + Self::HomeMiddleClass4 => "res://resources/Objects/Buildings/home_middle_class_4.tscn", + Self::HomeMiddleClass5 => "res://resources/Objects/Buildings/home_middle_class_5.tscn", + Self::Church => "res://resources/Objects/Buildings/church.tscn", + Self::OfficeBuildingMedium1 => { + "res://resources/Objects/Buildings/office_building_medium_1.tscn" + } + Self::OfficeBuildingMedium2 => { + "res://resources/Objects/Buildings/office_building_medium_2.tscn" + } + Self::OfficeBuildingMedium3 => { + "res://resources/Objects/Buildings/office_building_medium_3.tscn" + } + Self::OfficeBuildingMedium4 => { + "res://resources/Objects/Buildings/office_building_medium_4.tscn" + } + Self::OfficeBuildingMedium5 => { + "res://resources/Objects/Buildings/office_building_medium_5.tscn" + } + Self::OfficeBuildingMedium6 => { + "res://resources/Objects/Buildings/office_building_medium_6.tscn" + } + Self::AbandonedBuilding1 => { + "res://resources/Objects/Buildings/abandoned_building_1.tscn" + } + Self::AbandonedBuilding2 => { + "res://resources/Objects/Buildings/abandoned_building_2.tscn" + } + Self::AbandonedBuilding3 => { + "res://resources/Objects/Buildings/abandoned_building_3.tscn" + } + Self::AbandonedBuilding4 => { + "res://resources/Objects/Buildings/abandoned_building_4.tscn" + } + Self::AbandonedBuilding5 => { + "res://resources/Objects/Buildings/abandoned_building_5.tscn" + } + Self::AbandonedBuilding6 => { + "res://resources/Objects/Buildings/abandoned_building_6.tscn" + } + Self::HomeUpperClass1 => "res://resources/Objects/Buildings/home_upper_class_1.tscn", + Self::HomeUpperClass2 => "res://resources/Objects/Buildings/home_upper_class_2.tscn", + Self::HomeUpperClass3 => "res://resources/Objects/Buildings/home_upper_class_3.tscn", + Self::HomeUpperClass4 => "res://resources/Objects/Buildings/home_upper_class_4.tscn", + Self::Tarmac => "res://resources/Objects/Ground/tarmac.tscn", + Self::TarmacRadar => "res://resources/Objects/Buildings/tarmac_radar.tscn", + Self::Construction1 => "res://resources/Objects/Buildings/construction_1-2.tscn", + Self::Construction2 => "res://resources/Objects/Buildings/construction_1-2.tscn", + Self::Construction3 => "res://resources/Objects/Buildings/construction_3.tscn", + Self::Construction4 => "res://resources/Objects/Buildings/construction_4.tscn", + Self::Construction5 => "res://resources/Objects/Buildings/construction_5.tscn", + Self::Construction6 => "res://resources/Objects/Buildings/construction_6.tscn", + Self::Construction7 => "res://resources/Objects/Buildings/construction_7.tscn", + Self::Construction8 => "res://resources/Objects/Buildings/construction_8.tscn", + Self::AirportWarehouse => "res://resources/Objects/Buildings/airport_warehouse.tscn", + Self::AirportBuilding1 => "res://resources/Objects/Buildings/airport_building_1.tscn", + Self::AirportBuilding2 => "res://resources/Objects/Buildings/airport_building_2.tscn", + Self::AirportHangar1 => "res://resources/Objects/Buildings/airport_hangar_1.tscn", + Self::AirportRunway => "res://resources/Objects/Buildings/airport_runway.tscn", + Self::AirportRunwayIntersection => { + "res://resources/Objects/Buildings/airport_runway_intersection.tscn" + } + Self::Hangar2 => "res://resources/Objects/Buildings/hangar_2.tscn", + Self::CondominiumsMedium1 => { + "res://resources/Objects/Buildings/condominiums_medium_1.tscn" + } + Self::CondominiumsMedium2 => { + "res://resources/Objects/Buildings/condominiums_medium_2.tscn" + } + Self::CondominiumsMedium3 => { + "res://resources/Objects/Buildings/condominiums_medium_3.tscn" + } + Self::CondominiumsLarge1 => { + "res://resources/Objects/Buildings/condominiums_large_1.tscn" + } + Self::CondominiumsLarge2 => { + "res://resources/Objects/Buildings/condominiums_large_2.tscn" + } + Self::FactorySmall1 => "res://resources/Objects/Buildings/factory_small_1.tscn", + Self::FactorySmall2 => "res://resources/Objects/Buildings/factory_small_2.tscn", + Self::FactorySmall3 => "res://resources/Objects/Buildings/factory_small_3.tscn", + Self::FactorySmall4 => "res://resources/Objects/Buildings/factory_small_4.tscn", + Self::FactorySmall5 => "res://resources/Objects/Buildings/factory_small_5.tscn", + Self::FactorySmall6 => "res://resources/Objects/Buildings/factory_small_6.tscn", + Self::StationPolice => "res://resources/Objects/Buildings/station_police.tscn", + Self::ApartmentsMedium1 => "res://resources/Objects/Buildings/apartments_medium_1.tscn", + Self::ApartmentsMedium2 => "res://resources/Objects/Buildings/apartments_medium_2.tscn", + Self::ToyStore => "res://resources/Objects/Buildings/toy_store.tscn", + Self::IndustrialSubstation => { + "res://resources/Objects/Buildings/industrial_substation.tscn" + } + Self::OfficesSmall1 => "res://resources/Objects/Buildings/offices_small_1.tscn", + Self::OfficesSmall2 => "res://resources/Objects/Buildings/offices_small_2.tscn", + Self::OfficesHistoric => "res://resources/Objects/Buildings/offices_historic.tscn", + Self::WaterPump => "res://resources/Objects/Buildings/water_pump.tscn", + Self::StationHospital => "res://resources/Objects/Buildings/station_hospital.tscn", + Self::ConvenienceStore => "res://resources/Objects/Buildings/convenience_store.tscn", + Self::StationGas1 => "res://resources/Objects/Buildings/station_gas_1.tscn", + Self::StationGas2 => "res://resources/Objects/Buildings/station_gas_2.tscn", + Self::HomeLowerClass1 => "res://resources/Objects/Buildings/home_lower_class_1.tscn", + Self::HomeLowerClass2 => "res://resources/Objects/Buildings/home_lower_class_2.tscn", + Self::HomeLowerClass3 => "res://resources/Objects/Buildings/home_lower_class_3.tscn", + Self::Warehouse => "res://resources/Objects/Buildings/warehouse.tscn", + Self::AirportCivilianControlTower => { + "res://resources/Objects/Buildings/airport_civilian_control_tower.tscn" + } + Self::StationFire => "res://resources/Objects/Buildings/station_fire.tscn", + Self::PowerplantMicrowave => { + "res://resources/Objects/Buildings/powerplant_microwave.tscn" + } + Self::ResortHotel => "res://resources/Objects/Buildings/resort_hotel.tscn", + Self::ApartmentsLarge1 => "res://resources/Objects/Buildings/apartments_large_1.tscn", + Self::ApartmentsLarge2 => "res://resources/Objects/Buildings/apartments_large_2.tscn", + Self::ApartmentsSmall1 => "res://resources/Objects/Buildings/apartments_small_1.tscn", + Self::ApartmentsSmall2 => "res://resources/Objects/Buildings/apartments_small_2.tscn", + Self::ApartmentsSmall3 => "res://resources/Objects/Buildings/apartments_small_3.tscn", + Self::TreeCouple => "res://resources/Objects/Buildings/tree_couple.tscn", + Self::ChemicalStorage => "res://resources/Objects/Buildings/chemical_storage.tscn", + Self::ChemicalProcessing1 => { + "res://resources/Objects/Buildings/chemical_processing_1.tscn" + } + Self::ChemicalProcessing2 => { + "res://resources/Objects/Buildings/chemical_processing_2.tscn" + } + Self::School => "res://resources/Objects/Buildings/school.tscn", + Self::Library => "res://resources/Objects/Buildings/library.tscn", + Self::Marina => "res://resources/Objects/Buildings/marina.tscn", + Self::WarehouseLarge1 => "res://resources/Objects/Buildings/warehouse_large_1.tscn", + Self::WarehouseLarge2 => "res://resources/Objects/Buildings/warehouse_large_2.tscn", + Self::WarehouseSmall1 => "res://resources/Objects/Buildings/warehouse_small_1.tscn", + Self::WarehouseSmall2 => "res://resources/Objects/Buildings/warehouse_small_2.tscn", + Self::WarehouseMedium => "res://resources/Objects/Buildings/warehouse_medium.tscn", + Self::BbInn => "res://resources/Objects/Buildings/bb_inn.tscn", + Self::College => "res://resources/Objects/Buildings/college.tscn", + Self::ArcologyPlymouth => "res://resources/Objects/Buildings/arcology_plymouth.tscn", + Self::ArcologyForest => "res://resources/Objects/Buildings/arcology_forest.tscn", + Self::ArcologyDarco => "res://resources/Objects/Buildings/arcology_darco.tscn", + Self::ArcologyLaunch => "res://resources/Objects/Buildings/arcology_launch.tscn", + Self::MayorsHouse => "res://resources/Objects/Buildings/mayors_house.tscn", + Self::Museum => "res://resources/Objects/Buildings/museum.tscn", + Self::OfficeRetail => "res://resources/Objects/Buildings/office_retail.tscn", + Self::ParkingLot => "res://resources/Objects/Buildings/parking_lot.tscn", + Self::ShoppingCentre => "res://resources/Objects/Buildings/shopping_centre.tscn", + Self::Theatre => "res://resources/Objects/Buildings/theatre.tscn", + Self::WaterTreatment => "res://resources/Objects/Buildings/water_treatment.tscn", + } + } +} + +pub fn buildings(id: u8) -> Option<&'static str> { + Buildings::try_from_primitive(id) + .ok() + .as_ref() + .map(Buildings::as_str) +} diff --git a/native/scripts/src/spawner/car_spawner.rs b/native/scripts/src/spawner/car_spawner.rs new file mode 100644 index 0000000..be219b2 --- /dev/null +++ b/native/scripts/src/spawner/car_spawner.rs @@ -0,0 +1,112 @@ +use godot_rust_script::{ + godot::{ + engine::{ResourceLoader, Timer}, + prelude::{ + godot_error, Callable, GString, Gd, Node3D, NodePath, PackedScene, StringName, ToGodot, + }, + }, + godot_script_impl, GodotScript, +}; + +#[derive(Debug, GodotScript)] +#[script(base = Node3D)] +struct CarSpawner { + default_car: Option>, + car: Option>, + + #[export] + pub road_network_path: NodePath, + timer: Option>, + + base: Gd, +} + +#[godot_script_impl] +impl CarSpawner { + pub fn _init(&mut self) { + let mut loader = ResourceLoader::singleton(); + + self.default_car = loader + .load(GString::from( + "res://resources/Objects/Vehicles/car_station_wagon.tscn", + )) + .map(|res| res.cast()); + + self.car = loader + .load(GString::from("res://src/Objects/Vehicles/Car.gd")) + .map(|res| res.cast()); + } + + pub fn spawn_car(&mut self) { + let inst = self + .default_car + .as_ref() + .expect("failed to load default_car") + .instantiate(); + + let Some(mut inst) = inst else { + godot_error!("failed to instantiate car scene!"); + return; + }; + + inst.set( + StringName::from("road_network_path"), + self.road_network_path.to_variant(), + ); + + if let Some(mut parent) = self.base.get_parent() { + parent.add_child(inst.clone()); + } + + let Some(current_scene) = self + .base + .get_tree() + .and_then(|tree| tree.get_current_scene()) + else { + godot_error!("there is no active scene!"); + return; + }; + + inst.set_owner(current_scene); + + let mut inst: Gd = inst.cast(); + + inst.global_translate(self.base.get_global_transform().origin); + inst.call(StringName::from("activate"), &[]); + } + + pub fn start_auto_spawn(&mut self) { + let timer = match self.timer.as_mut() { + None => { + let mut timer = Timer::new_alloc(); + self.timer = Some(timer.clone()); + + self.base + .add_child_ex(timer.clone().upcast()) + .force_readable_name(true) + .done(); + + timer.connect( + StringName::from("timeout"), + Callable::from_object_method(self.base.clone(), "start_auto_spawn"), + ); + + self.timer.as_mut().unwrap() + } + + Some(timer) => timer, + }; + + timer.start_ex().time_sec(2.0).done(); + + self.spawn_car(); + } + + pub fn stop_auto_spawn(&mut self) { + let Some(timer) = self.timer.as_mut() else { + return; + }; + + timer.stop(); + } +} diff --git a/native/scripts/src/spawner/mod.rs b/native/scripts/src/spawner/mod.rs new file mode 100644 index 0000000..1b0d2b8 --- /dev/null +++ b/native/scripts/src/spawner/mod.rs @@ -0,0 +1 @@ +mod car_spawner; \ No newline at end of file diff --git a/native/src/lib.rs b/native/src/lib.rs index 98ef338..fd0be0f 100644 --- a/native/src/lib.rs +++ b/native/src/lib.rs @@ -1,8 +1,37 @@ mod terrain_builder; -use godot::prelude::{gdextension, ExtensionLibrary}; +use std::cell::RefCell; + +use godot::prelude::{gdextension, ExtensionLibrary, InitLevel}; +use godot_rust_script::{self, RustScriptExtensionLayer}; + +godot_rust_script::setup!(scripts); struct NativeLib; +thread_local! { + static RUST_SCRIPT_LAYER: RefCell = RefCell::new(godot_rust_script::init!()); +} + #[gdextension] -unsafe impl ExtensionLibrary for NativeLib {} +unsafe impl ExtensionLibrary for NativeLib { + fn on_level_init(level: InitLevel) { + match level { + InitLevel::Core => (), + InitLevel::Servers => (), + InitLevel::Scene => { + RUST_SCRIPT_LAYER.with_borrow_mut(|layer| layer.initialize()); + } + InitLevel::Editor => (), + } + } + + fn on_level_deinit(level: InitLevel) { + match level { + InitLevel::Editor => (), + InitLevel::Scene => RUST_SCRIPT_LAYER.with_borrow_mut(|layer| layer.deinitialize()), + InitLevel::Servers => {} + InitLevel::Core => (), + } + } +} diff --git a/native/src/terrain_builder.rs b/native/src/terrain_builder.rs index 6ad08dd..325846e 100644 --- a/native/src/terrain_builder.rs +++ b/native/src/terrain_builder.rs @@ -6,7 +6,7 @@ mod ybuffer; use godot::engine::mesh::PrimitiveType; use godot::engine::{ArrayMesh, Material, SurfaceTool}; -use godot::prelude::meta::VariantMetadata; +use godot::prelude::meta::GodotType; use godot::prelude::*; use std::cmp::{max, min}; @@ -27,12 +27,12 @@ use ybuffer::{HashMapYBuffer, YBuffer}; pub use terrain_rotation::TerrainRotation; -struct Shared(T); +struct Shared(T); -unsafe impl Send for Shared {} -unsafe impl Sync for Shared {} +unsafe impl Send for Shared {} +unsafe impl Sync for Shared {} -impl Deref for Shared { +impl Deref for Shared { type Target = T; fn deref(&self) -> &Self::Target { @@ -40,7 +40,7 @@ impl Deref for Shared { } } -impl Shared { +impl Shared { fn inner(self) -> T { self.0 } @@ -207,11 +207,11 @@ impl TerrainBuilder { } fn tilelist(&self) -> Shared { - Shared(self.tilelist.share()) + Shared(self.tilelist.clone()) } fn materials(&self) -> Shared { - Shared(self.materials.share()) + Shared(self.materials.clone()) } fn rotation(&self) -> &Gd { @@ -506,7 +506,7 @@ impl TerrainBuilderFactory { rotation: Gd, materials: Dictionary, ) -> Gd { - Gd::new(TerrainBuilder { + Gd::from_object(TerrainBuilder { tile_size: 16, city_size: 0, tile_height: 8, diff --git a/resources/Objects/Spawner/CarSpawner.tscn b/resources/Objects/Spawner/CarSpawner.tscn index cc1081d..341cc63 100644 --- a/resources/Objects/Spawner/CarSpawner.tscn +++ b/resources/Objects/Spawner/CarSpawner.tscn @@ -1,6 +1,6 @@ -[gd_scene load_steps=4 format=3 uid="uid://rup3fivpcq5r"] +[gd_scene load_steps=4 format=3 uid="uid://blyermwgncstx"] -[ext_resource type="Script" path="res://src/Objects/Spawner/CarSpawner.gd" id="1"] +[ext_resource type="Script" path="res://native/scripts/src/spawner/car_spawner.rs" id="1_c5pws"] [sub_resource type="StandardMaterial3D" id="1"] albedo_color = Color(1, 0, 0, 1) @@ -12,7 +12,8 @@ bottom_radius = 0.1 height = 200.0 [node name="CarSpawner" type="Marker3D"] -script = ExtResource("1") +script = ExtResource("1_c5pws") +road_network_path = null [node name="CSGMesh3D" type="CSGMesh3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 100, 0) diff --git a/resources/main.tscn b/resources/main.tscn index bd3f0d6..bd74e52 100644 --- a/resources/main.tscn +++ b/resources/main.tscn @@ -87,6 +87,7 @@ transform = Transform3D(1, 0, 0, 0, 0.847724, 0.530437, 0, -0.530437, 0.847724, script = ExtResource("10") snap = true track_y_axis = true +active = true [node name="DebugCameraAnchor" type="Marker3D" parent="SubViewportContainer/SubViewport/Schweizer_300"] process_mode = 3 diff --git a/src/Objects/Helicopters/Helicopter.gd b/src/Objects/Helicopters/Helicopter.gd index 7ee0cbc..a682898 100644 --- a/src/Objects/Helicopters/Helicopter.gd +++ b/src/Objects/Helicopters/Helicopter.gd @@ -1,6 +1,5 @@ extends RigidBody3D -const DustParticles := preload("res://src/Objects/Particles/DustParticles.gd") const Rotor := preload("res://src/Objects/Helicopters/Rotor.gd") const Logger := preload("res://src/util/Logger.gd") diff --git a/src/Objects/World/Networks.gd b/src/Objects/World/Networks.gd index 00e9cf2..24e52b0 100644 --- a/src/Objects/World/Networks.gd +++ b/src/Objects/World/Networks.gd @@ -3,7 +3,6 @@ extends Node const TimeBudget := preload("res://src/util/TimeBudget.gd") const CityCoordsFeature := preload("res://src/features/CityCoordsFeature.gd") const SceneObjectRegistry := preload("res://src/SceneObjectRegistry.gd") -const CarSpawner := preload("res://src/Objects/Spawner/CarSpawner.gd") const Building := preload("res://src/Objects/Map/Building.gd") const RoadNavigation := preload("res://src/Objects/Networks/RoadNavigation.gd") diff --git a/src/native.gdextension b/src/native.gdextension index eea9264..508c648 100644 --- a/src/native.gdextension +++ b/src/native.gdextension @@ -3,7 +3,8 @@ entry_symbol = "gdext_rust_init" compatibility_minimum = 4.1 [libraries] -macos.arm64="res://native/target/aarch64-apple-darwin/release/libnative.dylib" +macos.debug.arm64="res://native/target/aarch64-apple-darwin/debug/libnative.dylib" +macos.release.arm64="res://native/target/aarch64-apple-darwin/release/libnative.dylib" macos.x86_64="res://native/target/x86_64-apple-darwin/release/libnative.dylib" macos.universal="res://native/target/universal-apple-darwin/release/libnative.dylib" windows.x86_64="res://native/target/x86_64-pc-windows-msvc/release/native.dll"