Compare commits
13 Commits
new_bullet
...
master
Author | SHA1 | Date |
---|---|---|
Franklin | d1c5cdd9b9 | |
Franklin | dd9496d110 | |
Franklin | e99708cef9 | |
Franklin | 9f5491948e | |
Franklin Blanco | 51019a35a5 | |
Franklin | 5114114f9a | |
Franklin | 9b2176185e | |
Franklin | 340b516cab | |
Franklin | afe34105e4 | |
Franklin | 837ea1ab40 | |
Franklin | 4337b9af15 | |
Franklin | dde59da879 | |
franklinblanco | 0a7f426ce2 |
|
@ -343,9 +343,9 @@ checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2"
|
|||
|
||||
[[package]]
|
||||
name = "bevy"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "329e344f835f5a9a4c46a6d1d57371f726aa2c482d1bd669b2b9c4eb1ee91fd7"
|
||||
checksum = "e4bc7e09282a82a48d70ade0c4c1154b0fd7882a735a39c66766a5d0f4718ea9"
|
||||
dependencies = [
|
||||
"bevy_internal",
|
||||
]
|
||||
|
@ -416,9 +416,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_a11y"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "271b812e5734f5056a400f7d64592dd82d6c0e6179389c2f066f433ab8bc7692"
|
||||
checksum = "68080288c932634f6563d3a8299efe0ddc9ea6787539c4c771ba250d089a94f0"
|
||||
dependencies = [
|
||||
"accesskit",
|
||||
"bevy_app",
|
||||
|
@ -428,9 +428,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_animation"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab94187a1253433e14f175293d8a86ec1c2822fda2a17807908f11ec21f45f00"
|
||||
checksum = "7aa37683b1281e1ba8cf285644e6e3f0704f14b3901c5ee282067ff7ff6f4a56"
|
||||
dependencies = [
|
||||
"bevy_app",
|
||||
"bevy_asset",
|
||||
|
@ -447,9 +447,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_app"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "172d532ea812e5954fa814dae003c207f2a0b20c6e50431787c94a7159677ece"
|
||||
checksum = "d41731817993f92e4363dd3335558e779e290bc71eefc0b5547052b85810907e"
|
||||
dependencies = [
|
||||
"bevy_derive",
|
||||
"bevy_ecs",
|
||||
|
@ -463,9 +463,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_asset"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccb2b67984088b23e223cfe9ec1befd89a110665a679acb06839bc4334ed37d6"
|
||||
checksum = "935984568f75867dd7357133b06f4b1502cd2be55e4642d483ce597e46e63bff"
|
||||
dependencies = [
|
||||
"async-broadcast",
|
||||
"async-fs",
|
||||
|
@ -495,9 +495,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_asset_macros"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b3245193e90fc8abcf1059a467cb224501dcda083d114c67c10ac66b7171e3a"
|
||||
checksum = "3f48b9bbe4ec605e4910b5cd1e1a0acbfbe0b80af5f3bcc4489a9fdd1e80058c"
|
||||
dependencies = [
|
||||
"bevy_macro_utils",
|
||||
"proc-macro2",
|
||||
|
@ -507,9 +507,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_audio"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "478de80ff25cb7decbcb22797774d1597e8c32914e81431c67d64faadc08f84a"
|
||||
checksum = "18a69889e1bfa4dbac4e641536b94f91c441da55796ad9832e77836b8264688b"
|
||||
dependencies = [
|
||||
"bevy_app",
|
||||
"bevy_asset",
|
||||
|
@ -525,9 +525,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_core"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "025e6800b73048092a55c3611e9327ad4c4c17b60517ec1c0086bb40b4b19ea8"
|
||||
checksum = "3daa24502a14839509f02407bc7e48299fe84d260877de23b60662de0f4f4b6c"
|
||||
dependencies = [
|
||||
"bevy_app",
|
||||
"bevy_ecs",
|
||||
|
@ -540,9 +540,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_core_pipeline"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e4b08a2d53ba62d9ec1fca3f7f4e0f556e9f59e1c8e63a4b7c2a18c0701152c"
|
||||
checksum = "b4b77c4fca6e90edbe2e72da7bc9aa7aed7dfdfded0920ae0a0c845f5e11084a"
|
||||
dependencies = [
|
||||
"bevy_app",
|
||||
"bevy_asset",
|
||||
|
@ -562,9 +562,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_derive"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24bf40259be12a1a24d9fd536f5ff18d31eeb5665b77e2732899783be6edc5d6"
|
||||
checksum = "f484318350462c58ba3942a45a656c1fd6b6e484a6b6b7abc3a787ad1a51e500"
|
||||
dependencies = [
|
||||
"bevy_macro_utils",
|
||||
"quote",
|
||||
|
@ -573,9 +573,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_diagnostic"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41b5a99a9fb6cd7d1eb1714fad193944a0317f0887a15cccb8309c8d37951132"
|
||||
checksum = "fa38ca5967d335cc1006a0e0f1a86c350e2f15fd1878449f61d04cd57a7c4060"
|
||||
dependencies = [
|
||||
"bevy_app",
|
||||
"bevy_core",
|
||||
|
@ -588,9 +588,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_ecs"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae11a1f467c372b50e9d4b55e78370f5420c9db7416200cc441cc84f08174dd3"
|
||||
checksum = "7709fbd22f81fb681534cd913c41e1cd18b17143368743281195d7f024b61aea"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"bevy_ecs_macros",
|
||||
|
@ -609,9 +609,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_ecs_macros"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f642c2b67c4d0daf8edf15074f6351457eb487a34b3de1290c760d8f3ac9ec16"
|
||||
checksum = "a8843aa489f159f25cdcd9fee75cd7d221a7098a71eaa72cb2d6b40ac4e3f1ba"
|
||||
dependencies = [
|
||||
"bevy_macro_utils",
|
||||
"proc-macro2",
|
||||
|
@ -675,9 +675,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_encase_derive"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65b9fb5a62c4e3ab70caaa839470d35fa932001b1b34b08bc7f7f1909bd2b3a7"
|
||||
checksum = "5328a3715e933ebbff07d0e99528dc423c4f7a53590ed1ac19a120348b028990"
|
||||
dependencies = [
|
||||
"bevy_macro_utils",
|
||||
"encase_derive_impl",
|
||||
|
@ -685,9 +685,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_gilrs"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad31cc2c84315e0759d793d6c5bcb7d8789bbc16359c98d1b766e708c1bbae49"
|
||||
checksum = "9b81ca2ebf66cbc7f998f1f142b15038ffe3c4ae1d51f70adda26dcf51b0c4ca"
|
||||
dependencies = [
|
||||
"bevy_app",
|
||||
"bevy_ecs",
|
||||
|
@ -701,9 +701,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_gizmos"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87d1cc978b91f416b23eb16f00e69f95c3a04582021827d8082e92d4725cc510"
|
||||
checksum = "db232274ddca2ae452eb2731b98267b795d133ddd14013121bc7daddde1c7491"
|
||||
dependencies = [
|
||||
"bevy_app",
|
||||
"bevy_asset",
|
||||
|
@ -721,9 +721,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_gltf"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f933745c0c86e2c07948def581259b466f99708328657054e956275430ccfd7"
|
||||
checksum = "85adc6b1fc86687bf67149e0bafaa4d6da432232fa956472d1b37f19121d3ace"
|
||||
dependencies = [
|
||||
"base64 0.13.1",
|
||||
"bevy_animation",
|
||||
|
@ -781,9 +781,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_hierarchy"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64fa240011fce8ee23f9b46e5a26a628a31d7860d6d2e4e0e361bb3ea6d5a703"
|
||||
checksum = "06bd477152ce2ae1430f5e0a4f19216e5785c22fee1ab23788b5982dc59d1a55"
|
||||
dependencies = [
|
||||
"bevy_app",
|
||||
"bevy_core",
|
||||
|
@ -796,9 +796,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_input"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e86e241b3a10b79f65a69205552546723b855d3d4c1bd8261637c076144d32f"
|
||||
checksum = "cab9a599189b2a694c182d60cd52219dd9364f9892ff542d87799b8e45d9e6dc"
|
||||
dependencies = [
|
||||
"bevy_app",
|
||||
"bevy_ecs",
|
||||
|
@ -810,9 +810,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_internal"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55124e486814c4d3632d5cfad9c4f4e46d052c028593ec46fef5bfbfb0f840b1"
|
||||
checksum = "f124bece9831afd80897815231072d51bfe3ac58c6bb58eca8880963b6d0487c"
|
||||
dependencies = [
|
||||
"bevy_a11y",
|
||||
"bevy_animation",
|
||||
|
@ -849,9 +849,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_log"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "011417debf7868b45932bb97fc0d5bfdeaf9304e324aa94840e2f1e6deeed69d"
|
||||
checksum = "0dc10ba1d225a8477b9e80a1bf797d8a8b8274e83c9b24fb4d9351aec9229755"
|
||||
dependencies = [
|
||||
"android_log-sys",
|
||||
"bevy_app",
|
||||
|
@ -865,9 +865,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_macro_utils"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf6fba87c6d069fcbcd8a48625ca8ab4392ad40d2b260863ce7d641a0f42986d"
|
||||
checksum = "e566640c6b6dced73d2006c764c2cffebe1a82be4809486c4a5d7b4b50efed4d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -878,9 +878,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_math"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "752764558a1f429c20704c3b836a019fa308961c43fdfef4f08e339d456c96be"
|
||||
checksum = "58ddc2b76783939c530178f88e5711a1b01044d7b02db4033e2eb8b43b6cf4ec"
|
||||
dependencies = [
|
||||
"glam",
|
||||
"serde",
|
||||
|
@ -888,9 +888,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_mikktspace"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b596c41a56f2268ec7cde560edc588bc7b5886e4b49c8b27c4dcc9f7c743424c"
|
||||
checksum = "8ec4962977a746d870170532fc92759e04d3dbcae8b7b82e7ca3bb83b1d75277"
|
||||
dependencies = [
|
||||
"glam",
|
||||
]
|
||||
|
@ -912,9 +912,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_pbr"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eeb6a35a78d355cc21c10f277dcd171eca65e30a90e76eb89f4dacf606621fe1"
|
||||
checksum = "520bfd2a898c74f84ea52cfb8eb061f37373ad15e623489d5f75d27ebd6138fe"
|
||||
dependencies = [
|
||||
"bevy_app",
|
||||
"bevy_asset",
|
||||
|
@ -938,9 +938,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_ptr"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "308a02679f6ce21ef71de20fae6d6a2016c07baa21d8e8d0558e6b7851e8adf2"
|
||||
checksum = "c77ec20c8fafcdc196508ef5ccb4f0400a8d193cb61f7b14a36ed9a25ad423cf"
|
||||
|
||||
[[package]]
|
||||
name = "bevy_rapier3d"
|
||||
|
@ -957,9 +957,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_reflect"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdd56914a8ad57621d7a1a099f7e6b1f7482c9c76cedc9c3d4c175a203939c5d"
|
||||
checksum = "d7921f15fc944c9c8ad01d7dbcea6505b8909c6655cd9382bab1407181556038"
|
||||
dependencies = [
|
||||
"bevy_math",
|
||||
"bevy_ptr",
|
||||
|
@ -976,9 +976,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_reflect_derive"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25f627907c40ac552f798423447fc331fc1ddacd94c5f7a2a70942eb06bc8447"
|
||||
checksum = "b4a8c5475f216e751ef4452a1306b00711f33d2d04d9f149e4c845dfeb6753a0"
|
||||
dependencies = [
|
||||
"bevy_macro_utils",
|
||||
"proc-macro2",
|
||||
|
@ -989,9 +989,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_render"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90d777f4c51bd58e9e40777c6cb8dde0778df7e2c5298b3f9e3455bd12a9856c"
|
||||
checksum = "bdefdd3737125b0d94a6ff20bb70fa8cfe9d7d5dcd72ba4dfe6c5f1d30d9f6e4"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"bevy_app",
|
||||
|
@ -1035,9 +1035,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_render_macros"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35b00c3d0abff94a729460fc9aa95c2ceac71b49b3041166bb5ba3098e9657e7"
|
||||
checksum = "64d86bfc5a1e7fbeeaec0c4ceab18155530f5506624670965db3415f75826bea"
|
||||
dependencies = [
|
||||
"bevy_macro_utils",
|
||||
"proc-macro2",
|
||||
|
@ -1047,9 +1047,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_scene"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba6294396a6375f0b14341d8003408c10aa040e3f833ac8bd49677170ec55d73"
|
||||
checksum = "e7df078b5e406e37c8a1c6ba0d652bf105fde713ce3c3efda7263fe27467eee5"
|
||||
dependencies = [
|
||||
"bevy_app",
|
||||
"bevy_asset",
|
||||
|
@ -1068,9 +1068,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_sprite"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4f7d1f88a6e5497fdafd95c20984a1d1b5517bc39d51600b4988cd60c51837a"
|
||||
checksum = "c7cc0c9d946e17e3e0aaa202f182837bc796c4f862b2e5a805134f873f21cf7f"
|
||||
dependencies = [
|
||||
"bevy_app",
|
||||
"bevy_asset",
|
||||
|
@ -1094,9 +1094,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_tasks"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a45be906618192515bc613e46546150089adbb4a82178dc462045acd1e89e92"
|
||||
checksum = "f4fefa7fe0da8923525f7500e274f1bd60dbd79918a25cf7d0dfa0a6ba15c1cf"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"async-executor",
|
||||
|
@ -1108,9 +1108,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_text"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c136af700af4f87c94f68d6e019528c371bf09ebf4a8ff7468bb3c73806b34f5"
|
||||
checksum = "3a9a79d49ca06170d69149949b134c14e8b99ace1444c1ca2cd4743b19d5b055"
|
||||
dependencies = [
|
||||
"ab_glyph",
|
||||
"bevy_app",
|
||||
|
@ -1130,9 +1130,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_time"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b29709cadf22d318a0b7c79f763e9c5ac414292bd0e850066fa935959021b276"
|
||||
checksum = "e6250d76eed3077128b6a3d004f9f198b01107800b9824051e32bb658054e837"
|
||||
dependencies = [
|
||||
"bevy_app",
|
||||
"bevy_ecs",
|
||||
|
@ -1144,9 +1144,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_transform"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70262c51e915b6224129206d23823364e650cf5eb5f4b6ce3ee379f608c180d2"
|
||||
checksum = "d541e0c292edbd96afae816ee680e02247422423ccd5dc635c1e211a20ed64be"
|
||||
dependencies = [
|
||||
"bevy_app",
|
||||
"bevy_ecs",
|
||||
|
@ -1158,9 +1158,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_ui"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd5ecbf2dceaab118769dd870e34d780bfde556af561fd10d8d613b0f237297e"
|
||||
checksum = "d785e3b75dabcb2a8ad0d50933f8f3446d59e512cabc2d2a145e28c2bb8792ba"
|
||||
dependencies = [
|
||||
"bevy_a11y",
|
||||
"bevy_app",
|
||||
|
@ -1188,9 +1188,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_utils"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8e75d4a34ef0b15dffd1ee9079ef1f0f5139527e192b9d5708b3e158777c753"
|
||||
checksum = "7915222f4a08ccc782e08d10b751b42e5f9d786e697d0cb3fd09333cb7e8b6ea"
|
||||
dependencies = [
|
||||
"ahash 0.8.3",
|
||||
"bevy_utils_proc_macros",
|
||||
|
@ -1206,9 +1206,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_utils_proc_macros"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7dfd3735a61a1b681ed1e176afe4eae731bbb03e51ad871e9eb39e76a2d170e"
|
||||
checksum = "7aafecc952b6b8eb1a93c12590bd867d25df2f4ae1033a01dfdfc3c35ebccfff"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1217,9 +1217,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_window"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e60d1830b3fbd7db5bfea7ac9fcd0f5e1d1af88c91ab469e697ab176d8b3140b"
|
||||
checksum = "41ee72bf7f974000e9b31bb971a89387f1432ba9413f35c4fef59fef49767260"
|
||||
dependencies = [
|
||||
"bevy_a11y",
|
||||
"bevy_app",
|
||||
|
@ -1233,9 +1233,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bevy_winit"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f8294e78c6a1f9c34d36501a377c5d20bf0fa23a0958187bb270187741448ba"
|
||||
checksum = "1eb71f287eca9006dda998784c7b931e400ae2cc4c505da315882a8b082f21ad"
|
||||
dependencies = [
|
||||
"accesskit_winit",
|
||||
"approx",
|
||||
|
|
|
@ -15,7 +15,7 @@ opt-level = 3
|
|||
opt-level = 3
|
||||
|
||||
[dependencies]
|
||||
bevy = { version = "0.12", features = []}
|
||||
bevy = { version = "0.12.1", features = []}
|
||||
bevy-inspector-egui = "0.21.0"
|
||||
bevy_editor_pls = "0.6"
|
||||
bevy_rapier3d = { version = "0.23", features = ["debug-render-3d"] }
|
||||
|
|
29
Design.md
29
Design.md
|
@ -37,14 +37,20 @@ Multiplayer
|
|||
- [x] Gun colliding with bullet, making it lower on every shot fired.
|
||||
- [x] Optics
|
||||
- [x] All optics implementing a fn/trait that gives a specific gun offset to use the optic correctly
|
||||
- [ ] TODO: Find some way to implement a shader for the optics (AFTER IMPLEMENTING NEW BULLET SYSTEM)
|
||||
- [x] Find some way to implement a shader for the optics (AFTER IMPLEMENTING NEW BULLET SYSTEM)
|
||||
- [x] Optic glass material
|
||||
- [x] Reticle render
|
||||
- [x] Reticle adjustment while on the field
|
||||
- [ ] Parallax effect on reticle
|
||||
- [ ] Weapon Clipping
|
||||
- [ ] Make the player's collider bigger towards the front
|
||||
- [x] Make the player's collider bigger towards the front
|
||||
- [ ] Make the weapon's collider cover the firing point
|
||||
- [ ] If possible, create a new gun pose, like pushed back
|
||||
- [ ] Bobbing
|
||||
- [ ] Gun Bob on run
|
||||
- [ ] Gun Bob on walk
|
||||
- [x] Bobbing
|
||||
- [x] Gun Bob on run
|
||||
- [x] Gun Bob on walk
|
||||
- [ ] Check if Bobbing could be too exagerated
|
||||
- [ ] Leaning neutralizes Bobbing for some reason
|
||||
- [ ] Reload animation (procedural)
|
||||
- [ ] Real world magazines
|
||||
- [x] Rewriting bullet physics to use raycasts & kinematic rigidbodies (logic controlled)
|
||||
|
@ -53,6 +59,19 @@ Multiplayer
|
|||
- [x] Gun dropping does not apply impulse for some reason...
|
||||
- [x] Gun colliding with ground and going into low ready
|
||||
- [x] With introduction of floor collision groups now bullets go through floors
|
||||
- [x] Huge bug all attachments get despawned and spawned when gun shoots
|
||||
- [ ] Bloom on bullets is making them way too bright, bring down the emissive mat color & size of the bullets.
|
||||
- [ ] Red dot sight needs to be zeroed. (Height over bore)
|
||||
- [ ] Red dot on sight is too quick on a trackpad.
|
||||
- [ ] Red dot is automatically going up to max when shift is pressed for the first time.
|
||||
- [ ] Multiplayer
|
||||
- [ ] Start work on a multiplayer server
|
||||
- [ ] Map
|
||||
- [ ] Start building a map for your hideout
|
||||
- [ ] Player model hitbox
|
||||
- [ ] Organs
|
||||
- [ ] Heart
|
||||
- [ ] Brain
|
||||
|
||||
# Design
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -15,9 +15,11 @@ use super::markers::player::Player;
|
|||
|
||||
/// System that captures input and fires events
|
||||
pub fn capture_input(
|
||||
commands: Commands,
|
||||
keyboard_input: Res<Input<KeyCode>>,
|
||||
player_query: Query<
|
||||
(
|
||||
Entity,
|
||||
&mut Velocity,
|
||||
&mut ExternalImpulse,
|
||||
&mut PlayerLinearYState,
|
||||
|
@ -60,6 +62,7 @@ pub fn capture_input(
|
|||
};
|
||||
if game_ui_state.any_window() {
|
||||
move_player(
|
||||
commands,
|
||||
PlayerMovementInput::default(),
|
||||
player_query,
|
||||
time,
|
||||
|
@ -67,6 +70,7 @@ pub fn capture_input(
|
|||
);
|
||||
} else {
|
||||
move_player(
|
||||
commands,
|
||||
player_movement_input,
|
||||
player_query,
|
||||
time,
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::{comps::core::{
|
|||
grid::UGrid,
|
||||
items::item::{Item, ItemType, ItemId},
|
||||
markers::{holdable::HoldableObjectType, interactable::Interactable, proxy::{weapons::initial_attachments::InitialAttachments, physics::rapier::WhenColliderAddImpulse}}, inventory::slot::PlayerInventorySlotType, weapons::{firearm::Firearm, firearm_data::FirearmData}, events::pickup_item::ItemState,
|
||||
}, setup::assets::{GltfAssets, GltfAssetType}, utils};
|
||||
}, setup::assets::{GltfAssets, GltfAssetType}, utils, logic::core::player::hand_bobbing::HandBobbing};
|
||||
|
||||
#[derive(Component, Clone)]
|
||||
pub struct Ak105GunItem {
|
||||
|
@ -96,6 +96,7 @@ impl Item for Ak105GunItem {
|
|||
"{} Item Gltf Asset",
|
||||
self.inventory_title()
|
||||
)),
|
||||
HandBobbing::default(),
|
||||
))
|
||||
.id();
|
||||
match item_state {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use bevy::{
|
||||
prelude::{Component, Vec3},
|
||||
reflect::Reflect,
|
||||
time::Timer, ecs::{reflect::ReflectComponent, entity::Entity},
|
||||
reflect::Reflect, ecs::{reflect::ReflectComponent, entity::Entity},
|
||||
};
|
||||
|
||||
use crate::comps::core::weapons::caliber::Caliber;
|
||||
|
@ -17,7 +16,6 @@ pub struct BulletHit {
|
|||
pub struct BulletMarker {
|
||||
pub caliber: Caliber,
|
||||
pub starting_point: Vec3,
|
||||
pub timer: Timer,
|
||||
pub current_velocity: Vec3,
|
||||
pub hits: Vec<BulletHit>,
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ bitflags! {
|
|||
/// The value `C`, at bit position `2`.
|
||||
const SOLIDS = 0b00000100;
|
||||
const PLAYER = 0b00001000;
|
||||
const ENEMY = 0b00010000;
|
||||
|
||||
const FLOOR = 0b00010000;
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
#[derive(Component, Clone, Debug, Reflect, Default)]
|
||||
#[reflect(Component)]
|
||||
pub struct FirearmScene;
|
|
@ -8,4 +8,6 @@ pub mod player;
|
|||
pub mod settings_screen;
|
||||
pub mod proxy;
|
||||
pub mod inspect_screen;
|
||||
pub mod collider_flags;
|
||||
pub mod collider_flags;
|
||||
pub mod firearm_scene;
|
||||
pub mod player_health;
|
|
@ -0,0 +1,28 @@
|
|||
use super::proxy::other_players::human_body_part::HumanBodyPart;
|
||||
|
||||
|
||||
pub const MAX_BLOOD_ML: f32 = 6000.0;
|
||||
/// Health for a player
|
||||
pub struct PlayerHealth {
|
||||
/// Vision state. TODO: Create an enum for Partial blindness, Full blindness, Full blindness.
|
||||
pub vision: bool,
|
||||
/// Measured in milliliters
|
||||
pub current_blood: f32,
|
||||
/// The average adult has about 4 to 6 liters of blood (9 to 12 US pints) in their body. The average man has more blood than the average woman, and people who weigh more or are taller than others have more blood.[1] This means a person can die from losing 2 1/2 to 4 liters of blood. To compare, this is five to eight times as much blood as people usually give in a blood donation.[2]
|
||||
/// [Source](https://simple.wikipedia.org/wiki/Exsanguination#:~:text=People%20can%20die%20from%20losing,two%2Dthirds%20of%20their%20blood.&text=The%20average%20adult%20has%20about,than%20others%20have%20more%20blood.)
|
||||
/// Measured in milliliters
|
||||
pub max_blood: f32,
|
||||
pub human_body_parts_state: Vec<HumanBodyPartState>,
|
||||
}
|
||||
|
||||
pub struct HumanBodyPartState {
|
||||
pub body_part: HumanBodyPart,
|
||||
pub well: bool,
|
||||
}
|
||||
|
||||
|
||||
impl Default for PlayerHealth {
|
||||
fn default() -> Self {
|
||||
Self { current_blood: MAX_BLOOD_ML, max_blood: MAX_BLOOD_ML, vision: true, human_body_parts_state: Vec::new() } // TODO: add human body parts here
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy::{prelude::*, core_pipeline::{tonemapping::Tonemapping, bloom::BloomSettings}};
|
||||
use bevy_rapier3d::prelude::*;
|
||||
|
||||
use crate::{comps::core::markers::{proxy::physics::rapier::LinkToPlayer, camera::MainCamera}, logic::core::player::player_values_state::PlayerValuesState};
|
||||
use crate::{comps::core::markers::{proxy::physics::rapier::LinkToPlayer, camera::MainCamera, player::Player}, logic::core::player::player_values_state::PlayerValuesState, utils::hierarchy::find_child_in_parent_children};
|
||||
|
||||
use super::{third_person_camera::{ThirdPersonCameraProxy, ThirdPersonCamera}, in_player_hands_parent::InPlayerHandsParent};
|
||||
|
||||
|
@ -12,32 +12,47 @@ pub struct PlayerEye;
|
|||
|
||||
pub fn insert_components_into_spawned_player(
|
||||
mut commands: Commands,
|
||||
player_query: Query<Entity, With<Player>>,
|
||||
eye_query: Query<Entity, Added<PlayerEye>>,
|
||||
third_person_camera_query: Query<Entity, Added<ThirdPersonCameraProxy>>,
|
||||
player_collider_query: Query<Entity, (With<LinkToPlayer>, With<Collider>, Added<Collider>)>,
|
||||
mut hand_query: Query<(Entity, &mut Transform), (With<InPlayerHandsParent>, Without<LinkToPlayer>, Without<Collider>)>,
|
||||
player_values_state: Res<PlayerValuesState>,
|
||||
children: Query<&Children>,
|
||||
) {
|
||||
for eye in eye_query.iter() {
|
||||
// Spawn camera
|
||||
let camera = commands
|
||||
.spawn(MainCamera)
|
||||
.insert(Camera3dBundle {
|
||||
transform: Transform::from_xyz(0.0, 0.0, 0.0),
|
||||
..Default::default()
|
||||
})
|
||||
//s.insert(Skybox(skybox_handle.clone()))
|
||||
.insert(VisibilityBundle {
|
||||
visibility: Visibility::Inherited,
|
||||
..Default::default()
|
||||
})
|
||||
//.push_children(&[player_hand])
|
||||
.id();
|
||||
for (hand, mut hand_transform) in hand_query.iter_mut() {
|
||||
hand_transform.rotate_y(180.0f32.to_radians());
|
||||
commands.entity(hand).set_parent(camera);
|
||||
for player in player_query.iter() {
|
||||
if find_child_in_parent_children(&mut commands, player, eye, &children) {
|
||||
// Spawn camera
|
||||
let camera = commands
|
||||
.spawn(MainCamera)
|
||||
.insert(Camera3dBundle {
|
||||
transform: Transform::from_xyz(0.0, 0.0, 0.0),
|
||||
camera: Camera {
|
||||
hdr: true,
|
||||
..Default::default()
|
||||
},
|
||||
tonemapping: Tonemapping::TonyMcMapface,
|
||||
..Default::default()
|
||||
})
|
||||
.insert(BloomSettings {
|
||||
..Default::default()
|
||||
})
|
||||
//s.insert(Skybox(skybox_handle.clone()))
|
||||
.insert(VisibilityBundle {
|
||||
visibility: Visibility::Inherited,
|
||||
..Default::default()
|
||||
})
|
||||
//.push_children(&[player_hand])
|
||||
.id();
|
||||
for (hand, mut hand_transform) in hand_query.iter_mut() {
|
||||
hand_transform.rotate_y(180.0f32.to_radians());
|
||||
commands.entity(hand).set_parent(camera);
|
||||
}
|
||||
commands.entity(eye).add_child(camera);
|
||||
}
|
||||
}
|
||||
commands.entity(eye).add_child(camera);
|
||||
|
||||
}
|
||||
for third_person_camera in third_person_camera_query.iter() {
|
||||
|
||||
|
|
|
@ -2,4 +2,5 @@ pub mod character;
|
|||
pub mod plugin;
|
||||
pub mod physics;
|
||||
pub mod bevy;
|
||||
pub mod weapons;
|
||||
pub mod weapons;
|
||||
pub mod other_players;
|
|
@ -0,0 +1,38 @@
|
|||
use bevy::{ecs::{component::Component, reflect::ReflectComponent}, reflect::Reflect};
|
||||
|
||||
|
||||
#[derive(Component, Reflect, Clone, PartialEq, Default, Debug)]
|
||||
#[reflect(Component)]
|
||||
pub enum HumanBodyPart {
|
||||
Heart,
|
||||
Brain,
|
||||
#[default]
|
||||
Torso,
|
||||
Legs,
|
||||
Hands,
|
||||
Feet,
|
||||
Eyes,
|
||||
Head,
|
||||
Spine,
|
||||
}
|
||||
|
||||
|
||||
impl HumanBodyPart {
|
||||
/// For the sake of simplicity.
|
||||
/// A value of true means an instant death if a bullet hits this body part.
|
||||
/// A value of false means no instant death.
|
||||
pub fn is_vital(&self) -> bool {
|
||||
match self {
|
||||
HumanBodyPart::Heart => true,
|
||||
HumanBodyPart::Brain => true,
|
||||
HumanBodyPart::Spine => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
/// Take a mutable reference to the player_health
|
||||
pub fn effect_when_lost() {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
pub mod human_body_part;
|
|
@ -62,36 +62,35 @@ pub fn physics_replace_proxies(
|
|||
|
||||
mut commands: Commands,
|
||||
) {
|
||||
for (player_entity, _) in player_query.iter() {
|
||||
for proxy_colider in proxy_colliders.iter_mut() {
|
||||
let (entity, collider_proxy, name, mut visibility, link_to_player_opt, _) = proxy_colider;
|
||||
let (entity, collider_proxy, name, mut visibility, _, _) = proxy_colider;
|
||||
// we hide the collider meshes: perhaps they should be removed altogether once processed ?
|
||||
if name.ends_with("_collider") || name.ends_with("_sensor") {
|
||||
*visibility = Visibility::Hidden;
|
||||
}
|
||||
|
||||
let entity_to_insert_collider_on = if link_to_player_opt.is_some() { player_entity } else { entity };
|
||||
|
||||
|
||||
let mut rapier_collider: RapierCollider;
|
||||
match collider_proxy {
|
||||
Collider::Ball(radius) => {
|
||||
println!("proxy: ball");
|
||||
rapier_collider = RapierCollider::ball(*radius);
|
||||
commands.entity(entity_to_insert_collider_on)
|
||||
commands.entity(entity)
|
||||
.insert(rapier_collider)
|
||||
;
|
||||
}
|
||||
Collider::Cuboid(size) => {
|
||||
println!("proxy: cuboid");
|
||||
rapier_collider = RapierCollider::cuboid(size.x, size.y, size.z);
|
||||
commands.entity(entity_to_insert_collider_on)
|
||||
commands.entity(entity)
|
||||
.insert(rapier_collider)
|
||||
;
|
||||
}
|
||||
Collider::Capsule(a, b, radius) => {
|
||||
println!("proxy: capsule");
|
||||
rapier_collider = RapierCollider::capsule(*a, *b, *radius);
|
||||
commands.entity(entity_to_insert_collider_on)
|
||||
commands.entity(entity)
|
||||
.insert(rapier_collider)
|
||||
;
|
||||
}
|
||||
|
@ -110,6 +109,7 @@ pub fn physics_replace_proxies(
|
|||
commands.entity(impulse_entity).insert(impulse_to_be_applied.0);
|
||||
}
|
||||
}
|
||||
|
||||
//rapier_collider.set_scale(Vec3 { x: 3.0, y: 3.0, z: 3.0 }, 1);
|
||||
commands
|
||||
.entity(entity)
|
||||
|
@ -123,6 +123,10 @@ pub fn physics_replace_proxies(
|
|||
}
|
||||
}
|
||||
for (entity, proxy_rigidbody, link_to_player_opt, _) in proxy_rigidbodies.iter() {
|
||||
let mut entity_to_insert_collider_on = entity ;
|
||||
for (player_entity, _) in player_query.iter() {
|
||||
entity_to_insert_collider_on = if link_to_player_opt.is_some() { player_entity } else { entity };
|
||||
}
|
||||
let rapier_rigidbody: RapierRigidBody;
|
||||
match proxy_rigidbody {
|
||||
RigidBodyBlender::Fixed => rapier_rigidbody = RapierRigidBody::Fixed,
|
||||
|
@ -130,11 +134,10 @@ pub fn physics_replace_proxies(
|
|||
}
|
||||
commands
|
||||
.entity(
|
||||
if link_to_player_opt.is_some() { player_entity } else { entity }
|
||||
if link_to_player_opt.is_some() { entity_to_insert_collider_on } else { entity }
|
||||
)
|
||||
.insert(rapier_rigidbody)
|
||||
;
|
||||
commands.entity(entity).remove::<RigidBodyBlender>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ use bevy::app::{Plugin, Update};
|
|||
|
||||
use crate::{setup::load_state::update_game_load_state, comps::core::weapons::{firearm::Firearm, attachments::{weapon_attachment::WeaponAttachment, optic::Optic, stock::Stock, compensator::Compensator, magazine::Magazine, foregrip::ForeGrip}, parts::{charging_handle::ChargingHandle, fire_selector::FireSelector, firing_point::FiringPoint, trigger::Trigger}, slot::{compensator_slot::CompensatorSlot, fore_grip_slot::ForeGripSlot, magazine_slot::MagazineSlot, stock_slot::StockSlot, utility_slot::UtilitySlot, slot::WeaponSlot}}};
|
||||
|
||||
use super::{character::{player_hitbox::PlayerHitBox, player_character::PlayerCharacter, player_eye::{PlayerEye, insert_components_into_spawned_player}, in_player_hands_parent::{InPlayerHandsParent, insert_components_into_player_hand}, third_person_camera::ThirdPersonCameraProxy}, physics::{rapier::{AutoAABBCollider, physics_replace_proxies}, self}, weapons::{firearm::insert_firearm_state_to_firearms, gun_colliders::{GunFirearmCollider, update_gun_collider}, sight_placement::{SightPlacementStart, SightPlacementEnd}}};
|
||||
use super::{character::{player_hitbox::PlayerHitBox, player_character::PlayerCharacter, player_eye::{PlayerEye, insert_components_into_spawned_player}, in_player_hands_parent::{InPlayerHandsParent, insert_components_into_player_hand}, third_person_camera::ThirdPersonCameraProxy}, physics::{rapier::{AutoAABBCollider, physics_replace_proxies}, self}, weapons::{firearm::insert_firearm_state_to_firearms, gun_colliders::{GunFirearmCollider, update_gun_collider}, sight_placement::{SightPlacementStart, SightPlacementEnd}, optic_sight_glass::{OpticSightGlass, replace_optic_sight_material, DebugMaterialResource}}, other_players::human_body_part::HumanBodyPart};
|
||||
|
||||
|
||||
|
||||
|
@ -20,6 +20,9 @@ impl Plugin for ProxyComponentsPlugin {
|
|||
app.register_type::<InPlayerHandsParent>();
|
||||
app.register_type::<ThirdPersonCameraProxy>();
|
||||
|
||||
// OtherPlayer
|
||||
app.register_type::<HumanBodyPart>();
|
||||
|
||||
// Firearms
|
||||
app.register_type::<Firearm>();
|
||||
app.register_type::<GunFirearmCollider>();
|
||||
|
@ -36,6 +39,8 @@ impl Plugin for ProxyComponentsPlugin {
|
|||
app.register_type::<Magazine>();
|
||||
app.register_type::<ForeGrip>();
|
||||
|
||||
app.register_type::<OpticSightGlass>();
|
||||
|
||||
// Parts
|
||||
app.register_type::<ChargingHandle>();
|
||||
app.register_type::<FireSelector>();
|
||||
|
@ -54,10 +59,16 @@ impl Plugin for ProxyComponentsPlugin {
|
|||
app.register_type::<physics::rapier::Collider>();
|
||||
app.register_type::<physics::rapier::RigidBodyBlender>();
|
||||
app.register_type::<physics::rapier::LinkToPlayer>();
|
||||
|
||||
// Debug for creating materials
|
||||
app.register_type::<DebugMaterialResource>();
|
||||
app.insert_resource(DebugMaterialResource::default());
|
||||
|
||||
app.add_systems(Update, (physics_replace_proxies, update_game_load_state));
|
||||
app.add_systems(Update, insert_components_into_spawned_player);
|
||||
app.add_systems(Update, insert_components_into_player_hand);
|
||||
app.add_systems(Update, insert_firearm_state_to_firearms);
|
||||
app.add_systems(Update, update_gun_collider);
|
||||
app.add_systems(Update, replace_optic_sight_material);
|
||||
}
|
||||
}
|
|
@ -11,7 +11,8 @@ pub struct InsertFirearmStateIntoFirearmsParams<'w, 's> {
|
|||
firearm_scene_bundle: Query<'w, 's, (Entity, Option<&'static ItemState>, Option<&'static InitialAttachments>, &'static Children), With<SceneInstance>>,
|
||||
firearm_query: Query<'w, 's, (Entity, &'static Firearm, &'static Parent, Option<&'static mut FirearmState>), Or<(Without<FirearmState>, Changed<FirearmState>)>>,
|
||||
slots_query: Query<'w, 's, (Entity, &'static WeaponSlot, &'static Parent, &'static mut Transform)>,
|
||||
attachments_query: Query<'w, 's, (Entity, &'static WeaponAttachment, &'static Parent)>,
|
||||
attachments_query: Query<'w, 's, (&'static WeaponAttachment, &'static Parent)>,
|
||||
scenes_query: Query<'w, 's, (&'static Children, &'static Parent), With<Handle<Scene>>>,
|
||||
//sight_placement_start_query: Query<'w, 's, (&'static Parent, &'static Transform), (With<SightPlacementStart>, Without<SightPlacementEnd>)>,
|
||||
//sight_placement_end_query: Query<'w, 's, (&'static Parent, &'static Transform), (With<SightPlacementEnd>, Without<SightPlacementStart>)>,
|
||||
in_player_hands_query: Query<'w, 's, &'static ItemId, With<InPlayerHands>>,
|
||||
|
@ -36,8 +37,8 @@ pub fn insert_firearm_state_to_firearms(
|
|||
#[allow(irrefutable_let_patterns)]
|
||||
if let ItemState::Weapon(mut firearm_state) = item_state.clone() {
|
||||
commands.entity(firearm_scene_entity).remove::<ItemState>();
|
||||
spawn_attachments_in_firearm(&mut commands, firearm_entity, &mut firearm_state, &queries.slots_query, &assets_gltf, &loaded_gltf_assets);
|
||||
adjust_sight_slot_position(&mut queries.slots_query, firearm_state.optic_pos);
|
||||
spawn_attachments_in_firearm(&mut commands, firearm_entity, &mut firearm_state, &queries.slots_query, &queries.attachments_query, &queries.scenes_query, &assets_gltf, &loaded_gltf_assets);
|
||||
adjust_sight_slot_position(&mut queries.slots_query, firearm_state.get_optic_pos_opt());
|
||||
commands
|
||||
.entity(firearm_entity)
|
||||
.insert(firearm_state);
|
||||
|
@ -48,8 +49,8 @@ pub fn insert_firearm_state_to_firearms(
|
|||
match firearm_state_opt {
|
||||
Some(mut firearm_state) => {
|
||||
// Change the Slots
|
||||
spawn_attachments_in_firearm(&mut commands, firearm_entity, &mut firearm_state, &queries.slots_query, &assets_gltf, &loaded_gltf_assets);
|
||||
adjust_sight_slot_position(&mut queries.slots_query, firearm_state.optic_pos);
|
||||
spawn_attachments_in_firearm(&mut commands, firearm_entity, &mut firearm_state, &queries.slots_query, &queries.attachments_query, &queries.scenes_query, &assets_gltf, &loaded_gltf_assets);
|
||||
adjust_sight_slot_position(&mut queries.slots_query, firearm_state.get_optic_pos_opt());
|
||||
for in_player_hands_item_id in queries.in_player_hands_query.iter() {
|
||||
for player_inventory in queries.player_inventories_query.iter() {
|
||||
if let Some(current_item) = player_inventory.get_current_slot_item() {
|
||||
|
@ -63,14 +64,16 @@ pub fn insert_firearm_state_to_firearms(
|
|||
None => {
|
||||
// Create the firearm_state
|
||||
let mut firearm_slots = Vec::new();
|
||||
let magazine_data = None;
|
||||
let mut magazine_data = None;
|
||||
let mut optic_data = None;
|
||||
for (slot_entity, slot, parent_entity, _) in queries.slots_query.iter() {
|
||||
if firearm_entity == parent_entity.get() {
|
||||
let mut attachment = None;
|
||||
for (_, weapon_attachment, attachment_parent) in queries.attachments_query.iter() {
|
||||
for (weapon_attachment, attachment_parent) in queries.attachments_query.iter() {
|
||||
if slot_entity == attachment_parent.get() {
|
||||
attachment = Some(weapon_attachment.clone())
|
||||
}
|
||||
println!("A");
|
||||
}
|
||||
firearm_slots.push(AttachmentSlot {
|
||||
attachment,
|
||||
|
@ -81,11 +84,18 @@ pub fn insert_firearm_state_to_firearms(
|
|||
|
||||
if let Some(initial_attachments) = initial_attchments_opt {
|
||||
for initial_attachment in initial_attachments.attachments.iter() {
|
||||
firearm_slots.iter_mut().for_each(|firearm_slot| if initial_attachment.fits_into_slot(&firearm_slot.slot_type) { firearm_slot.attachment = Some(initial_attachment.clone()) });
|
||||
firearm_slots.iter_mut().for_each(|firearm_slot| if initial_attachment.fits_into_slot(&firearm_slot.slot_type) {
|
||||
firearm_slot.attachment = Some(initial_attachment.clone());
|
||||
match initial_attachment {
|
||||
WeaponAttachment::Magazine(magazine) => magazine_data = Some(magazine.magazine_data()),
|
||||
WeaponAttachment::Optic(optic) => optic_data = Some(optic.optic_data()),
|
||||
_ => {}
|
||||
};
|
||||
});
|
||||
}
|
||||
commands.entity(firearm_scene_entity).remove::<InitialAttachments>();
|
||||
}
|
||||
let firearm_state = FirearmState::new(firearm_slots, magazine_data);
|
||||
let firearm_state = FirearmState::new(firearm_slots, magazine_data, optic_data);
|
||||
commands
|
||||
.entity(firearm_entity)
|
||||
.insert(firearm_state.clone());
|
||||
|
@ -102,6 +112,8 @@ fn spawn_attachments_in_firearm(
|
|||
firearm_entity: Entity,
|
||||
firearm_state: &mut FirearmState,
|
||||
slots_query: &Query<(Entity, &WeaponSlot, &Parent, &mut Transform)>,
|
||||
attachments_query: &Query<(&'static WeaponAttachment, &'static Parent)>,
|
||||
scenes_query: &Query<(&'static Children, &'static Parent), With<Handle<Scene>>>,
|
||||
assets_gltf: &GltfAssets,
|
||||
loaded_gltf_assets: &Assets<Gltf>,
|
||||
) {
|
||||
|
@ -111,9 +123,24 @@ fn spawn_attachments_in_firearm(
|
|||
}
|
||||
for attachment_slot in firearm_state.attachment_slots.iter() {
|
||||
if discriminant(&attachment_slot.slot_type) == discriminant(weapon_slot) {
|
||||
commands.entity(slot_entity).despawn_descendants();
|
||||
match &attachment_slot.attachment {
|
||||
Some(attachment) =>
|
||||
{
|
||||
// Check for existing attachment in slot, if it matches then don't despawn it.
|
||||
let mut skip = false;
|
||||
for (scene_children, scene_parent) in scenes_query.iter() {
|
||||
for (weapon_attachment, attachment_parent) in attachments_query.iter() {
|
||||
if scene_parent.get() == slot_entity {
|
||||
for scene_child in scene_children {
|
||||
if scene_child == &attachment_parent.get() && weapon_attachment == attachment{
|
||||
skip = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if skip { continue; }
|
||||
commands.entity(slot_entity).despawn_descendants();
|
||||
if let Some(asset_handle) = assets_gltf.assets.iter().find(|asset| {
|
||||
asset.asset_type == GltfAssetType::Attachment(attachment.clone())
|
||||
}) {
|
||||
|
@ -132,8 +159,16 @@ fn spawn_attachments_in_firearm(
|
|||
firearm_state.magazine_data = Some(magazine.magazine_data());
|
||||
}
|
||||
}
|
||||
}},
|
||||
None => {},
|
||||
else if let None = &firearm_state.optic_data {
|
||||
if let WeaponAttachment::Optic(optic) = attachment {
|
||||
firearm_state.optic_data = Some(optic.optic_data());
|
||||
}
|
||||
}
|
||||
}}
|
||||
},
|
||||
None => {
|
||||
commands.entity(slot_entity).despawn_descendants();
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -142,12 +177,12 @@ fn spawn_attachments_in_firearm(
|
|||
|
||||
fn adjust_sight_slot_position(
|
||||
slots_query: &mut Query<(Entity, &'static WeaponSlot, &'static Parent, &'static mut Transform)>,
|
||||
optic_pos_opt: Option<Vec3>,
|
||||
optic_pos_opt: Option<f32>,
|
||||
) {
|
||||
if let Some(optic_pos) = optic_pos_opt {
|
||||
for (_, slot, _, mut slot_transform) in slots_query.iter_mut() {
|
||||
if slot == &WeaponSlot::SightSlot {
|
||||
slot_transform.translation = optic_pos;
|
||||
slot_transform.translation.y = optic_pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
pub mod firearm;
|
||||
pub mod initial_attachments;
|
||||
pub mod gun_colliders;
|
||||
pub mod sight_placement;
|
||||
pub mod sight_placement;
|
||||
pub mod optic_sight_glass;
|
||||
pub mod reticle;
|
|
@ -0,0 +1,29 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
use crate::comps::core::weapons::attachments::optic::Optic;
|
||||
|
||||
#[derive(Default, Component, Reflect, Debug)]
|
||||
#[reflect(Component)]
|
||||
pub struct OpticSightGlass (pub Optic);
|
||||
|
||||
#[derive(Default, Resource, Reflect, Debug)]
|
||||
#[reflect(Resource)]
|
||||
pub struct DebugMaterialResource(StandardMaterial);
|
||||
|
||||
pub fn replace_optic_sight_material(
|
||||
//mut commands: Commands,
|
||||
marker_query: Query<(Entity, &OpticSightGlass), Added<OpticSightGlass>>,
|
||||
materials_query: Query<(&Parent, &Handle<StandardMaterial>), With<Handle<Mesh>>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
for (marker, optic_sight_glass) in marker_query.iter() {
|
||||
for (material_parent, material_handle) in materials_query.iter() {
|
||||
if marker == material_parent.get() {
|
||||
if let Some(material) = materials.get_mut(material_handle) {
|
||||
*material = optic_sight_glass.0.sight_glass_material();
|
||||
//TODO: Reticle
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
use bevy::{ecs::component::Component, reflect::Reflect};
|
||||
|
||||
|
||||
#[derive(Component, Reflect, Clone, Debug, Default)]
|
||||
pub struct DrawnReticle;
|
|
@ -0,0 +1,71 @@
|
|||
use bevy::{prelude::*, gltf::Gltf};
|
||||
use bevy_rapier3d::prelude::*;
|
||||
|
||||
use crate::{
|
||||
comps::core::markers::collider_flags::ColliderFlags,
|
||||
setup::{load_state::GameLoadState, assets::GltfAssets},
|
||||
};
|
||||
|
||||
use super::spawn_point::SpawnPoint;
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct DummySpawnPoint {
|
||||
pub transform: Transform,
|
||||
}
|
||||
|
||||
impl SpawnPoint for DummySpawnPoint {
|
||||
fn get_transform(&self) -> Transform {
|
||||
self.transform
|
||||
}
|
||||
}
|
||||
|
||||
/// System that runs every fame checking if player has been spawned.
|
||||
/// For player to spawn, everything inside GameLoadState must be loaded Except player.
|
||||
pub fn dummy_spawner(
|
||||
mut commands: Commands,
|
||||
dummy_sp_query: Query<(Entity, &DummySpawnPoint)>,
|
||||
game_load_state: Res<GameLoadState>,
|
||||
assets: Res<GltfAssets>,
|
||||
loaded_gltf_assets: Res<Assets<Gltf>>,
|
||||
) {
|
||||
if !game_load_state.is_everything_except_player_loaded() {
|
||||
return;
|
||||
}
|
||||
|
||||
for (dummy_spawn_point_entity, dummy_spawn_point) in dummy_sp_query.iter() {
|
||||
let dummy_scene = commands.spawn(
|
||||
(
|
||||
SceneBundle {
|
||||
scene: loaded_gltf_assets.get(assets.assets[3].asset.clone()).unwrap().scenes[0].clone(),
|
||||
transform: Transform::from_translation(Vec3::ZERO).with_scale(Vec3 { x: 3.0, y: 3.0, z: 3.0 }),
|
||||
visibility: Visibility::Inherited,
|
||||
..Default::default()
|
||||
},
|
||||
Name::new("Dummy Scene Bundle")
|
||||
)
|
||||
).id();
|
||||
|
||||
// Spawn dummy
|
||||
commands
|
||||
.spawn(TransformBundle {
|
||||
local: dummy_spawn_point.get_transform(),
|
||||
..Default::default()
|
||||
})
|
||||
.insert(
|
||||
LockedAxes::ROTATION_LOCKED_Z
|
||||
| LockedAxes::ROTATION_LOCKED_X
|
||||
| LockedAxes::ROTATION_LOCKED_Y,
|
||||
)
|
||||
.insert(VisibilityBundle {
|
||||
visibility: Visibility::Visible,
|
||||
..Default::default()
|
||||
})
|
||||
// Data
|
||||
.insert(CollisionGroups::new(Group::from_bits_retain(ColliderFlags::ENEMY.bits()), Group::from_bits_retain((ColliderFlags::SOLIDS | ColliderFlags::PLAYER | ColliderFlags::BULLETS | ColliderFlags::FLOOR).bits())))
|
||||
.insert(Name::new("Dummy"))
|
||||
.add_child(dummy_scene);
|
||||
|
||||
commands.entity(dummy_spawn_point_entity).despawn();
|
||||
println!("Spawned dummy");
|
||||
}
|
||||
}
|
|
@ -3,3 +3,4 @@ pub mod item;
|
|||
pub mod player;
|
||||
pub mod spawn;
|
||||
pub mod spawn_point;
|
||||
pub mod dummy;
|
|
@ -3,13 +3,13 @@ use bevy::prelude::*;
|
|||
use super::{
|
||||
item::{item_spawner, ItemSpawnPointPlugin},
|
||||
player::player_spawner,
|
||||
spawn_point::SpawnPointPlugin,
|
||||
spawn_point::SpawnPointPlugin, dummy::dummy_spawner,
|
||||
};
|
||||
|
||||
pub struct SpawnerPlugin;
|
||||
impl Plugin for SpawnerPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_plugins((SpawnPointPlugin, ItemSpawnPointPlugin));
|
||||
app.add_systems(Update, (player_spawner, item_spawner));
|
||||
app.add_systems(Update, (player_spawner, item_spawner, dummy_spawner));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
use crate::comps::core::spawners::player::PlayerSpawnPoint;
|
||||
use crate::comps::core::spawners::{player::PlayerSpawnPoint, dummy::DummySpawnPoint};
|
||||
|
||||
#[bevy_trait_query::queryable]
|
||||
pub trait SpawnPoint {
|
||||
|
@ -12,5 +12,6 @@ impl Plugin for SpawnPointPlugin {
|
|||
fn build(&self, app: &mut App) {
|
||||
use bevy_trait_query::RegisterExt;
|
||||
app.register_component_as::<dyn SpawnPoint, PlayerSpawnPoint>();
|
||||
app.register_component_as::<dyn SpawnPoint, DummySpawnPoint>();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,9 @@ pub trait Attachment {
|
|||
/// Starts at 1
|
||||
fn current_attachment_index(&self) -> u32;
|
||||
fn all_attachments() -> Vec<Self> where Self: Sized;
|
||||
/// Horizontal recoil % to remove. Additive
|
||||
fn horizontal_recoil_modifier(&self) -> f32;
|
||||
fn vertical_recoil_modifier(&self) -> f32;
|
||||
}
|
||||
|
||||
/// Used to switch attachments.
|
||||
|
|
|
@ -20,4 +20,14 @@ impl Attachment for Compensator {
|
|||
fn all_attachments() -> Vec<Self> where Self: Sized {
|
||||
Vec::from([Self::FirstCompensator])
|
||||
}
|
||||
|
||||
fn horizontal_recoil_modifier(&self) -> f32 {
|
||||
0.12
|
||||
}
|
||||
|
||||
fn vertical_recoil_modifier(&self) -> f32 {
|
||||
0.12
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -20,4 +20,12 @@ impl Attachment for ForeGrip {
|
|||
fn all_attachments() -> Vec<Self> where Self: Sized {
|
||||
Vec::from([Self::Pk5])
|
||||
}
|
||||
|
||||
fn horizontal_recoil_modifier(&self) -> f32 {
|
||||
0.06
|
||||
}
|
||||
|
||||
fn vertical_recoil_modifier(&self) -> f32 {
|
||||
0.06
|
||||
}
|
||||
}
|
|
@ -33,4 +33,12 @@ impl Attachment for Magazine {
|
|||
fn all_attachments() -> Vec<Self> where Self: Sized {
|
||||
Vec::from([Self::Ak105])
|
||||
}
|
||||
|
||||
fn horizontal_recoil_modifier(&self) -> f32 {
|
||||
0.0
|
||||
}
|
||||
|
||||
fn vertical_recoil_modifier(&self) -> f32 {
|
||||
0.0
|
||||
}
|
||||
}
|
|
@ -1,4 +1,7 @@
|
|||
use bevy::{reflect::{Reflect, std_traits::ReflectDefault}, ecs::{component::Component, reflect::ReflectComponent}, math::Vec3};
|
||||
use bevy::{reflect::{Reflect, std_traits::ReflectDefault}, ecs::{component::Component, reflect::ReflectComponent}, math::Vec3, pbr::StandardMaterial, render::color::Color};
|
||||
use bevy_inspector_egui::egui::Rgba;
|
||||
|
||||
use crate::comps::core::weapons::{optic_data::OpticData, reticle::SightReticle};
|
||||
|
||||
use super::attachment::Attachment;
|
||||
|
||||
|
@ -16,6 +19,39 @@ impl Optic {
|
|||
Optic::AimpointT1 => Vec3 { x: 0.0, y: -0.05, z: 0.0 },
|
||||
}
|
||||
}
|
||||
|
||||
/// Goes from 5-500
|
||||
pub fn default_reticle_brightness(&self) -> f32 {
|
||||
200.0
|
||||
}
|
||||
|
||||
pub fn reticle(&self) -> SightReticle {
|
||||
match self {
|
||||
Optic::AimpointT1 => SightReticle::Dot(0.05, Color::rgb_linear(1.0, 0.0, 0.0)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn optic_data(&self) -> OpticData {
|
||||
OpticData { optic_pos_y: None, reticle_brightness: self.default_reticle_brightness() }
|
||||
}
|
||||
|
||||
pub fn sight_glass_material(&self) -> StandardMaterial {
|
||||
match self {
|
||||
Optic::AimpointT1 => {
|
||||
StandardMaterial {
|
||||
base_color: Color::Rgba { red: 0.0, green: 0.47, blue: 0.42, alpha: 0.48 },
|
||||
reflectance: 0.0,
|
||||
diffuse_transmission: -2.0,
|
||||
specular_transmission: -1.8,
|
||||
thickness: 0.0,
|
||||
ior: 0.0,
|
||||
attenuation_distance: 1.0,
|
||||
alpha_mode: bevy::pbr::AlphaMode::Blend,
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Attachment for Optic {
|
||||
|
@ -28,5 +64,13 @@ impl Attachment for Optic {
|
|||
fn all_attachments() -> Vec<Self> where Self: Sized {
|
||||
Vec::from([Self::AimpointT1])
|
||||
}
|
||||
|
||||
fn horizontal_recoil_modifier(&self) -> f32 {
|
||||
0.0
|
||||
}
|
||||
|
||||
fn vertical_recoil_modifier(&self) -> f32 {
|
||||
0.0
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,4 +20,12 @@ impl Attachment for Silencer {
|
|||
fn all_attachments() -> Vec<Self> where Self: Sized {
|
||||
Vec::from([Self::FirstSilencer])
|
||||
}
|
||||
|
||||
fn horizontal_recoil_modifier(&self) -> f32 {
|
||||
0.10
|
||||
}
|
||||
|
||||
fn vertical_recoil_modifier(&self) -> f32 {
|
||||
0.10
|
||||
}
|
||||
}
|
|
@ -20,4 +20,12 @@ impl Attachment for Stock {
|
|||
fn all_attachments() -> Vec<Self> where Self: Sized {
|
||||
Vec::from([Self::MagpullTan])
|
||||
}
|
||||
|
||||
fn horizontal_recoil_modifier(&self) -> f32 {
|
||||
0.23
|
||||
}
|
||||
|
||||
fn vertical_recoil_modifier(&self) -> f32 {
|
||||
0.23
|
||||
}
|
||||
}
|
|
@ -23,20 +23,20 @@ impl Default for WeaponAttachment {
|
|||
impl WeaponAttachment {
|
||||
pub fn vertical_recoil_modifier(&self) -> f32 {
|
||||
match self {
|
||||
WeaponAttachment::Compensator(_) => 0.0,
|
||||
WeaponAttachment::Magazine(_) => 0.0,
|
||||
WeaponAttachment::Stock(_) => 0.0,
|
||||
WeaponAttachment::ForeGrip(_) => 0.0,
|
||||
WeaponAttachment::Optic(_) => 0.0,
|
||||
WeaponAttachment::Compensator(comp) => comp.vertical_recoil_modifier(),
|
||||
WeaponAttachment::Magazine(mag) => mag.vertical_recoil_modifier(),
|
||||
WeaponAttachment::Stock(stock) => stock.vertical_recoil_modifier(),
|
||||
WeaponAttachment::ForeGrip(foregrip) => foregrip.vertical_recoil_modifier(),
|
||||
WeaponAttachment::Optic(optic) => optic.vertical_recoil_modifier(),
|
||||
}
|
||||
}
|
||||
pub fn horizontal_recoil_modifier(&self) -> f32 {
|
||||
match self {
|
||||
WeaponAttachment::Compensator(_) => 0.0,
|
||||
WeaponAttachment::Magazine(_) => 0.0,
|
||||
WeaponAttachment::Stock(_) => 0.0,
|
||||
WeaponAttachment::ForeGrip(_) => 0.0,
|
||||
WeaponAttachment::Optic(_) => 0.0,
|
||||
WeaponAttachment::Compensator(comp) => comp.horizontal_recoil_modifier(),
|
||||
WeaponAttachment::Magazine(mag) => mag.horizontal_recoil_modifier(),
|
||||
WeaponAttachment::Stock(stock) => stock.horizontal_recoil_modifier(),
|
||||
WeaponAttachment::ForeGrip(foregrip) => foregrip.horizontal_recoil_modifier(),
|
||||
WeaponAttachment::Optic(optic) => optic.horizontal_recoil_modifier(),
|
||||
}
|
||||
}
|
||||
pub fn asset_path<'a>(&self) -> &'a str {
|
||||
|
|
|
@ -1,82 +1,74 @@
|
|||
use bevy::reflect::Reflect;
|
||||
|
||||
#[allow(unused)]
|
||||
/// Unit = m/s
|
||||
/// When a bullet reaches this speed (213 fps == 64.92), it is no longer able to penetrate human bone.
|
||||
///
|
||||
/// Quote: `The speed at which a projectile must travel to penetrate skin is 163 fps and to break bone is 213 fps, both of which are quite low, so other factors are more important in producing damage. (Belkin, 1978)`
|
||||
///
|
||||
/// [Source](https://webpath.med.utah.edu/TUTORIAL/GUNS/GUNBLST.html#:~:text=The%20speed%20at%20which%20a,more%20important%20in%20producing%20damage.)
|
||||
pub const MIN_LETHAL_BULLET_VELOCITY: f32 = 64.92;
|
||||
|
||||
#[derive(Clone, Reflect, Default)]
|
||||
pub enum Caliber {
|
||||
/// 5.56x45mm
|
||||
/// Reference [Wikipedia](https://en.wikipedia.org/wiki/5.56%C3%9745mm_NATO)
|
||||
NATO556,
|
||||
/// 9x19mm
|
||||
/// 9x19mm Parabellum (NATO)
|
||||
/// Reference: [Wikipedia](https://en.wikipedia.org/wiki/9%C3%9719mm_Parabellum)
|
||||
#[default]
|
||||
Parabellum9mm,
|
||||
NATOParabellum9mm,
|
||||
/// 5.45x39mm (7N6M)
|
||||
/// Reference: [Wikipedia](https://en.wikipedia.org/wiki/5.45%C3%9739mm)
|
||||
RU545
|
||||
}
|
||||
impl Caliber {
|
||||
/// Unit = Meters
|
||||
/// Not real for the moment as this is just to make sure the bullet despawns if it goes too far
|
||||
pub fn range(&self) -> f32 {
|
||||
match self {
|
||||
Caliber::NATO556 => 7500.0,
|
||||
Caliber::Parabellum9mm => 2500.0,
|
||||
Caliber::NATOParabellum9mm => 2500.0,
|
||||
Caliber::RU545 => 4500.0,
|
||||
}
|
||||
}
|
||||
pub fn max_airtime_secs(&self) -> f32 {
|
||||
match self {
|
||||
Caliber::NATO556 => 3.0,
|
||||
Caliber::Parabellum9mm => 3.0,
|
||||
Caliber::RU545 => 3.0,
|
||||
}
|
||||
}
|
||||
pub fn impulse(&self) -> f32 {
|
||||
match self {
|
||||
Caliber::NATO556 => 100.0,
|
||||
Caliber::Parabellum9mm => 50.0,
|
||||
Caliber::RU545 => 75.0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Unit = kg
|
||||
/// Real life value (BULLET WEIGHT)
|
||||
pub fn mass(&self) -> f32 {
|
||||
match self {
|
||||
Caliber::NATO556 => 0.00402,
|
||||
Caliber::Parabellum9mm => 0.05,
|
||||
Caliber::NATOParabellum9mm => 0.0052,
|
||||
Caliber::RU545 => 0.00343,
|
||||
}
|
||||
}
|
||||
pub fn linear_damping(&self) -> f32 {
|
||||
match self {
|
||||
Caliber::NATO556 => 1.0,
|
||||
Caliber::Parabellum9mm => 2.0,
|
||||
Caliber::RU545 => 1.5,
|
||||
}
|
||||
}
|
||||
pub fn angular_damping(&self) -> f32 {
|
||||
match self {
|
||||
Caliber::NATO556 => 1.0,
|
||||
Caliber::Parabellum9mm => 1.0,
|
||||
Caliber::RU545 => 1.0,
|
||||
}
|
||||
}
|
||||
/// Unit = meters
|
||||
/// Real life value (BULLET DIAMETER/2)
|
||||
pub fn size(&self) -> f32 {
|
||||
match self {
|
||||
Caliber::NATO556 => 0.07,
|
||||
Caliber::Parabellum9mm => 0.05,
|
||||
Caliber::RU545 => 0.06
|
||||
Caliber::NATOParabellum9mm => 0.05,
|
||||
Caliber::RU545 => 0.0056/2.0
|
||||
}
|
||||
}
|
||||
|
||||
/// Unit = m/s
|
||||
/// Real life value (Muzzle velocity)
|
||||
/// (TODO: Factor in the barrel that it is being shot from)
|
||||
pub fn muzzle_velocity(&self) -> f32 {
|
||||
match self {
|
||||
Caliber::NATO556 => 991.0,
|
||||
Caliber::Parabellum9mm => todo!(),
|
||||
Caliber::NATOParabellum9mm => 460.0,
|
||||
Caliber::RU545 => 880.0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Unit = m/s
|
||||
/// Can't find accurate information for real bullets, so invented these values based on how good the wiki says they are long range.
|
||||
pub fn velocity_shed(&self) -> f32 {
|
||||
match self {
|
||||
Caliber::NATO556 => todo!(),
|
||||
Caliber::Parabellum9mm => todo!(),
|
||||
Caliber::RU545 => 120.0,
|
||||
Caliber::NATO556 => 150.0,
|
||||
Caliber::NATOParabellum9mm => 450.0,
|
||||
Caliber::RU545 => 300.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ impl Firearm {
|
|||
}*/
|
||||
Firearm::Glock17 => {
|
||||
FirearmData {
|
||||
caliber: Caliber::Parabellum9mm,
|
||||
caliber: Caliber::NATOParabellum9mm,
|
||||
fire_rate: 600.0,
|
||||
aim_time_seconds: 0.1,
|
||||
rebound_time_seconds: 0.5,
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
use super::{attachment_slot::AttachmentSlot, slot::slot::WeaponSlot, magazine_data::MagazineData, attachments::{weapon_attachment::WeaponAttachment, attachment::Position}};
|
||||
use super::{attachment_slot::AttachmentSlot, slot::slot::WeaponSlot, magazine_data::MagazineData, attachments::{weapon_attachment::WeaponAttachment, attachment::Position}, optic_data::OpticData};
|
||||
|
||||
#[derive(Component, Reflect, PartialEq, Debug, Clone)]
|
||||
pub struct FirearmState {
|
||||
pub attachment_slots: Vec<AttachmentSlot>,
|
||||
pub magazine_data: Option<MagazineData>,
|
||||
pub optic_pos: Option<Vec3>,
|
||||
pub optic_data: Option<OpticData>,
|
||||
}
|
||||
|
||||
impl FirearmState {
|
||||
pub fn new(attachment_slots: Vec<AttachmentSlot>, magazine_data: Option<MagazineData>) -> Self {
|
||||
Self { attachment_slots, magazine_data: None, optic_pos: None }
|
||||
pub fn new(attachment_slots: Vec<AttachmentSlot>, magazine_data: Option<MagazineData>, optic_data: Option<OpticData>) -> Self {
|
||||
Self { attachment_slots, magazine_data, optic_data}
|
||||
}
|
||||
|
||||
/// Call this function when a user requests to switch an attachment in a specific slot.
|
||||
|
@ -48,4 +48,30 @@ impl FirearmState {
|
|||
}
|
||||
Vec3::ZERO
|
||||
}
|
||||
|
||||
pub fn get_optic_pos_opt(&self) -> Option<f32> {
|
||||
match self.optic_data {
|
||||
Some(ref optic_data) => optic_data.optic_pos_y,
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_horizontal_recoil_modifier(&self) -> f32 {
|
||||
let mut total = 0.0;
|
||||
self.attachment_slots.iter().for_each(|attachment| {
|
||||
if let Some(attachment) = &attachment.attachment {
|
||||
total += attachment.horizontal_recoil_modifier()
|
||||
}
|
||||
});
|
||||
1.0 - total
|
||||
}
|
||||
pub fn get_vertical_recoil_modifier(&self) -> f32 {
|
||||
let mut total = 0.0;
|
||||
self.attachment_slots.iter().for_each(|attachment| {
|
||||
if let Some(attachment) = &attachment.attachment {
|
||||
total += attachment.vertical_recoil_modifier()
|
||||
}
|
||||
});
|
||||
1.0 - total
|
||||
}
|
||||
}
|
|
@ -7,4 +7,6 @@ pub mod magazine_data;
|
|||
pub mod slot;
|
||||
pub mod parts;
|
||||
pub mod firearm_state;
|
||||
pub mod attachment_slot;
|
||||
pub mod attachment_slot;
|
||||
pub mod optic_data;
|
||||
pub mod reticle;
|
|
@ -0,0 +1,21 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
#[derive(PartialEq, Clone, Debug, Reflect)]
|
||||
pub struct OpticData {
|
||||
/// The y position of the optic on the mounted gun
|
||||
/// A value of None means use the y_pos that the gun came with.
|
||||
/// In other words, the user hasn't changed the position of the optic.
|
||||
pub optic_pos_y: Option<f32>,
|
||||
/// Adjustable setting for each reticle in every optic.
|
||||
/// 1.0 == baseline
|
||||
pub reticle_brightness: f32,
|
||||
}
|
||||
|
||||
impl Default for OpticData {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
optic_pos_y: None,
|
||||
reticle_brightness: 1.0,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
use bevy::{prelude::*, sprite::MaterialMesh2dBundle};
|
||||
|
||||
use crate::comps::core::markers::proxy::weapons::reticle::DrawnReticle;
|
||||
|
||||
#[derive(Reflect, PartialEq, Clone, Debug)]
|
||||
pub enum SightReticle {
|
||||
/// Reticle Radius & Reticle Color
|
||||
Dot(f32, Color),
|
||||
}
|
||||
|
||||
impl Default for SightReticle {
|
||||
fn default() -> Self {
|
||||
Self::Dot(0.05, Color::rgb_linear(1.0, 0.0, 0.0))
|
||||
}
|
||||
}
|
||||
|
||||
impl SightReticle {
|
||||
pub fn spawn(self, commands: &mut Commands, parent: Entity, meshes: &mut ResMut<Assets<Mesh>>, materials: &mut ResMut<Assets<StandardMaterial>>) {
|
||||
match self {
|
||||
SightReticle::Dot(radius, color) => {
|
||||
commands.spawn((
|
||||
MaterialMeshBundle {
|
||||
mesh: meshes.add(shape::Circle::new(radius).into()).into(),
|
||||
material: materials.add(StandardMaterial {
|
||||
emissive: color,
|
||||
..Default::default()
|
||||
}),
|
||||
transform: {
|
||||
let mut t = Transform::from_translation(Vec3::ZERO);
|
||||
t.rotate_x(90.0f32.to_radians());
|
||||
t
|
||||
},
|
||||
..default()
|
||||
}
|
||||
,
|
||||
Name::new("Reticle"),
|
||||
DrawnReticle,
|
||||
)).set_parent(parent);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_color(&self) -> Color {
|
||||
match self {
|
||||
SightReticle::Dot(_, color) => color.clone(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,17 +9,15 @@
|
|||
use bevy::{prelude::*, ecs::system::SystemParam};
|
||||
use bevy_rapier3d::{pipeline::CollisionEvent, rapier::geometry::CollisionEventFlags, geometry::Sensor};
|
||||
|
||||
use crate::comps::core::{markers::{bullet::BulletMarker, proxy::weapons::gun_colliders::GunFirearmCollider}, events::{bullet_collision::BulletCollisionEvent, equipped_gun_collision::EquippedGunCollisionEvent, collision_event_type::CollisionEventType}};
|
||||
use crate::comps::core::{markers::{bullet::BulletMarker, proxy::weapons::gun_colliders::GunFirearmCollider}, events::{equipped_gun_collision::EquippedGunCollisionEvent, collision_event_type::CollisionEventType}};
|
||||
|
||||
#[derive(SystemParam)]
|
||||
pub struct CollisionHandlerQueryParams<'w, 's> {
|
||||
bullets: Query<'w, 's, (Entity, &'static Transform), With<BulletMarker>>,
|
||||
firearms: Query<'w, 's, Entity, (With<Sensor>, With<GunFirearmCollider>, Without<BulletMarker>)>,
|
||||
}
|
||||
|
||||
#[derive(SystemParam)]
|
||||
pub struct CollisionHandlerEventParams<'w> {
|
||||
bullet_collision_events: EventWriter<'w, BulletCollisionEvent>,
|
||||
equipped_gun_collision_events: EventWriter<'w, EquippedGunCollisionEvent>,
|
||||
}
|
||||
|
||||
|
@ -62,25 +60,5 @@ pub fn collision_handler(
|
|||
}
|
||||
continue; // Continue, as we already handled sensor collisions
|
||||
}
|
||||
// ######
|
||||
// Bullet collisions
|
||||
// ######
|
||||
for (bullet, bullet_transform) in queries.bullets.iter() {
|
||||
if entity_a == &bullet {
|
||||
events.bullet_collision_events.send(BulletCollisionEvent {
|
||||
bullet,
|
||||
other: *entity_b,
|
||||
at: *bullet_transform,
|
||||
collision_type,
|
||||
});
|
||||
} else if entity_b == &bullet {
|
||||
events.bullet_collision_events.send(BulletCollisionEvent {
|
||||
bullet,
|
||||
other: *entity_a,
|
||||
at: *bullet_transform,
|
||||
collision_type,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use crate::comps::core::{markers::{bullet::BulletMarker, muzzle_flash::MuzzleFlashMarker}, events::{bullet_collision::BulletCollisionEvent, collision_event_type::CollisionEventType}};
|
||||
use crate::comps::core::{markers::muzzle_flash::MuzzleFlashMarker, events::{bullet_collision::BulletCollisionEvent, collision_event_type::CollisionEventType}};
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub fn despawn_muzzle_flashes(
|
||||
|
@ -18,18 +18,13 @@ pub fn despawn_stray_bullets(
|
|||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
mut query: Query<(&mut BulletMarker, Entity, &Transform)>,
|
||||
|
||||
mut bullet_collisions: EventReader<BulletCollisionEvent>,
|
||||
time: Res<Time>,
|
||||
) {
|
||||
let collisions_read: Vec<&BulletCollisionEvent> = bullet_collisions.read().collect();
|
||||
for event in collisions_read.into_iter() {
|
||||
match event.collision_type {
|
||||
CollisionEventType::Start => {
|
||||
|
||||
//commands.entity(event.bullet).remove::<Collider>();
|
||||
//commands.entity(bullet_entity).insert(Sensor);
|
||||
spawn_bullet_hit_marker(
|
||||
&mut commands,
|
||||
event.at.translation,
|
||||
|
@ -38,15 +33,6 @@ pub fn despawn_stray_bullets(
|
|||
);
|
||||
},
|
||||
CollisionEventType::End => {
|
||||
/*for (_, bullet_entity, _) in query.iter() {
|
||||
if bullet_entity != event.bullet { continue; }
|
||||
/*commands
|
||||
.entity(event.bullet)
|
||||
.insert(Collider::ball(bullet.caliber.size()));*/
|
||||
}*/
|
||||
|
||||
//commands.entity(bullet_entity).remove::<Sensor>();
|
||||
//commands.entity(*entity_b).despawn();
|
||||
spawn_bullet_exit_marker(
|
||||
&mut commands,
|
||||
event.at.translation,
|
||||
|
@ -57,15 +43,6 @@ pub fn despawn_stray_bullets(
|
|||
} //_ => {}
|
||||
}
|
||||
}
|
||||
for (mut bullet, bullet_entity, transform) in query.iter_mut() {
|
||||
bullet.timer.tick(time.delta());
|
||||
if bullet.timer.finished() {
|
||||
commands.entity(bullet_entity).despawn();
|
||||
}
|
||||
if transform.translation.distance(bullet.starting_point) > bullet.caliber.range() {
|
||||
commands.entity(bullet_entity).despawn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spawn_bullet_hit_marker(
|
||||
|
@ -87,7 +64,6 @@ pub fn spawn_bullet_hit_marker(
|
|||
},
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: Color::GREEN,
|
||||
//base_color_texture: Some(Color::GREEN),
|
||||
emissive: Color::GREEN,
|
||||
..Default::default()
|
||||
}),
|
||||
|
@ -116,7 +92,6 @@ fn spawn_bullet_exit_marker(
|
|||
},
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: Color::RED,
|
||||
//base_color_texture: Some(Color::GREEN),
|
||||
emissive: Color::RED,
|
||||
..Default::default()
|
||||
}),
|
||||
|
|
|
@ -83,7 +83,7 @@ pub fn inspect_firearm(
|
|||
}
|
||||
firearm_state.switch_attachment_by_pos(slot, None);
|
||||
if slot == &WeaponSlot::SightSlot {
|
||||
firearm_state.optic_pos = None;
|
||||
firearm_state.optic_data = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -111,7 +111,9 @@ pub fn inspect_firearm(
|
|||
if !find_child_in_parent_children(&mut commands, in_player_hands_entity, firearm_entity, &queries.children) {
|
||||
continue;
|
||||
}
|
||||
firearm_state.optic_pos = Some(slot_transform.translation);
|
||||
if let Some(optic_data) = firearm_state.optic_data.as_mut() {
|
||||
optic_data.optic_pos_y = Some(slot_transform.translation.y);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -3,4 +3,5 @@ pub mod player_firing;
|
|||
pub mod shoot;
|
||||
pub mod inspect;
|
||||
pub mod equipped_gun_collisions;
|
||||
pub mod update_bullet;
|
||||
pub mod update_bullet;
|
||||
pub mod reticle;
|
|
@ -27,6 +27,7 @@ pub struct PlayerFiringInfo {
|
|||
/// This is specifically for situations where the player is holding a gun that is stuck against a wall, and should not be false
|
||||
/// until the gun stops colliding with the wall.
|
||||
pub gun_colliding_with_object: bool,
|
||||
pub is_aiming: bool,
|
||||
}
|
||||
|
||||
impl Default for PlayerFiringInfo {
|
||||
|
@ -40,6 +41,7 @@ impl Default for PlayerFiringInfo {
|
|||
gun_ready_pose: GunReadyPose::LowReady,
|
||||
is_inspecting: false,
|
||||
gun_colliding_with_object: false,
|
||||
is_aiming: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
use bevy::{prelude::*, ecs::system::SystemParam};
|
||||
|
||||
use crate::comps::core::{markers::{proxy::weapons::{optic_sight_glass::OpticSightGlass, reticle::DrawnReticle}, camera::MainCamera}, weapons::{firearm_state::FirearmState, parts::firing_point::FiringPoint}};
|
||||
|
||||
|
||||
#[derive(SystemParam)]
|
||||
pub struct UpdateReticleQueryParams<'w, 's> {
|
||||
sight_query_added: Query<'w, 's, (Entity, &'static OpticSightGlass), Added<OpticSightGlass>>,
|
||||
sight_query: Query<'w, 's, (Entity, &'static OpticSightGlass)>,
|
||||
reticle_query: Query<'w, 's, (&'static Parent, &'static Handle<StandardMaterial>, &'static DrawnReticle, &'static mut Transform),>,
|
||||
firearm_state: Query<'w, 's, &'static FirearmState, Changed<FirearmState>>,
|
||||
firing_point_query: Query<'w, 's, &'static GlobalTransform, (With<FiringPoint>, Without<DrawnReticle>)>,
|
||||
main_camera_query: Query<'w, 's, (&'static Camera, &'static GlobalTransform), (With<MainCamera>, Without<FiringPoint>, Without<DrawnReticle>)>,
|
||||
}
|
||||
/// How?
|
||||
/// Achieve parallax on all reticles by drawing a line straight out of the barrel and a straight line from the sight that intersected at the specified zeroed range for the optic.
|
||||
/// Make sure that the reticle is where the bullets will land at the specified zeroed range.
|
||||
pub fn update_reticle(
|
||||
mut commands: Commands,
|
||||
// TODO: make this identify which optic is on the gun, but meanwhile just start doing it to all the optics in
|
||||
mut query: UpdateReticleQueryParams,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
|
||||
// Spawn reticles
|
||||
for (entity, sight) in query.sight_query_added.iter() {
|
||||
let reticle = sight.0.reticle();
|
||||
reticle.spawn(&mut commands, entity, &mut meshes, &mut materials);
|
||||
}
|
||||
// Modify reticle brightness
|
||||
for (optic_entity, optic_sight_glass) in query.sight_query.iter() {
|
||||
for (reticle_parent, reticle_material, _, mut reticle_transform) in query.reticle_query.iter_mut () {
|
||||
if optic_entity != reticle_parent.get() { continue; }
|
||||
for firearm_state in query.firearm_state.iter() {
|
||||
if let Some(ref optic_data) = firearm_state.optic_data {
|
||||
if let Some(mat) = materials.get_mut(reticle_material) {
|
||||
mat.emissive = optic_sight_glass.0.reticle().get_color() * optic_data.reticle_brightness;
|
||||
}
|
||||
}
|
||||
}
|
||||
for firing_point_transform in query.firing_point_query.iter() {
|
||||
for (cam, cam_transform) in query.main_camera_query.iter() {
|
||||
let point_at_range = firing_point_transform.translation() + firing_point_transform.forward() * 50.0;
|
||||
/*match cam.world_to_viewport(cam_transform, point_at_range) {
|
||||
Some(_) => todo!(),
|
||||
None => todo!(),
|
||||
};
|
||||
|
||||
|
||||
reticle_transform.translation.x = point_at_range.x;
|
||||
reticle_transform.translation.y = point_at_range.y;*/
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -38,26 +38,6 @@ pub fn shoot_bullet(
|
|||
MuzzleFlashMarker(Timer::new(Duration::from_millis(10), TimerMode::Once)),
|
||||
));
|
||||
|
||||
// Spawn Line
|
||||
/*if player_settings.shot_lines_enabled {
|
||||
commands.spawn(
|
||||
MaterialMeshBundle {
|
||||
mesh: {
|
||||
let mut mesh = Mesh::new(PrimitiveTopology::LineStrip);
|
||||
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, Vec::from([Vec3::ZERO, forward * caliber.range()]));
|
||||
meshes.add(mesh)
|
||||
},
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: Color::GREEN,
|
||||
..Default::default()
|
||||
}),
|
||||
visibility: Visibility::Visible,
|
||||
transform: firing_point,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}*/
|
||||
|
||||
spawn_bullet(
|
||||
commands,
|
||||
meshes,
|
||||
|
@ -83,10 +63,6 @@ pub fn spawn_bullet(
|
|||
BulletMarker {
|
||||
caliber: caliber.clone(),
|
||||
starting_point: firing_point.translation,
|
||||
timer: Timer::new(
|
||||
Duration::from_secs_f32(caliber.max_airtime_secs()),
|
||||
TimerMode::Once,
|
||||
),
|
||||
current_velocity: forward * caliber.muzzle_velocity(),
|
||||
hits: Vec::new()
|
||||
},
|
||||
|
@ -116,6 +92,6 @@ pub fn spawn_bullet(
|
|||
},
|
||||
RigidBody::KinematicPositionBased,
|
||||
ActiveEvents::COLLISION_EVENTS,
|
||||
CollisionGroups::new(Group::from_bits_retain(ColliderFlags::BULLETS.bits()), Group::from_bits_retain((ColliderFlags::SOLIDS | ColliderFlags::FLOOR).bits())),
|
||||
CollisionGroups::new(Group::from_bits_retain(ColliderFlags::BULLETS.bits()), Group::from_bits_retain((ColliderFlags::SOLIDS | ColliderFlags::FLOOR | ColliderFlags::ENEMY).bits())),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use bevy::{prelude::*, render::render_resource::PrimitiveTopology, ecs::system::SystemParam};
|
||||
use bevy_rapier3d::prelude::*;
|
||||
|
||||
use crate::{comps::core::{markers::{bullet::{BulletMarker, BulletHit}, proxy::weapons::gun_colliders::GunFirearmCollider}, events::{bullet_collision::BulletCollisionEvent, collision_event_type::CollisionEventType}}, logic::core::player::player_settings::PlayerSettings};
|
||||
use crate::{comps::core::{markers::{bullet::{BulletMarker, BulletHit}, proxy::weapons::gun_colliders::GunFirearmCollider}, events::{bullet_collision::BulletCollisionEvent, collision_event_type::CollisionEventType}, weapons::caliber::MIN_LETHAL_BULLET_VELOCITY}, logic::core::player::player_settings::PlayerSettings};
|
||||
|
||||
#[derive(SystemParam)]
|
||||
pub struct UpdateBulletQueryParams<'w, 's> {
|
||||
|
@ -20,6 +20,13 @@ pub fn update_bullet(
|
|||
mut bullet_collision_event: EventWriter<BulletCollisionEvent>,
|
||||
) {
|
||||
for (bullet, mut marker, mut transform) in query.bullets.iter_mut() {
|
||||
|
||||
let normalized_vel = (marker.current_velocity.normalize() * MIN_LETHAL_BULLET_VELOCITY).abs();
|
||||
if transform.translation.distance(marker.starting_point) > marker.caliber.range() || normalized_vel.x + normalized_vel.z > marker.current_velocity.abs().x + marker.current_velocity.abs().z {
|
||||
commands.entity(bullet).despawn();
|
||||
continue;
|
||||
}
|
||||
|
||||
let future_frame_pos = (marker.current_velocity * time.delta_seconds()) + (Vec3 { x: 0.0, y: -9.81, z: 0.0 } * time.delta_seconds() * marker.caliber.mass());
|
||||
|
||||
let max_toi = transform.translation.distance(future_frame_pos + transform.translation);
|
||||
|
@ -46,7 +53,7 @@ pub fn update_bullet(
|
|||
},
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: Color::RED,
|
||||
emissive: Color::RED,
|
||||
emissive: Color::RED * 10.0,
|
||||
..Default::default()
|
||||
}),
|
||||
visibility: Visibility::Visible,
|
||||
|
@ -56,7 +63,6 @@ pub fn update_bullet(
|
|||
);
|
||||
}
|
||||
|
||||
// Raycast to future frame pos
|
||||
transform.translation += future_frame_pos;
|
||||
let vel_shed = marker.caliber.velocity_shed() * marker.current_velocity.normalize() * time.delta_seconds();
|
||||
marker.current_velocity -= vel_shed;
|
||||
|
|
|
@ -27,6 +27,13 @@ impl Default for MouseMovementSettings {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Component, Clone, Debug, Reflect, Default)]
|
||||
#[reflect(Component)]
|
||||
pub struct HandSwaying {
|
||||
pub sway_pos: Vec3,
|
||||
pub sway_rot: Quat,
|
||||
}
|
||||
|
||||
/// Synchronizes camera's translation to player.
|
||||
pub fn update_camera_vertical_position(
|
||||
mut player: Query<(&mut Transform, &PlayerLinearXZState), (With<Player>, Without<PlayerEye>)>,
|
||||
|
@ -71,12 +78,13 @@ pub struct FollowCursorWithCameraQueryParams<'w, 's> {
|
|||
player_query: Query<'w, 's, &'static mut Transform, (With<Player>, Without<MainCamera>)>,
|
||||
camera_query: Query<'w, 's, &'static mut Transform, (With<MainCamera>, Without<Player>)>,
|
||||
player_model_query: Query<'w, 's, &'static mut Transform, (With<PlayerCharacter>, Without<Player>, Without<MainCamera>)>,
|
||||
in_player_hands_query: Query<'w, 's, &'static mut Transform, (With<InPlayerHands>, Without<Player>, Without<MainCamera>, Without<PlayerCharacter>)>,
|
||||
in_player_hands_query: Query<'w, 's, Entity, (With<InPlayerHands>, Without<Player>, Without<MainCamera>, Without<PlayerCharacter>)>,
|
||||
//in_player_hands_parent_query: Query<'w, 's, &'static mut Transform, (With<InPlayerHandsParent>, Without<Player>, Without<MainCamera>, Without<PlayerCharacter>, Without<InPlayerHands>)>
|
||||
}
|
||||
|
||||
/// Handles looking around if cursor is locked
|
||||
pub fn follow_cursor_with_camera(
|
||||
mut commands: Commands,
|
||||
settings: Res<MouseMovementSettings>,
|
||||
mut motions: EventReader<MouseMotion>,
|
||||
keyboard_input: Res<Input<KeyCode>>,
|
||||
|
@ -134,6 +142,11 @@ pub fn follow_cursor_with_camera(
|
|||
for mut camera_transform in query.camera_query.iter_mut() {
|
||||
for mut player_model_transform in query.player_model_query.iter_mut() {
|
||||
let (mut yaw, mut pitch) = (player_transform.rotation.to_euler(EulerRot::YXZ).0, camera_transform.rotation.to_euler(EulerRot::YXZ).1) ;
|
||||
if motions.len() == 0 {
|
||||
for in_player_hands_entity in query.in_player_hands_query.iter() {
|
||||
commands.entity(in_player_hands_entity).insert(HandSwaying { sway_pos: Vec3::ZERO, sway_rot: Quat::default() });
|
||||
}
|
||||
}
|
||||
for motion in motions.read() {
|
||||
let window_scale = window.height().min(window.width());
|
||||
let mut weapon_sway_vec = Vec3::ZERO;
|
||||
|
@ -175,9 +188,10 @@ pub fn follow_cursor_with_camera(
|
|||
weapon_sway_vec_rot.y = weapon_sway_vec_rot.y.clamp(-0.5, 0.5);
|
||||
}
|
||||
// Weapon Sway
|
||||
for mut in_player_hands_transform in query.in_player_hands_query.iter_mut() {
|
||||
in_player_hands_transform.translation = in_player_hands_transform.translation.lerp(weapon_sway_vec, time.delta_seconds() * 1.0);
|
||||
in_player_hands_transform.rotation = in_player_hands_transform.rotation.lerp(Quat::from_euler(EulerRot::XYZ, weapon_sway_vec_rot.x, weapon_sway_vec_rot.y, weapon_sway_vec_rot.y), time.delta_seconds() * 3.0);
|
||||
for in_player_hands_entity in query.in_player_hands_query.iter() {
|
||||
commands.entity(in_player_hands_entity).insert(HandSwaying { sway_pos: weapon_sway_vec, sway_rot: Quat::from_euler(EulerRot::XYZ, weapon_sway_vec_rot.x, weapon_sway_vec_rot.y, weapon_sway_vec_rot.y) });
|
||||
//in_player_hands_transform.translation = in_player_hands_transform.translation.lerp(weapon_sway_vec, time.delta_seconds() * 1.0);
|
||||
//in_player_hands_transform.rotation = in_player_hands_transform.rotation.lerp(Quat::from_euler(EulerRot::XYZ, weapon_sway_vec_rot.x, weapon_sway_vec_rot.y, weapon_sway_vec_rot.y), time.delta_seconds() * 3.0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy_rapier3d::dynamics::Velocity;
|
||||
|
||||
use crate::{comps::core::markers::{player::Player, holdable::InPlayerHands, firearm_scene::FirearmScene}, logic::core::guns::player_firing::PlayerFiringInfo};
|
||||
|
||||
use super::{player_movement::{PlayerLinearYState, PlayerMovementInput, PlayerLinearXZState}, camera_player_sync::HandSwaying};
|
||||
|
||||
#[derive(Component, Clone, Debug, Reflect, Default)]
|
||||
#[reflect(Component)]
|
||||
pub struct HandBobbing {
|
||||
pub speed_curve: f32,
|
||||
pub bob_position: Vec3,
|
||||
pub bob_euler_rotation: Vec3,
|
||||
}
|
||||
|
||||
/// The maximum limits of travel from move input
|
||||
const TRAVEL_LIMIT: Vec3 = Vec3 { x: 0.01, y: 0.01, z: 0.01 };
|
||||
/// The maximum limits of travel from bobbing over time
|
||||
const BOBBING_LIMIT: Vec3 = Vec3 { x: 0.01, y: 0.01, z: 0.01 };
|
||||
const BOBBING_ROT_MULTIPLIER: Vec3 = Vec3 { x: 2.0, y: 2.0, z: 2.0};
|
||||
|
||||
pub fn hand_bobbing_on_player_movement(
|
||||
player_query: Query<(&Velocity, &PlayerLinearYState, &PlayerLinearXZState, &PlayerMovementInput, &PlayerFiringInfo), With<Player>>,
|
||||
|
||||
in_player_hands_query: Query<(Entity, &HandSwaying), With<InPlayerHands>>,
|
||||
mut firearm_scene_query: Query<(&Parent, &mut Transform, &mut HandBobbing), (With<Handle<Scene>>, With<FirearmScene>)>,
|
||||
time: Res<Time>,
|
||||
) {
|
||||
for (in_player_hands, hand_swaying) in in_player_hands_query.iter() {
|
||||
for (firearm_scene_parent, mut firearm_scene_transform, mut hand_bobbing) in firearm_scene_query.iter_mut() {
|
||||
if in_player_hands == firearm_scene_parent.get() {
|
||||
for (player_velocity, player_linear_y_state, player_linear_xz_state, player_movement_input, player_firing_info) in player_query.iter() {
|
||||
let bobbing_limit = BOBBING_LIMIT *
|
||||
if player_linear_xz_state.is_sprinting() { 2.0 } else { 1.0 } *
|
||||
if player_linear_xz_state.is_crouched() { 0.9 } else { 1.0 } *
|
||||
if player_firing_info.is_aiming { 0.6 } else { 1.0 };
|
||||
let travel_limit = TRAVEL_LIMIT *
|
||||
if player_linear_xz_state.is_sprinting() { 1.0 } else { 1.0 } *
|
||||
if player_linear_xz_state.is_crouched() { 0.9 } else { 1.0 } *
|
||||
if player_firing_info.is_aiming { 0.6 } else { 1.0 };
|
||||
let bobbing_rot_multiplier = BOBBING_ROT_MULTIPLIER *
|
||||
if player_linear_xz_state.is_sprinting() { 2.0 } else { 1.0 } *
|
||||
if player_linear_xz_state.is_crouched() { 0.9 } else { 1.0 } *
|
||||
if player_firing_info.is_aiming { 0.6 } else { 1.0 };
|
||||
// Speed curve
|
||||
hand_bobbing.speed_curve += time.delta_seconds() *
|
||||
if player_linear_y_state.is_grounded(&0.25) {
|
||||
if player_linear_xz_state.is_sprinting() { player_velocity.linvel.length() / 2.0 } else { player_velocity.linvel.length() }
|
||||
} else { 1.0 };
|
||||
|
||||
// Bobbing translation
|
||||
hand_bobbing.bob_position.x = (hand_bobbing.speed_curve.cos() * bobbing_limit.x * (
|
||||
if player_linear_y_state.is_grounded(&0.25) { 1.0 } else { 0.0 }
|
||||
)) - (player_movement_input.get_horizontal_value_normalized() * travel_limit.x);
|
||||
|
||||
hand_bobbing.bob_position.y = (hand_bobbing.speed_curve.sin() * bobbing_limit.y) - (player_velocity.linvel.y * travel_limit.y);
|
||||
|
||||
hand_bobbing.bob_position.z = player_movement_input.get_vertical_value_normalized() * travel_limit.z * -1.0;
|
||||
|
||||
// Bobbing rotation
|
||||
let input = player_movement_input.get_input();
|
||||
hand_bobbing.bob_euler_rotation.x = if input == Vec2::ZERO {
|
||||
bobbing_rot_multiplier.x * ((hand_bobbing.speed_curve * 2.0).sin() / 2.0)
|
||||
} else {
|
||||
bobbing_rot_multiplier.x * (hand_bobbing.speed_curve * 2.0).sin()
|
||||
};
|
||||
|
||||
hand_bobbing.bob_euler_rotation.y = if input == Vec2::ZERO { 0.0 } else {
|
||||
bobbing_rot_multiplier.y * hand_bobbing.speed_curve.cos()
|
||||
};
|
||||
|
||||
hand_bobbing.bob_euler_rotation.z = if input == Vec2::ZERO { 0.0 } else {
|
||||
bobbing_rot_multiplier.z * hand_bobbing.speed_curve.cos() * input.x
|
||||
};
|
||||
|
||||
// Applying bobbing + sway to actual transform
|
||||
firearm_scene_transform.translation = firearm_scene_transform.translation.lerp(
|
||||
hand_bobbing.bob_position + hand_swaying.sway_pos, time.delta_seconds() * 5.0);
|
||||
|
||||
firearm_scene_transform.rotation = firearm_scene_transform.rotation.slerp(
|
||||
hand_swaying.sway_rot * Quat::from_euler(EulerRot::XYZ,
|
||||
hand_bobbing.bob_euler_rotation.x.to_radians(), hand_bobbing.bob_euler_rotation.y.to_radians(), hand_bobbing.bob_euler_rotation.z.to_radians()
|
||||
), time.delta_seconds() * 12.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -60,6 +60,8 @@ pub fn capture_hand_usage(
|
|||
mut equipment_change_event_writer: EventWriter<EquipmentChangeEvent>,
|
||||
mut inventory_changed_events: EventWriter<PlayerInventoryChangedEvent>,
|
||||
mut mouse_wheel_events: EventReader<MouseWheel>,
|
||||
|
||||
mut gizmos: Gizmos,
|
||||
) {
|
||||
if !resources.game_load_state.player_loaded {
|
||||
return;
|
||||
|
@ -92,7 +94,7 @@ pub fn capture_hand_usage(
|
|||
};
|
||||
*hand_transform = hand_transform.lerp(default_hand_transform, resources.time.delta_seconds() / 0.25);
|
||||
}
|
||||
|
||||
let scroll_events: Vec<&MouseWheel> = mouse_wheel_events.read().collect();
|
||||
if !resources.game_ui_state.any_window() && !player_firing_info.is_reloading {
|
||||
if resources.keyboard_input.just_pressed(resources.player_controls.primary_weapon) {
|
||||
if let Some(primary_item) = player_inventory.get_primary() {
|
||||
|
@ -142,9 +144,9 @@ pub fn capture_hand_usage(
|
|||
if player.0.equipment.is_firearm() {
|
||||
player_firing_info.is_inspecting = true;
|
||||
}
|
||||
} else if !mouse_wheel_events.is_empty() {
|
||||
} else if !scroll_events.is_empty() {
|
||||
if player.0.equipment.is_firearm() {
|
||||
for mouse_wheel_event in mouse_wheel_events.read() {
|
||||
for mouse_wheel_event in scroll_events.iter() {
|
||||
if player_firing_info.gun_colliding_with_object { continue; }
|
||||
if mouse_wheel_event.y >= 0.0 {
|
||||
player_firing_info.gun_ready_pose = GunReadyPose::HighReady;
|
||||
|
@ -201,6 +203,7 @@ pub fn capture_hand_usage(
|
|||
&& !resources.game_ui_state.any_window() && !player_linear_xz_state.is_sprinting()
|
||||
&& !player_firing_info.gun_colliding_with_object
|
||||
{
|
||||
player_firing_info.is_aiming = true;
|
||||
player_firing_info.gun_ready_pose = GunReadyPose::HighReady;
|
||||
let rotation_lerp_quat = in_hand_transform.rotation.lerp(
|
||||
firearm_data.final_aimed_rotation + resources.player_settings.rot_aimed_offset,
|
||||
|
@ -216,7 +219,18 @@ pub fn capture_hand_usage(
|
|||
);
|
||||
in_hand_transform.rotation = rotation_lerp_quat;
|
||||
in_hand_transform.translation = position_lerp_vec3;
|
||||
|
||||
if resources.keyboard_input.pressed(resources.player_controls.reticle_adjustment_requisite) {
|
||||
if let Some(ref mut optic_data) = firearm_state.optic_data {
|
||||
for mouse_wheel_event in scroll_events.iter() {
|
||||
let add_to_brightness = mouse_wheel_event.y * resources.time.delta_seconds() * 2000.0;
|
||||
// println!("{}, {}", mouse_wheel_event.y, add_to_brightness);
|
||||
optic_data.reticle_brightness = (optic_data.reticle_brightness + add_to_brightness).clamp(5.0, 500.0); // TODO: Clamp values correctly (introduce variables in optic or firearmstate stating min. and max. values)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
player_firing_info.is_aiming = false;
|
||||
in_hand_transform.rotation = in_hand_transform.rotation.lerp(
|
||||
firearm_data.rotation_offset + resources.player_settings.rot_offset,
|
||||
(resources.time.delta_seconds()
|
||||
|
@ -235,7 +249,9 @@ pub fn capture_hand_usage(
|
|||
if resources.mouse_buttons.pressed(MouseButton::Left) // Shooting (LClick)
|
||||
&& !resources.game_ui_state.any_window() && player_firing_info.gun_ready_pose == GunReadyPose::HighReady
|
||||
{
|
||||
if let Some(magazine_data) = &mut firearm_state.magazine_data {
|
||||
let firearm_vert_recoil_modifier = firearm_state.get_vertical_recoil_modifier();
|
||||
let firearm_horiz_recoil_modifier = firearm_state.get_horizontal_recoil_modifier();
|
||||
if let Some(ref mut magazine_data) = firearm_state.magazine_data {
|
||||
if player_firing_info.full_auto_timer.finished() {
|
||||
if magazine_data.rounds_shot < magazine_data.max_capacity {
|
||||
// Get recoil numbers from patterns
|
||||
|
@ -274,16 +290,24 @@ pub fn capture_hand_usage(
|
|||
player_firing_info.full_auto_timer.reset();
|
||||
magazine_data.rounds_shot += 1;
|
||||
|
||||
|
||||
let crouch_recoil_modifier = if player_linear_xz_state.is_crouched() {
|
||||
0.6
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
// Apply recoil
|
||||
in_hand_transform.rotate_x(radians_from_degrees(
|
||||
//TODO: Recoil modifier firearm_data.vertical_recoil_modifier
|
||||
-1.0 * 2.0
|
||||
* vertical_recoil_number,
|
||||
* vertical_recoil_number
|
||||
* firearm_horiz_recoil_modifier
|
||||
* crouch_recoil_modifier,
|
||||
));
|
||||
in_hand_transform.rotate_y(radians_from_degrees(
|
||||
//TODO: Recoil modifier firearm_data.horizontal_recoil_modifier
|
||||
1.0 * 0.5
|
||||
* horizontal_recoil_number,
|
||||
* horizontal_recoil_number
|
||||
* firearm_vert_recoil_modifier
|
||||
* crouch_recoil_modifier,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -298,6 +322,11 @@ pub fn capture_hand_usage(
|
|||
player_firing_info.current_round_index = 0;
|
||||
}
|
||||
}
|
||||
if player_firing_info.gun_ready_pose == GunReadyPose::HighReady {
|
||||
for (firing_point_transform, firing_point_parent) in queries.firing_point_query.iter() {
|
||||
gizmos.line(firing_point_transform.translation(), firing_point_transform.forward() * 100000.0, Color::RED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,4 +7,5 @@ pub mod player_values_state;
|
|||
pub mod player_vertical_sync;
|
||||
pub mod animate_player;
|
||||
pub mod camera_switching;
|
||||
pub mod player_settings;
|
||||
pub mod player_settings;
|
||||
pub mod hand_bobbing;
|
|
@ -74,7 +74,8 @@ impl PlayerLinearXZState {
|
|||
}
|
||||
|
||||
/// Holds all the possible ways a player can be attempting to move at any time.
|
||||
#[derive(Default, Reflect)]
|
||||
#[derive(Default, Reflect, Component, Clone)]
|
||||
#[reflect(Component)]
|
||||
pub struct PlayerMovementInput {
|
||||
/// Means the player is pressing the space bar key. (JUMP)
|
||||
/// ## DOES NOT MEAN the player should gain upwards velocity
|
||||
|
@ -102,9 +103,11 @@ pub struct PlayerMovementInput {
|
|||
*/
|
||||
/// Applies game logic to determine how player should move.
|
||||
pub fn move_player(
|
||||
mut commands: Commands,
|
||||
player_movement_input: PlayerMovementInput,
|
||||
mut query: Query<
|
||||
(
|
||||
Entity,
|
||||
&mut Velocity,
|
||||
&mut ExternalImpulse,
|
||||
&mut PlayerLinearYState,
|
||||
|
@ -119,6 +122,7 @@ pub fn move_player(
|
|||
player_values_state: Res<PlayerValuesState>,
|
||||
) {
|
||||
for (
|
||||
player_entity,
|
||||
mut player_velocity,
|
||||
mut player_external_force,
|
||||
mut player_linear_y_state,
|
||||
|
@ -128,6 +132,7 @@ pub fn move_player(
|
|||
mut player_firing_info,
|
||||
) in &mut query
|
||||
{
|
||||
commands.entity(player_entity).insert(player_movement_input.clone());
|
||||
if player_linear_xz_state.is_sprinting() {
|
||||
player_firing_info.gun_ready_pose = GunReadyPose::LowReady;
|
||||
}
|
||||
|
@ -146,6 +151,11 @@ pub fn move_player(
|
|||
} else {
|
||||
1.0
|
||||
};
|
||||
let aimed_in_multiplier = if player_firing_info.is_aiming {
|
||||
0.6
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
let local_z = player_transform.local_z();
|
||||
let forward = -Vec3::new(local_z.x, 0.0, local_z.z);
|
||||
let right = Vec3::new(local_z.z, 0.0, -local_z.x);
|
||||
|
@ -162,7 +172,7 @@ pub fn move_player(
|
|||
forward,
|
||||
player_velocity.linvel,
|
||||
time.delta_seconds(),
|
||||
sprint_multiplier * crouch_multiplier,
|
||||
sprint_multiplier * crouch_multiplier * aimed_in_multiplier,
|
||||
player_values_state.player_acceleration,
|
||||
);
|
||||
}
|
||||
|
@ -177,7 +187,7 @@ pub fn move_player(
|
|||
-forward,
|
||||
player_velocity.linvel,
|
||||
time.delta_seconds(),
|
||||
crouch_multiplier,
|
||||
crouch_multiplier * aimed_in_multiplier,
|
||||
player_values_state.player_acceleration,
|
||||
);
|
||||
}
|
||||
|
@ -197,7 +207,7 @@ pub fn move_player(
|
|||
* crouch_multiplier
|
||||
} else {
|
||||
player_values_state.player_lateral_acceleration_multiplier
|
||||
* crouch_multiplier
|
||||
* crouch_multiplier * aimed_in_multiplier
|
||||
},
|
||||
player_values_state.player_acceleration,
|
||||
);
|
||||
|
@ -218,7 +228,7 @@ pub fn move_player(
|
|||
* crouch_multiplier
|
||||
} else {
|
||||
player_values_state.player_lateral_acceleration_multiplier
|
||||
* crouch_multiplier
|
||||
* crouch_multiplier * aimed_in_multiplier
|
||||
},
|
||||
player_values_state.player_acceleration,
|
||||
);
|
||||
|
@ -245,9 +255,10 @@ pub fn move_player(
|
|||
player_velocity.linvel.x = player_values_state.max_linear_player_velocity
|
||||
* crouch_multiplier
|
||||
* sprint_multiplier
|
||||
* aimed_in_multiplier
|
||||
} else {
|
||||
player_velocity.linvel.x =
|
||||
player_values_state.max_linear_player_velocity * -1.0 * crouch_multiplier
|
||||
player_values_state.max_linear_player_velocity * -1.0 * crouch_multiplier * aimed_in_multiplier
|
||||
}
|
||||
}
|
||||
if player_velocity.linvel.z.abs()
|
||||
|
@ -256,10 +267,10 @@ pub fn move_player(
|
|||
let positive = player_velocity.linvel.z.is_sign_positive();
|
||||
if positive {
|
||||
player_velocity.linvel.z =
|
||||
player_values_state.max_linear_player_velocity * crouch_multiplier * sprint_multiplier
|
||||
player_values_state.max_linear_player_velocity * crouch_multiplier * sprint_multiplier * aimed_in_multiplier
|
||||
} else {
|
||||
player_velocity.linvel.z =
|
||||
player_values_state.max_linear_player_velocity * -1.0 * crouch_multiplier * sprint_multiplier
|
||||
player_values_state.max_linear_player_velocity * -1.0 * crouch_multiplier * sprint_multiplier * aimed_in_multiplier
|
||||
}
|
||||
}
|
||||
if player_velocity.linvel.x > -1.0
|
||||
|
@ -283,3 +294,34 @@ fn apply_movement_acceleration_to_vec(
|
|||
) -> Vec3 {
|
||||
current_linvel + (direction * player_acceleration * delta_time_secs * multiplier)
|
||||
}
|
||||
|
||||
|
||||
impl PlayerMovementInput {
|
||||
pub fn get_horizontal_value_normalized(&self) -> f32 {
|
||||
let mut val = 0.0;
|
||||
if self.left {
|
||||
val -= 1.0;
|
||||
}
|
||||
if self.right {
|
||||
val += 1.0;
|
||||
}
|
||||
val
|
||||
}
|
||||
/// Vertical == forward and backward
|
||||
pub fn get_vertical_value_normalized(&self) -> f32 {
|
||||
let mut val = 0.0;
|
||||
if self.back {
|
||||
val -= 1.0;
|
||||
}
|
||||
if self.front {
|
||||
val += 1.0;
|
||||
}
|
||||
val
|
||||
}
|
||||
pub fn get_input(&self) -> Vec2 {
|
||||
Vec2 {
|
||||
x: self.get_horizontal_value_normalized(),
|
||||
y: self.get_vertical_value_normalized(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,10 +28,12 @@ fn main() {
|
|||
|
||||
fn setup_plugins(application: &mut App) {
|
||||
application
|
||||
.add_plugins(DefaultPlugins.set(AssetPlugin::default()))
|
||||
.add_plugins(DefaultPlugins.set(AssetPlugin {
|
||||
..Default::default()
|
||||
}))
|
||||
//.add_plugins(DefaultInspectorConfigPlugin)
|
||||
.add_plugins(RapierPhysicsPlugin::<NoUserData>::default())
|
||||
//.add_plugins(RapierDebugRenderPlugin::default())
|
||||
.add_plugins(RapierDebugRenderPlugin::default())
|
||||
.add_plugins(ComponentsFromGltfPlugin)
|
||||
//.add_plugins(bevy_egui::EguiPlugin)
|
||||
//.add_plugins(WorldInspectorPlugin::new())
|
||||
|
|
|
@ -7,14 +7,14 @@ use crate::{
|
|||
spawners::{player::player_spawner, spawn::SpawnerPlugin}, events::{bullet_collision::BulletCollisionEvent, equipped_gun_collision::EquippedGunCollisionEvent},
|
||||
},
|
||||
logic::core::{
|
||||
guns::{despawn_shots::{despawn_muzzle_flashes, despawn_stray_bullets}, inspect::inspect_firearm, equipped_gun_collisions::update_gun_position_on_collision, update_bullet::update_bullet},
|
||||
guns::{despawn_shots::{despawn_muzzle_flashes, despawn_stray_bullets}, inspect::inspect_firearm, equipped_gun_collisions::update_gun_position_on_collision, update_bullet::update_bullet, reticle::update_reticle},
|
||||
player::{
|
||||
camera_player_sync::{
|
||||
follow_cursor_with_camera, update_camera_vertical_position, MouseMovementSettings,
|
||||
},
|
||||
hands::{capture_hand_usage, interact_action},
|
||||
player_values_state::PlayerValuesState,
|
||||
player_vertical_sync::sync_player_y_state, camera_switching::switch_camera,
|
||||
player_vertical_sync::sync_player_y_state, camera_switching::switch_camera, hand_bobbing::hand_bobbing_on_player_movement,
|
||||
}, collisions::collision_handler,
|
||||
},
|
||||
setup::{
|
||||
|
@ -63,6 +63,8 @@ pub fn load_scene(application: &mut App) {
|
|||
application.add_systems(Update, collision_handler);
|
||||
application.add_systems(Update, update_gun_position_on_collision);
|
||||
application.add_systems(Update, update_bullet);
|
||||
application.add_systems(Update, update_reticle);
|
||||
application.add_systems(Update, hand_bobbing_on_player_movement);
|
||||
|
||||
//application.add_systems(Update, animate_player);
|
||||
//application.add_systems(Update, register_bullet_hits);
|
||||
|
|
|
@ -4,8 +4,8 @@ use crate::{
|
|||
comps::core::{
|
||||
markers::player::{Player, PlayerData},
|
||||
spawners::{
|
||||
guns::{glock17_spawner::Glock17SpawnPoint, ak105_spawner::Ak105SpawnPoint},
|
||||
player::PlayerSpawnPoint,
|
||||
guns::ak105_spawner::Ak105SpawnPoint,
|
||||
player::PlayerSpawnPoint, dummy::DummySpawnPoint,
|
||||
},
|
||||
},
|
||||
utils,
|
||||
|
@ -23,25 +23,29 @@ pub fn set_spawn_points(mut commands: Commands) {
|
|||
transform
|
||||
},
|
||||
});*/
|
||||
commands.spawn(Glock17SpawnPoint {
|
||||
/*commands.spawn(Glock17SpawnPoint {
|
||||
transform: {
|
||||
let mut transform = Transform::from_xyz(20.0, 10.0, 10.0);
|
||||
transform.rotate_z(utils::rad_deg::radians_from_degrees(-90.0));
|
||||
transform
|
||||
},
|
||||
});*/
|
||||
|
||||
commands.spawn(DummySpawnPoint {
|
||||
transform: Transform::from_xyz(15.0, 0.1, 20.0),
|
||||
});
|
||||
|
||||
commands.spawn(Ak105SpawnPoint ::new_fully_kitted_default({
|
||||
commands.spawn(Ak105SpawnPoint::new_fully_kitted_default({
|
||||
let mut transform = Transform::from_xyz(18.0, 10.0, 18.0);
|
||||
transform.rotate_z(utils::rad_deg::radians_from_degrees(-90.0));
|
||||
transform
|
||||
}));
|
||||
|
||||
commands.spawn(Glock17SpawnPoint {
|
||||
/*commands.spawn(Glock17SpawnPoint {
|
||||
transform: {
|
||||
let mut transform = Transform::from_xyz(20.0, 10.0, 20.0);
|
||||
transform.rotate_z(utils::rad_deg::radians_from_degrees(-90.0));
|
||||
transform
|
||||
},
|
||||
});
|
||||
});*/
|
||||
}
|
||||
|
|
|
@ -7,8 +7,7 @@ pub enum GltfAssetType {
|
|||
Firearm(Firearm),
|
||||
Attachment(WeaponAttachment),
|
||||
Character,
|
||||
#[allow(unused)]
|
||||
Enemy,
|
||||
OtherPlayer,
|
||||
}
|
||||
|
||||
#[derive(Resource, Reflect, Default)]
|
||||
|
@ -87,11 +86,16 @@ pub fn load_all_assets(
|
|||
asset_type: GltfAssetType::Character,
|
||||
asset: asset_server.load("character/main_character.glb"),
|
||||
};
|
||||
let other_player_character_asset = GltfAsset {
|
||||
asset_type: GltfAssetType::OtherPlayer,
|
||||
asset: asset_server.load("character/other_player_character.glb"),
|
||||
};
|
||||
|
||||
commands.insert_resource(GltfAssets {
|
||||
assets: Vec::from([/*m4a1_gltf_asset, */
|
||||
ak105_gltf_asset, glock17_gltf_asset, // Firearms
|
||||
main_character_asset, // Characters
|
||||
other_player_character_asset, // Enemies
|
||||
aimpoint_t1_gltf_asset, pk5_foregrip_gltf_asset, ak105_magazine_gltf_asset, first_compensator_gltf_asset, tan_magpull_stock_gltf_asset // Attachments
|
||||
]),
|
||||
});
|
||||
|
|
|
@ -5,9 +5,9 @@ use bevy::{gltf::Gltf, prelude::*};
|
|||
use crate::{
|
||||
comps::core::{markers::{
|
||||
holdable::InPlayerHands,
|
||||
player::Player, proxy::character::in_player_hands_parent::InPlayerHandsParent,
|
||||
player::Player, proxy::character::in_player_hands_parent::InPlayerHandsParent, firearm_scene::FirearmScene,
|
||||
}, weapons::{firearm::Firearm, firearm_data::FirearmData, firearm_state::FirearmState}, events::pickup_item::ItemState, items::item::ItemId},
|
||||
logic::core::guns::player_firing::PlayerFiringInfo,
|
||||
logic::core::{guns::player_firing::PlayerFiringInfo, player::hand_bobbing::HandBobbing},
|
||||
utils::{self},
|
||||
};
|
||||
|
||||
|
@ -43,38 +43,40 @@ pub fn change_equipment(
|
|||
loaded_gltf_assets: Res<Assets<Gltf>>,
|
||||
) {
|
||||
for equipment_change_event in equipment_change_event_reader.read() {
|
||||
let Ok((mut player, player_firing_info)) = player_query.get_single_mut() else {
|
||||
let Ok((mut player, mut player_firing_info)) = player_query.get_single_mut() else {
|
||||
return;
|
||||
};
|
||||
//if player_firing_info.is_reloading { return; }
|
||||
// Primary firearm change
|
||||
let player_hands = player_hands_query.single_mut();
|
||||
|
||||
commands.entity(player_hands).despawn_descendants(); // TODO: Don't do this without keeping the state from the last mag
|
||||
for player_hands in player_hands_query.iter_mut() {
|
||||
commands.entity(player_hands).despawn_descendants(); // TODO: Don't do this without keeping the state from the last mag
|
||||
|
||||
if let Equipment::Firearm(new_firearm, firearm_state) = equipment_change_event.0.clone() {
|
||||
// Add sensor to firearm collider if it is a child of player_hands
|
||||
spawn_firearm_on_player_hands(
|
||||
&mut commands,
|
||||
player_firing_info,
|
||||
player_hands,
|
||||
&assets_gltf,
|
||||
&loaded_gltf_assets,
|
||||
new_firearm,
|
||||
firearm_state,
|
||||
equipment_change_event.1.clone().expect("Spawning firearm on player hands without an ItemId"),
|
||||
);
|
||||
if let Equipment::Firearm(new_firearm, firearm_state) = equipment_change_event.0.clone() {
|
||||
// Add sensor to firearm collider if it is a child of player_hands
|
||||
spawn_firearm_on_player_hands(
|
||||
&mut commands,
|
||||
&mut player_firing_info,
|
||||
player_hands,
|
||||
&assets_gltf,
|
||||
&loaded_gltf_assets,
|
||||
new_firearm,
|
||||
firearm_state,
|
||||
equipment_change_event.1.clone().expect("Spawning firearm on player hands without an ItemId"),
|
||||
);
|
||||
}
|
||||
|
||||
// Set the player's equipment to the newly spawned equipment
|
||||
player.0.equipment = equipment_change_event.0.clone();
|
||||
println!("Equipment change done");
|
||||
}
|
||||
|
||||
// Set the player's equipment to the newly spawned equipment
|
||||
player.0.equipment = equipment_change_event.0.clone();
|
||||
println!("Equipment change done");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fn spawn_firearm_on_player_hands(
|
||||
commands: &mut Commands,
|
||||
mut player_firing_info: Mut<PlayerFiringInfo>,
|
||||
player_firing_info: &mut PlayerFiringInfo,
|
||||
player_hands: Entity,
|
||||
assets_gltf: &GltfAssets,
|
||||
loaded_gltf_assets: &Assets<Gltf>,
|
||||
|
@ -107,6 +109,8 @@ fn spawn_firearm_on_player_hands(
|
|||
},
|
||||
ItemState::Weapon(firearm_state),
|
||||
Name::new("Firearm Gltf Asset"),
|
||||
FirearmScene,
|
||||
HandBobbing { speed_curve: 0.0, bob_position: Vec3::ZERO, bob_euler_rotation: Vec3::ZERO },
|
||||
))
|
||||
.id();
|
||||
let firearm_entity = commands
|
||||
|
|
|
@ -6,13 +6,13 @@ use crate::{
|
|||
comps::core::{markers::{
|
||||
holdable::{HoldableObjectData, InPlayerHands},
|
||||
player::{Player, PlayerData, PlayerHand}, inspect_screen::InspectScreenSlotUiMarker, bullet::BulletMarker,
|
||||
}, weapons::{firearm_data::FirearmData, magazine_data::MagazineData, caliber::Caliber, firearm::Firearm, spray_pattern::FirearmSprayPattern, firearm_state::FirearmState}},
|
||||
}, weapons::{firearm_data::FirearmData, magazine_data::MagazineData, caliber::Caliber, firearm::Firearm, spray_pattern::FirearmSprayPattern, firearm_state::FirearmState, reticle::SightReticle}},
|
||||
logic::core::{
|
||||
guns::player_firing::PlayerFiringInfo,
|
||||
player::{
|
||||
camera_player_sync::MouseMovementSettings,
|
||||
player_movement::{PlayerLinearXZState, PlayerLinearYState, PlayerMovementInput},
|
||||
player_values_state::PlayerValuesState, player_settings::PlayerSettings,
|
||||
player_values_state::PlayerValuesState, player_settings::PlayerSettings, hand_bobbing::HandBobbing,
|
||||
},
|
||||
},
|
||||
scenes::scene1::skybox::Cubemap,
|
||||
|
@ -57,6 +57,8 @@ impl Plugin for MainEditorUiPlugin {
|
|||
.register_type::<PlayerSettings>()
|
||||
.register_type::<InspectScreenSlotUiMarker>()
|
||||
.register_type::<PlayerControls>()
|
||||
.register_type::<SightReticle>()
|
||||
.register_type::<HandBobbing>()
|
||||
//.register_type::<AllAnimations>()
|
||||
//.register_type::<FirearmAnimations>()
|
||||
.register_type::<GltfAssetType>()
|
||||
|
|
|
@ -74,12 +74,10 @@ pub fn update_inspect_screen(
|
|||
for player_firing_info in player_firing_info_query.iter() {
|
||||
if player_firing_info.is_inspecting {
|
||||
*inspect_screen_visibility = Visibility::Visible;
|
||||
// TODO: Build
|
||||
for (camera, camera_transform) in camera_query.iter() {
|
||||
for (mut inspect_slot_visibility, mut inspect_slot, mut inspect_slot_style, mut inspect_slot_border_color) in inspect_slots_query.iter_mut() {
|
||||
for (slot, slot_transform) in slots_query.iter() {
|
||||
if &inspect_slot.slot == slot {
|
||||
//inspect_slot_text.sections.first_mut().expect("No section in an already created text...").value = format!("{}", slot.get_index());
|
||||
match camera.world_to_viewport(camera_transform, slot_transform.translation()) {
|
||||
Some(pos_vec) => {
|
||||
*inspect_slot_visibility = Visibility::Visible;
|
||||
|
|
|
@ -57,6 +57,9 @@ pub struct PlayerControls {
|
|||
|
||||
pub inventory: KeyCode,
|
||||
|
||||
/// Press this key and then adjust with another key
|
||||
pub reticle_adjustment_requisite: KeyCode,
|
||||
|
||||
}
|
||||
|
||||
impl Default for PlayerControls {
|
||||
|
@ -100,6 +103,8 @@ impl Default for PlayerControls {
|
|||
low_ready: ControlsInput::ScrollWheel(ScrollWheelInput::Down),
|
||||
|
||||
inventory: KeyCode::Tab,
|
||||
|
||||
reticle_adjustment_requisite: KeyCode::ShiftLeft,
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue