Compare commits
3 Commits
a2b88af375
...
8d3e5e581a
Author | SHA1 | Date |
---|---|---|
Mark | 8d3e5e581a | |
Mark | d6a3e10a84 | |
Mark | 98b460aba9 |
|
@ -75,6 +75,12 @@ version = "0.2.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04"
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
|
@ -147,6 +153,12 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arc-swap"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6"
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.7"
|
||||
|
@ -315,6 +327,20 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41daef31d7a747c5c847246f36de49ced6f7403b4cdabc807a97b5cc184cda7a"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"wasm-bindgen",
|
||||
"windows-targets 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.4.18"
|
||||
|
@ -535,6 +561,23 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derivative"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "destructure_traitobject"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c877555693c14d2f84191cfd3ad8582790fc52b5e2274b40b59cf5f5cea25c7"
|
||||
|
||||
[[package]]
|
||||
name = "dispatch"
|
||||
version = "0.2.0"
|
||||
|
@ -634,6 +677,12 @@ dependencies = [
|
|||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "fontconfig-parser"
|
||||
version = "0.5.3"
|
||||
|
@ -724,6 +773,8 @@ dependencies = [
|
|||
"galactica-system",
|
||||
"galactica-util",
|
||||
"image",
|
||||
"log",
|
||||
"log4rs",
|
||||
"nalgebra",
|
||||
"pollster",
|
||||
"rand",
|
||||
|
@ -741,6 +792,7 @@ dependencies = [
|
|||
"galactica-util",
|
||||
"image",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"nalgebra",
|
||||
"rapier2d",
|
||||
"serde",
|
||||
|
@ -787,6 +839,7 @@ dependencies = [
|
|||
"galactica-util",
|
||||
"glyphon",
|
||||
"image",
|
||||
"log",
|
||||
"nalgebra",
|
||||
"rand",
|
||||
"wgpu",
|
||||
|
@ -927,7 +980,7 @@ checksum = "cc11df1ace8e7e564511f53af41f3e42ddc95b56fd07b3f4445d2a6048bc682c"
|
|||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"gpu-descriptor-types",
|
||||
"hashbrown",
|
||||
"hashbrown 0.14.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -948,6 +1001,12 @@ dependencies = [
|
|||
"crunchy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.3"
|
||||
|
@ -985,6 +1044,35 @@ version = "0.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.59"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.24.7"
|
||||
|
@ -1004,6 +1092,16 @@ dependencies = [
|
|||
"tiff",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown 0.12.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.1.0"
|
||||
|
@ -1011,7 +1109,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
"hashbrown 0.14.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1026,6 +1124,12 @@ dependencies = [
|
|||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys"
|
||||
version = "0.3.0"
|
||||
|
@ -1131,6 +1235,12 @@ dependencies = [
|
|||
"redox_syscall 0.4.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.11"
|
||||
|
@ -1146,6 +1256,41 @@ name = "log"
|
|||
version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log-mdc"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a94d21414c1f4a51209ad204c1776a3d0765002c76c6abcb602a6f09f1e881c7"
|
||||
|
||||
[[package]]
|
||||
name = "log4rs"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d36ca1786d9e79b8193a68d480a0907b612f109537115c6ff655a3a1967533fd"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"arc-swap",
|
||||
"chrono",
|
||||
"derivative",
|
||||
"fnv",
|
||||
"humantime",
|
||||
"libc",
|
||||
"log",
|
||||
"log-mdc",
|
||||
"parking_lot",
|
||||
"serde",
|
||||
"serde-value",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"thiserror",
|
||||
"thread-id",
|
||||
"typemap-ors",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lru"
|
||||
|
@ -1153,7 +1298,7 @@ version = "0.12.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2994eeba8ed550fd9b47a0b38f0242bc3344e496483c6180b69139cc2fa5d1d7"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
"hashbrown 0.14.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1255,7 +1400,7 @@ dependencies = [
|
|||
"bitflags 2.4.1",
|
||||
"codespan-reporting",
|
||||
"hexf-parse",
|
||||
"indexmap",
|
||||
"indexmap 2.1.0",
|
||||
"log",
|
||||
"num-traits",
|
||||
"rustc-hash",
|
||||
|
@ -1517,6 +1662,15 @@ dependencies = [
|
|||
"libredox",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordered-float"
|
||||
version = "2.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "owned_ttf_parser"
|
||||
version = "0.20.0"
|
||||
|
@ -1824,6 +1978,12 @@ dependencies = [
|
|||
"unicode-script",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
|
||||
|
||||
[[package]]
|
||||
name = "safe_arch"
|
||||
version = "0.7.1"
|
||||
|
@ -1882,6 +2042,16 @@ dependencies = [
|
|||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-value"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
|
||||
dependencies = [
|
||||
"ordered-float",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.193"
|
||||
|
@ -1893,6 +2063,17 @@ dependencies = [
|
|||
"syn 2.0.42",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb0652c533506ad7a2e353cce269330d6afd8bdfb6d75e0ace5b35aacbd7b9e9"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.5"
|
||||
|
@ -1902,6 +2083,18 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.8.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b"
|
||||
dependencies = [
|
||||
"indexmap 1.9.3",
|
||||
"ryu",
|
||||
"serde",
|
||||
"yaml-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simba"
|
||||
version = "0.8.1"
|
||||
|
@ -1970,7 +2163,7 @@ version = "2.5.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd774eb23cff002036706e6ea83c3f4ab4c80dad89da76fe16d49f77ab71682f"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
"hashbrown 0.14.3",
|
||||
"num-traits",
|
||||
"robust",
|
||||
"smallvec",
|
||||
|
@ -2089,6 +2282,16 @@ dependencies = [
|
|||
"syn 2.0.42",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread-id"
|
||||
version = "4.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0ec81c46e9eb50deaa257be2f148adf052d1fb7701cfd55ccfab2525280b70b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiff"
|
||||
version = "0.9.0"
|
||||
|
@ -2167,7 +2370,7 @@ version = "0.19.15"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"indexmap 2.1.0",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
@ -2178,7 +2381,7 @@ version = "0.21.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"indexmap 2.1.0",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
|
@ -2197,6 +2400,15 @@ version = "0.20.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4"
|
||||
|
||||
[[package]]
|
||||
name = "typemap-ors"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a68c24b707f02dd18f1e4ccceb9d49f2058c2fb86384ef9972592904d7a28867"
|
||||
dependencies = [
|
||||
"unsafe-any-ors",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.17.0"
|
||||
|
@ -2263,6 +2475,15 @@ version = "0.2.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
|
||||
|
||||
[[package]]
|
||||
name = "unsafe-any-ors"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0a303d30665362d9680d7d91d78b23f5f899504d4f08b3c4cf08d055d87c0ad"
|
||||
dependencies = [
|
||||
"destructure_traitobject",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
|
@ -2891,6 +3112,15 @@ version = "0.13.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4"
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
||||
dependencies = [
|
||||
"linked-hash-map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yazi"
|
||||
version = "0.1.6"
|
||||
|
|
|
@ -72,3 +72,5 @@ toml = "0.8.8"
|
|||
glyphon = "0.4.1"
|
||||
lazy_static = "1.4.0"
|
||||
clap = { version = "4.4.18", features = ["derive"] }
|
||||
log = "0.4.20"
|
||||
log4rs = { version = "1.2.0", features = ["console_appender"] }
|
||||
|
|
23
TODO.md
23
TODO.md
|
@ -1,14 +1,12 @@
|
|||
# Specific projects
|
||||
|
||||
## Currently working on:
|
||||
- first: sticky effects
|
||||
- first: read state from image so we can add objects?
|
||||
- clickable buttons
|
||||
- planet outfitter
|
||||
|
||||
|
||||
## Small jobs
|
||||
- 🌟 clean up and document short sprite sections
|
||||
- 🌟 Better planet desc formatting
|
||||
- Procedural suns
|
||||
- 🌟 Back arrow -> reverse
|
||||
|
@ -16,7 +14,7 @@
|
|||
- 🌟 User-configurable outfit space types
|
||||
- 🌟 Sticky radar
|
||||
- Configurable radar
|
||||
- 🌟 Ship damage events, unify spawners
|
||||
- 🌟 Ship damage events
|
||||
- Better landing animation (slow down)
|
||||
- Land from farther away
|
||||
- Ship collapse: damage + force events
|
||||
|
@ -37,18 +35,15 @@
|
|||
- Correct drawing order (player on top, landing ships)
|
||||
- Faster handles (better than a hashmap?)
|
||||
- Check for handle leaks
|
||||
- 🌟 Log/warning system
|
||||
- Better physshiphandle
|
||||
- Clean up & faster frame timings (average)
|
||||
- 🌟 Handle lost focus
|
||||
- User config file
|
||||
- 🌟 Document content
|
||||
- 🌟 Clean up content: one ship per file, autodetect
|
||||
- CLI: content location, logs, etc
|
||||
- Better WGSL preprocessor?
|
||||
- Projectile performance
|
||||
- Starfield clusters, shader instead of an array?
|
||||
- CLI: specify dirs, content location, logs, etc
|
||||
- Starfield clusters, less flicker
|
||||
- Collider groups for factions? (projectile optimization)
|
||||
- Better error when sprite is missing from atlas
|
||||
|
||||
## 🌟 Player selection
|
||||
- Planet name, ring, and distance
|
||||
|
@ -115,12 +110,6 @@
|
|||
- Cache direcory
|
||||
- How to pack?
|
||||
|
||||
## Effect physics
|
||||
- Effect should stick to their ships. How?
|
||||
- Land and unland effects
|
||||
- Effect on fire gun
|
||||
- Effect / sprite color variation
|
||||
|
||||
## Sound effects
|
||||
- Sound effects
|
||||
- User-configurable music (?, game config or user config?)
|
||||
|
@ -176,6 +165,9 @@
|
|||
- Galaxy date system, slowly orbiting planets
|
||||
- Parallelize frame computations
|
||||
- Advanced AI: avoid collisions
|
||||
- Land and unland effects
|
||||
- Muzzle effect
|
||||
- Effect / sprite color variation
|
||||
|
||||
|
||||
## Game & Story
|
||||
|
@ -217,6 +209,7 @@
|
|||
- Outfits may not change unless you've landed. They might not change ever for CC ships!
|
||||
- All angle adjustments happen in content & shaders
|
||||
- Reserved texture: index zero
|
||||
- Errors: lowercase, no punctuation
|
||||
|
||||
|
||||
## Ideas
|
||||
|
|
|
@ -1,75 +1,71 @@
|
|||
[effect."small explosion"]
|
||||
sprite = "effect::explosion::small"
|
||||
lifetime = "inherit"
|
||||
inherit_velocity = "target"
|
||||
size = 8.0
|
||||
size_rng = 1.6
|
||||
angle_rng = 360
|
||||
velocity_scale_parent = 1.0
|
||||
fade = 0.2
|
||||
fade_rng = 0.1
|
||||
velocity.sticky = "parent"
|
||||
|
||||
|
||||
[effect."large explosion"]
|
||||
sprite = "effect::explosion::large"
|
||||
lifetime = "inherit"
|
||||
inherit_velocity = "target"
|
||||
size = 25.0
|
||||
size_rng = 5.0
|
||||
angle_rng = 360
|
||||
velocity_scale_parent = 1.0
|
||||
fade = 0.2
|
||||
fade_rng = 0.1
|
||||
velocity.sticky = "parent"
|
||||
|
||||
|
||||
[effect."huge explosion"]
|
||||
sprite = "effect::explosion::huge"
|
||||
lifetime = "inherit"
|
||||
inherit_velocity = "target"
|
||||
size = 50.0
|
||||
size_rng = 10.0
|
||||
angle_rng = 360
|
||||
velocity_scale_parent = 1.0
|
||||
fade = 0.2
|
||||
fade_rng = 0.1
|
||||
velocity.sticky = "parent"
|
||||
|
||||
|
||||
[effect."blue spark"]
|
||||
sprite = "effect::spark::blue"
|
||||
lifetime = 0.5
|
||||
lifetime_rng = 0.5
|
||||
inherit_velocity = "parent"
|
||||
size = 4.0
|
||||
size_rng = 2.0
|
||||
angle_rng = 360
|
||||
angvel_rng = 0.0
|
||||
velocity_scale_parent = 1.0
|
||||
fade = 0.2
|
||||
fade_rng = 0.1
|
||||
velocity.sticky = "parent"
|
||||
|
||||
|
||||
[effect."yellow spark"]
|
||||
sprite = "effect::spark::yellow"
|
||||
lifetime = "inherit"
|
||||
inherit_velocity = "parent"
|
||||
size = 4.0
|
||||
size_rng = 2.0
|
||||
angle_rng = 360
|
||||
angvel_rng = 0.0
|
||||
velocity_scale_parent = 1.0
|
||||
fade = 0.2
|
||||
fade_rng = 0.1
|
||||
velocity.sticky = "parent"
|
||||
|
||||
|
||||
[effect."red spark"]
|
||||
sprite = "effect::spark::red"
|
||||
lifetime = "inherit"
|
||||
inherit_velocity = "parent"
|
||||
size = 4.0
|
||||
size_rng = 1.0
|
||||
angle_rng = 360
|
||||
angvel_rng = 0.0
|
||||
velocity_scale_parent = 1.0
|
||||
fade = 0.2
|
||||
fade_rng = 0.1
|
||||
velocity.sticky = "parent"
|
||||
|
||||
|
||||
# Every effect has a parent, some effects have a target
|
||||
|
@ -90,12 +86,11 @@ angvel = 0.0 # Angular velocity at creation
|
|||
|
||||
|
||||
# Total velocity is sum of parent + target velocities with scale applied
|
||||
velocity_scale_parent = 0.0 # Multiply velocity by this value
|
||||
velocity_scale_parent_rng = 0.0 # random variation of scale
|
||||
velocity_scale_target = 1.0
|
||||
velocity_scale_target_rng = 1.0
|
||||
|
||||
direction_rng = 0.0 # Random variation of travel direction, in degrees, applied to velocity vector (/2 each side?)
|
||||
velocity.scale_parent = 0.0 # Multiply velocity by this value
|
||||
velocity.scale_parent_rng = 0.0 # random variation of scale
|
||||
velocity.scale_target = 1.0
|
||||
velocity.scale_target_rng = 1.0
|
||||
velocity.direction_rng = 0.0 # Random variation of travel direction, in degrees, applied to velocity vector (/2 each side?)
|
||||
|
||||
fade = 0.2
|
||||
fade_rng = 0.1
|
||||
|
|
|
@ -54,4 +54,4 @@ gun.projectile.impact_effect = "blaster impact"
|
|||
gun.projectile.expire_effect.sprite = "effect::blaster"
|
||||
gun.projectile.expire_effect.lifetime = "inherit"
|
||||
gun.projectile.expire_effect.size = 3.0
|
||||
gun.projectile.expire_effect.velocity_scale_parent = 1.0
|
||||
gun.projectile.expire_effect.velocity.scale_parent = 1.0
|
||||
|
|
|
@ -28,3 +28,4 @@ nalgebra = { workspace = true }
|
|||
image = { workspace = true }
|
||||
rapier2d = { workspace = true }
|
||||
lazy_static = { workspace = true }
|
||||
log = { workspace = true }
|
||||
|
|
|
@ -10,6 +10,7 @@ mod util;
|
|||
|
||||
use anyhow::{bail, Context, Result};
|
||||
use galactica_packer::{SpriteAtlas, SpriteAtlasImage};
|
||||
use log::warn;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs::File,
|
||||
|
@ -179,22 +180,22 @@ impl Content {
|
|||
match e.path().extension() {
|
||||
Some(t) => {
|
||||
if t.to_str() != Some("toml") {
|
||||
println!("[WARNING] {e:#?} is not a toml file, skipping.");
|
||||
warn!("{e:#?} is not a toml file, skipping");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
None => {
|
||||
println!("[WARNING] {e:#?} is not a toml file, skipping.");
|
||||
warn!("{e:#?} is not a toml file, skipping");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let path = e.path();
|
||||
let this_root = Self::try_parse(path)
|
||||
.with_context(|| format!("Could not read {}", path.display()))?;
|
||||
.with_context(|| format!("could not read {}", path.display()))?;
|
||||
|
||||
root.merge(this_root)
|
||||
.with_context(|| format!("Could not parse {}", path.display()))?;
|
||||
.with_context(|| format!("could not parse {}", path.display()))?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,13 +23,26 @@ pub(crate) mod syntax {
|
|||
pub angle_rng: Option<f32>,
|
||||
pub angvel: Option<f32>,
|
||||
pub angvel_rng: Option<f32>,
|
||||
pub velocity_scale_parent: Option<f32>,
|
||||
pub velocity_scale_parent_rng: Option<f32>,
|
||||
pub velocity_scale_target: Option<f32>,
|
||||
pub velocity_scale_target_rng: Option<f32>,
|
||||
pub direction_rng: Option<f32>,
|
||||
|
||||
pub fade: Option<f32>,
|
||||
pub fade_rng: Option<f32>,
|
||||
|
||||
pub velocity: EffectVelocity,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum EffectVelocity {
|
||||
Sticky {
|
||||
sticky: String,
|
||||
},
|
||||
Explicit {
|
||||
scale_parent: Option<f32>,
|
||||
scale_parent_rng: Option<f32>,
|
||||
scale_target: Option<f32>,
|
||||
scale_target_rng: Option<f32>,
|
||||
direction_rng: Option<f32>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
|
@ -69,12 +82,38 @@ pub(crate) mod syntax {
|
|||
}
|
||||
};
|
||||
|
||||
let velocity = match self.velocity {
|
||||
EffectVelocity::Explicit {
|
||||
scale_parent,
|
||||
scale_parent_rng,
|
||||
scale_target,
|
||||
scale_target_rng,
|
||||
direction_rng,
|
||||
} => super::EffectVelocity::Explicit {
|
||||
scale_parent: scale_parent.unwrap_or(0.0),
|
||||
scale_parent_rng: scale_parent_rng.unwrap_or(0.0),
|
||||
scale_target: scale_target.unwrap_or(0.0),
|
||||
scale_target_rng: scale_target_rng.unwrap_or(0.0),
|
||||
direction_rng: direction_rng.unwrap_or(0.0) / 2.0,
|
||||
},
|
||||
EffectVelocity::Sticky { sticky } => {
|
||||
if sticky == "parent" {
|
||||
super::EffectVelocity::StickyParent
|
||||
} else if sticky == "target" {
|
||||
super::EffectVelocity::StickyTarget
|
||||
} else {
|
||||
bail!("bad sticky specification `{}`", sticky);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let handle = EffectHandle {
|
||||
index: content.effects.len(),
|
||||
};
|
||||
content.effects.push(super::Effect {
|
||||
handle,
|
||||
sprite,
|
||||
velocity,
|
||||
size: self.size,
|
||||
size_rng: self.size_rng.unwrap_or(0.0),
|
||||
lifetime,
|
||||
|
@ -83,11 +122,6 @@ pub(crate) mod syntax {
|
|||
angle_rng: to_radians(self.angle_rng.unwrap_or(0.0) / 2.0),
|
||||
angvel: to_radians(self.angvel.unwrap_or(0.0)),
|
||||
angvel_rng: to_radians(self.angvel_rng.unwrap_or(0.0)),
|
||||
velocity_scale_parent: self.velocity_scale_parent.unwrap_or(0.0),
|
||||
velocity_scale_parent_rng: self.velocity_scale_parent_rng.unwrap_or(0.0),
|
||||
velocity_scale_target: self.velocity_scale_target.unwrap_or(0.0),
|
||||
velocity_scale_target_rng: self.velocity_scale_target_rng.unwrap_or(0.0),
|
||||
direction_rng: self.direction_rng.unwrap_or(0.0) / 2.0,
|
||||
fade: self.fade.unwrap_or(0.0),
|
||||
fade_rng: self.fade_rng.unwrap_or(0.0),
|
||||
});
|
||||
|
@ -157,27 +191,43 @@ pub struct Effect {
|
|||
/// Random angvel variation
|
||||
pub angvel_rng: f32,
|
||||
|
||||
/// The amount of this effect's parent's velocity to inherit
|
||||
pub velocity_scale_parent: f32,
|
||||
|
||||
/// Parent velocity random variation
|
||||
pub velocity_scale_parent_rng: f32,
|
||||
|
||||
/// The amount of this effect's parent's target velocity to inherit.
|
||||
/// If there is no target, this is zero.
|
||||
pub velocity_scale_target: f32,
|
||||
|
||||
/// Target velocity random variation
|
||||
pub velocity_scale_target_rng: f32,
|
||||
|
||||
/// Travel direction random variation
|
||||
pub direction_rng: f32,
|
||||
|
||||
/// Fade this effect out over this many seconds as it ends
|
||||
pub fade: f32,
|
||||
|
||||
/// Random fade ariation
|
||||
/// Random fade variation
|
||||
pub fade_rng: f32,
|
||||
|
||||
/// How to compute this effect's velocity
|
||||
pub velocity: EffectVelocity,
|
||||
}
|
||||
|
||||
/// How to compute an effect's velocity
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum EffectVelocity {
|
||||
/// Stick to parent
|
||||
StickyParent,
|
||||
|
||||
/// Stick to target.
|
||||
/// Zero velocity if no target is given.
|
||||
StickyTarget,
|
||||
|
||||
/// Compute velocity from parent and target
|
||||
Explicit {
|
||||
/// How much of the parent's velocity to inherit
|
||||
scale_parent: f32,
|
||||
|
||||
/// Random variation of scale_parent
|
||||
scale_parent_rng: f32,
|
||||
|
||||
/// How much of the target's velocity to keep
|
||||
scale_target: f32,
|
||||
|
||||
/// Random variation of scale_target
|
||||
scale_target_rng: f32,
|
||||
|
||||
/// Random variation of travel direction
|
||||
direction_rng: f32,
|
||||
},
|
||||
}
|
||||
|
||||
impl crate::Build for Effect {
|
||||
|
|
|
@ -10,7 +10,7 @@ pub(crate) mod sprite;
|
|||
pub(crate) mod system;
|
||||
|
||||
pub use config::Config;
|
||||
pub use effect::Effect;
|
||||
pub use effect::*;
|
||||
pub use faction::{Faction, Relationship};
|
||||
pub use outfit::{Gun, Outfit, Projectile, ProjectileCollider};
|
||||
pub use outfitspace::OutfitSpace;
|
||||
|
|
|
@ -160,7 +160,7 @@ fn resolve_coordinates(
|
|||
None => bail!("Could not resolve coordinate label `{l}`"),
|
||||
};
|
||||
Ok(resolve_position(&objects, &p, cycle_detector)
|
||||
.with_context(|| format!("In object {:#?}", l))?)
|
||||
.with_context(|| format!("in object {:#?}", l))?)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ impl crate::Build for System {
|
|||
objects.push(SystemObject {
|
||||
sprite: sprite_handle,
|
||||
pos: resolve_position(&system.object, &obj, cycle_detector)
|
||||
.with_context(|| format!("In object {:#?}", label))?,
|
||||
.with_context(|| format!("in object {:#?}", label))?,
|
||||
size: obj.size,
|
||||
angle: to_radians(obj.angle.unwrap_or(0.0)),
|
||||
handle: SystemObjectHandle {
|
||||
|
|
|
@ -37,3 +37,5 @@ nalgebra = { workspace = true }
|
|||
clap = { workspace = true }
|
||||
walkdir = { workspace = true }
|
||||
image = { workspace = true }
|
||||
log = { workspace = true }
|
||||
log4rs = { workspace = true }
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use anyhow::{bail, Context, Result};
|
||||
use galactica_packer::AtlasSet;
|
||||
use image::io::Reader;
|
||||
use log::warn;
|
||||
use std::path::Path;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
|
@ -22,21 +23,21 @@ pub fn run(asset_root: &Path, cache_target: &Path) -> Result<()> {
|
|||
match e.path().extension() {
|
||||
Some(t) => {
|
||||
if t.to_str() != Some("png") && t.to_str() != Some("jpg") {
|
||||
println!("[WARNING] {e:#?} is not a png file, skipping.");
|
||||
warn!("{e:#?} is not a png file, skipping");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
None => {
|
||||
println!("[WARNING] {e:#?} is not a png file, skipping.");
|
||||
warn!("{e:#?} is not a png file, skipping");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let path = e.path().to_path_buf();
|
||||
let reader = Reader::open(&path)
|
||||
.with_context(|| format!("While reading file `{}`", path.display()))?;
|
||||
.with_context(|| format!("while reading file `{}`", path.display()))?;
|
||||
let dim = reader.into_dimensions().with_context(|| {
|
||||
format!("While reading dimensions of file `{}`", path.display())
|
||||
format!("while reading dimensions of file `{}`", path.display())
|
||||
})?;
|
||||
files.push((path, [dim.0, dim.1]));
|
||||
total_dim += dim.0 as f64 * dim.1 as f64;
|
||||
|
@ -55,7 +56,7 @@ pub fn run(asset_root: &Path, cache_target: &Path) -> Result<()> {
|
|||
// Our tiling algorithm usually has efficiency better than 80% (~90%, as of writing)
|
||||
// We need room for error, though, since this check doesn't guarante success.
|
||||
if total_dim / 0.80 >= (8192.0 * 8192.0 * 16.0) {
|
||||
bail!("Texture atlas is too small")
|
||||
bail!("texture atlas is too small")
|
||||
}
|
||||
|
||||
// Create atlas set
|
||||
|
|
|
@ -64,6 +64,24 @@ impl<'a> Game {
|
|||
],
|
||||
);
|
||||
|
||||
let a = phys_sim.add_ship(
|
||||
&ct,
|
||||
ShipHandle { index: 0 },
|
||||
FactionHandle { index: 1 },
|
||||
ShipPersonality::Point,
|
||||
Point2::new(1000.0, 4000.0),
|
||||
);
|
||||
|
||||
let s = phys_sim.get_ship_mut(&a).unwrap();
|
||||
s.add_outfits(
|
||||
&ct,
|
||||
[
|
||||
OutfitHandle { index: 0 },
|
||||
OutfitHandle { index: 1 },
|
||||
OutfitHandle { index: 2 },
|
||||
],
|
||||
);
|
||||
|
||||
let a = phys_sim.add_ship(
|
||||
&ct,
|
||||
ShipHandle { index: 0 },
|
||||
|
|
|
@ -10,6 +10,13 @@ use galactica_system::{
|
|||
phys::{PhysImage, PhysSimShipHandle},
|
||||
};
|
||||
use galactica_util::constants::ASSET_CACHE;
|
||||
use log::LevelFilter;
|
||||
use log4rs::{
|
||||
append::console::ConsoleAppender,
|
||||
config::{Appender, Logger, Root},
|
||||
encode::pattern::PatternEncoder,
|
||||
Config,
|
||||
};
|
||||
use nalgebra::Vector2;
|
||||
use std::{
|
||||
fs,
|
||||
|
@ -35,9 +42,34 @@ struct Args {
|
|||
|
||||
mod cli;
|
||||
|
||||
fn set_up_logger(_args: &Args) -> log4rs::Handle {
|
||||
// h: highlight with level color
|
||||
// :<0.40 right align, min 0, max 40
|
||||
let stdout = ConsoleAppender::builder()
|
||||
.encoder(Box::new(PatternEncoder::new(
|
||||
"{d(%H:%M:%S)} | {({h({l})}):5.5} | \x1b[0;34m{M}\x1b[0m — {m:<0.50}{n}",
|
||||
)))
|
||||
.build();
|
||||
|
||||
let config = Config::builder()
|
||||
.appender(Appender::builder().build("stdout", Box::new(stdout)))
|
||||
.logger(Logger::builder().build("wgpu_core", LevelFilter::Warn))
|
||||
.logger(Logger::builder().build("wgpu_hal", LevelFilter::Warn))
|
||||
.logger(Logger::builder().build("naga", LevelFilter::Warn))
|
||||
.logger(Logger::builder().build("cosmic_text", LevelFilter::Warn))
|
||||
.logger(Logger::builder().build("winit", LevelFilter::Warn))
|
||||
.logger(Logger::builder().build("mio", LevelFilter::Warn))
|
||||
.build(Root::builder().appender("stdout").build(LevelFilter::Trace))
|
||||
.unwrap();
|
||||
|
||||
log4rs::init_config(config).unwrap()
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let args = Args::parse();
|
||||
|
||||
let _ = set_up_logger(&args);
|
||||
|
||||
let cache_dir = Path::new(ASSET_CACHE);
|
||||
fs::create_dir_all(cache_dir)?;
|
||||
|
||||
|
|
|
@ -85,9 +85,9 @@ impl AtlasSet {
|
|||
let mut f = File::open(&path)?;
|
||||
let mut bytes = Vec::new();
|
||||
f.read_to_end(&mut bytes)
|
||||
.with_context(|| format!("While reading file `{}`", path.display()))?;
|
||||
.with_context(|| format!("while reading file `{}`", path.display()))?;
|
||||
let img = image::load_from_memory(&bytes)
|
||||
.with_context(|| format!("While loading file `{}`", path.display()))?;
|
||||
.with_context(|| format!("while loading file `{}`", path.display()))?;
|
||||
|
||||
let image_dim = img.dimensions();
|
||||
|
||||
|
@ -102,7 +102,7 @@ impl AtlasSet {
|
|||
}
|
||||
}
|
||||
if transparent_border {
|
||||
println!("[WARNING] {} wastes space with a transmparent border",);
|
||||
warn!("{} wastes space with a transmparent border",);
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
|
@ -31,3 +31,4 @@ winit = { workspace = true }
|
|||
wgpu = { workspace = true }
|
||||
bytemuck = { workspace = true }
|
||||
glyphon = { workspace = true }
|
||||
log = { workspace = true }
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::globaluniform::GlobalUniform;
|
||||
|
||||
// TODO: build script?
|
||||
// TODO: better preprocessor, build script?
|
||||
// Not yet, this is ok for now.
|
||||
/// Basic wgsl preprocesser
|
||||
pub(crate) fn preprocess_shader(
|
||||
shader: &str,
|
||||
|
|
|
@ -5,6 +5,7 @@ use galactica_content::Content;
|
|||
use galactica_packer::SpriteAtlasImage;
|
||||
use galactica_util::constants::ASSET_CACHE;
|
||||
use image::GenericImageView;
|
||||
use log::info;
|
||||
use std::{fs::File, io::Read, num::NonZeroU32, path::Path};
|
||||
use wgpu::BindGroupLayout;
|
||||
|
||||
|
@ -93,7 +94,7 @@ impl TextureArray {
|
|||
let mut texture_data = Vec::new();
|
||||
|
||||
for file in ct.atlas_files() {
|
||||
println!("opening {file}");
|
||||
info!("opening {file}");
|
||||
let p = Path::new(ASSET_CACHE);
|
||||
let mut f = File::open(p.join(file))?;
|
||||
let mut bytes = Vec::new();
|
||||
|
@ -108,7 +109,7 @@ impl TextureArray {
|
|||
|
||||
let mut image_locations = AtlasArray::zeroed();
|
||||
|
||||
println!("sending to gpu");
|
||||
info!("sending to gpu");
|
||||
for image in ct.get_atlas().iter_images() {
|
||||
image_locations.data[image.idx.get() as usize] = AtlasImageLocation {
|
||||
xpos: image.x,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use galactica_content::{Content, EffectHandle, SpriteAutomaton};
|
||||
use nalgebra::{Rotation2, Vector2};
|
||||
use galactica_content::{Content, EffectHandle, EffectVelocity, SpriteAutomaton};
|
||||
use nalgebra::{Point2, Rotation2, Vector2};
|
||||
use rand::Rng;
|
||||
use rapier2d::dynamics::{RigidBodyBuilder, RigidBodyHandle, RigidBodyType};
|
||||
use rapier2d::dynamics::{RevoluteJointBuilder, RigidBodyBuilder, RigidBodyHandle, RigidBodyType};
|
||||
|
||||
use crate::phys::{PhysStepResources, PhysWrapper};
|
||||
|
||||
|
@ -35,25 +35,18 @@ impl PhysEffect {
|
|||
ct: &Content,
|
||||
wrapper: &mut PhysWrapper,
|
||||
effect: EffectHandle,
|
||||
// Where to spawn the particle, in world space.
|
||||
pos: Vector2<f32>,
|
||||
parent_angle: f32,
|
||||
parent_velocity: Vector2<f32>,
|
||||
target_velocity: Vector2<f32>,
|
||||
parent: RigidBodyHandle,
|
||||
target: Option<RigidBodyHandle>,
|
||||
) -> Self {
|
||||
let effect = ct.get_effect(effect);
|
||||
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
let velocity = {
|
||||
let a =
|
||||
rng.gen_range(-effect.velocity_scale_parent_rng..=effect.velocity_scale_parent_rng);
|
||||
let b =
|
||||
rng.gen_range(-effect.velocity_scale_target_rng..=effect.velocity_scale_target_rng);
|
||||
|
||||
let velocity = ((effect.velocity_scale_parent + a) * parent_velocity)
|
||||
+ ((effect.velocity_scale_target + b) * target_velocity);
|
||||
|
||||
Rotation2::new(rng.gen_range(-effect.direction_rng..=effect.direction_rng)) * velocity
|
||||
};
|
||||
let parent_body = wrapper.get_rigid_body(parent).unwrap();
|
||||
let parent_angle = parent_body.rotation().angle();
|
||||
let parent_pos = *parent_body.translation();
|
||||
let parent_velocity = parent_body.velocity_at_point(parent_body.center_of_mass());
|
||||
|
||||
let angvel = if effect.angvel_rng == 0.0 {
|
||||
effect.angvel
|
||||
|
@ -66,22 +59,112 @@ impl PhysEffect {
|
|||
parent_angle + effect.angle + rng.gen_range(-effect.angle_rng..=effect.angle_rng)
|
||||
};
|
||||
|
||||
let rb = RigidBodyBuilder::new(RigidBodyType::KinematicVelocityBased)
|
||||
.position(pos.into())
|
||||
.rotation(angle)
|
||||
.angvel(angvel)
|
||||
.linvel(velocity);
|
||||
let target_velocity = {
|
||||
if let Some(target) = target {
|
||||
let target_body = wrapper.get_rigid_body(target).unwrap();
|
||||
target_body.velocity_at_point(&Point2::new(pos.x, pos.y))
|
||||
} else {
|
||||
Vector2::new(0.0, 0.0)
|
||||
}
|
||||
};
|
||||
|
||||
PhysEffect {
|
||||
anim: SpriteAutomaton::new(ct, effect.sprite),
|
||||
rigid_body: wrapper.insert_rigid_body(rb.build()),
|
||||
lifetime: 0f32
|
||||
.max(effect.lifetime + rng.gen_range(-effect.lifetime_rng..=effect.lifetime_rng)),
|
||||
match effect.velocity {
|
||||
EffectVelocity::StickyTarget | EffectVelocity::StickyParent => {
|
||||
let rigid_body = wrapper.insert_rigid_body(
|
||||
RigidBodyBuilder::new(RigidBodyType::Dynamic)
|
||||
.additional_mass(f32::MIN_POSITIVE)
|
||||
.position(pos.into())
|
||||
.rotation(angle)
|
||||
.angvel(angvel)
|
||||
.build(),
|
||||
);
|
||||
|
||||
// Make sure size isn't negative. This check should be on EVERY rng!
|
||||
size: 0f32.max(effect.size + rng.gen_range(-effect.size_rng..=effect.size_rng)),
|
||||
fade: 0f32.max(effect.fade + rng.gen_range(-effect.fade_rng..=effect.fade_rng)),
|
||||
is_destroyed: false,
|
||||
match effect.velocity {
|
||||
EffectVelocity::StickyParent => {
|
||||
let d = Rotation2::new(-parent_angle) * (pos - parent_pos);
|
||||
|
||||
wrapper.add_joint(
|
||||
rigid_body,
|
||||
parent,
|
||||
RevoluteJointBuilder::new()
|
||||
.local_anchor1(Point2::new(0.0, 0.0))
|
||||
.local_anchor2(Point2::new(d.x, d.y)),
|
||||
)
|
||||
}
|
||||
EffectVelocity::StickyTarget => {
|
||||
if target.is_some() {
|
||||
let target_body = wrapper.get_rigid_body(target.unwrap()).unwrap();
|
||||
|
||||
// Correct for rotation, since joint coordinates are relative
|
||||
// and input coordinates are in world space.
|
||||
let d = Rotation2::new(-target_body.rotation().angle())
|
||||
* (pos - target_body.translation());
|
||||
|
||||
wrapper.add_joint(
|
||||
rigid_body,
|
||||
target.unwrap(),
|
||||
RevoluteJointBuilder::new()
|
||||
.local_anchor1(Point2::new(0.0, 0.0))
|
||||
.local_anchor2(Point2::new(d.x, d.y)),
|
||||
)
|
||||
}
|
||||
}
|
||||
_ => unreachable!("lol what?"),
|
||||
};
|
||||
|
||||
PhysEffect {
|
||||
anim: SpriteAutomaton::new(ct, effect.sprite),
|
||||
rigid_body,
|
||||
lifetime: 0f32.max(
|
||||
effect.lifetime + rng.gen_range(-effect.lifetime_rng..=effect.lifetime_rng),
|
||||
),
|
||||
|
||||
// Make sure size isn't negative. This check should be on EVERY rng!
|
||||
size: 0f32.max(effect.size + rng.gen_range(-effect.size_rng..=effect.size_rng)),
|
||||
fade: 0f32.max(effect.fade + rng.gen_range(-effect.fade_rng..=effect.fade_rng)),
|
||||
is_destroyed: false,
|
||||
}
|
||||
}
|
||||
|
||||
EffectVelocity::Explicit {
|
||||
scale_parent,
|
||||
scale_parent_rng,
|
||||
scale_target,
|
||||
scale_target_rng,
|
||||
direction_rng,
|
||||
} => {
|
||||
let velocity = {
|
||||
let a = rng.gen_range(-scale_parent_rng..=scale_parent_rng);
|
||||
let b = rng.gen_range(-scale_target_rng..=scale_target_rng);
|
||||
|
||||
let velocity = ((scale_parent + a) * parent_velocity)
|
||||
+ ((scale_target + b) * target_velocity);
|
||||
|
||||
Rotation2::new(rng.gen_range(-direction_rng..=direction_rng)) * velocity
|
||||
};
|
||||
|
||||
let rigid_body = wrapper.insert_rigid_body(
|
||||
RigidBodyBuilder::new(RigidBodyType::KinematicVelocityBased)
|
||||
.position(pos.into())
|
||||
.rotation(angle)
|
||||
.angvel(angvel)
|
||||
.linvel(velocity)
|
||||
.build(),
|
||||
);
|
||||
|
||||
PhysEffect {
|
||||
anim: SpriteAutomaton::new(ct, effect.sprite),
|
||||
rigid_body,
|
||||
lifetime: 0f32.max(
|
||||
effect.lifetime + rng.gen_range(-effect.lifetime_rng..=effect.lifetime_rng),
|
||||
),
|
||||
|
||||
// Make sure size isn't negative. This check should be on EVERY rng!
|
||||
size: 0f32.max(effect.size + rng.gen_range(-effect.size_rng..=effect.size_rng)),
|
||||
fade: 0f32.max(effect.fade + rng.gen_range(-effect.fade_rng..=effect.fade_rng)),
|
||||
is_destroyed: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use galactica_content::{AnimationState, Content, FactionHandle, Projectile, SpriteAutomaton};
|
||||
use nalgebra::Vector2;
|
||||
use rand::Rng;
|
||||
use rapier2d::{dynamics::RigidBodyHandle, geometry::ColliderHandle};
|
||||
|
||||
|
@ -97,35 +96,18 @@ impl PhysProjectile {
|
|||
return;
|
||||
}
|
||||
|
||||
let rigid_body = wrapper.remove_rigid_body(self.rigid_body).unwrap();
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
let rb = wrapper.get_rigid_body(self.rigid_body).unwrap();
|
||||
if expire {
|
||||
match &self.content.expire_effect {
|
||||
None => {}
|
||||
Some(handle) => {
|
||||
let x = res.ct.get_effect(*handle);
|
||||
let pos = *rigid_body.translation();
|
||||
let vel = rigid_body.velocity_at_point(rigid_body.center_of_mass());
|
||||
let angle = rigid_body.rotation().angle();
|
||||
|
||||
let velocity = {
|
||||
let a = rng
|
||||
.gen_range(-x.velocity_scale_parent_rng..=x.velocity_scale_parent_rng);
|
||||
|
||||
let velocity = (x.velocity_scale_parent + a) * vel;
|
||||
|
||||
velocity
|
||||
};
|
||||
|
||||
new.effects.push(PhysEffect::new(
|
||||
res.ct,
|
||||
wrapper,
|
||||
*handle,
|
||||
pos,
|
||||
angle,
|
||||
velocity,
|
||||
Vector2::new(0.0, 0.0),
|
||||
*rb.translation(),
|
||||
self.rigid_body,
|
||||
None,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,17 +88,13 @@ impl ShipCollapseSequence {
|
|||
};
|
||||
let pos = ship_pos + (ship_rot * pos);
|
||||
|
||||
let velocity =
|
||||
rigid_body.velocity_at_point(&Point2::new(pos.x, pos.y));
|
||||
|
||||
new.effects.push(PhysEffect::new(
|
||||
res.ct,
|
||||
wrapper,
|
||||
spawner.effect,
|
||||
pos,
|
||||
0.0,
|
||||
velocity,
|
||||
Vector2::new(0.0, 0.0),
|
||||
rigid_body_handle,
|
||||
None,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -133,16 +129,13 @@ impl ShipCollapseSequence {
|
|||
|
||||
// Position, adjusted for ship rotation
|
||||
let pos = ship_pos + (ship_rot * pos);
|
||||
let vel = rigid_body.velocity_at_point(&Point2::new(pos.x, pos.y));
|
||||
|
||||
new.effects.push(PhysEffect::new(
|
||||
res.ct,
|
||||
wrapper,
|
||||
spawner.effect,
|
||||
pos,
|
||||
0.0,
|
||||
vel,
|
||||
Vector2::new(0.0, 0.0),
|
||||
rigid_body_handle,
|
||||
None,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -453,16 +453,14 @@ impl PhysShip {
|
|||
};
|
||||
|
||||
let pos = ship_pos + (Rotation2::new(ship_ang) * pos);
|
||||
let velocity = rigid_body.velocity_at_point(&Point2::new(pos.x, pos.y));
|
||||
|
||||
new.effects.push(PhysEffect::new(
|
||||
res.ct,
|
||||
wrapper,
|
||||
e.effect,
|
||||
pos.into(),
|
||||
0.0,
|
||||
velocity,
|
||||
Vector2::new(0.0, 0.0),
|
||||
pos,
|
||||
self.rigid_body,
|
||||
None,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,25 +126,17 @@ impl PhysSim {
|
|||
// Borrow again, we can only have one at a time
|
||||
let pr = self.wrapper.get_rigid_body(projectile.rigid_body).unwrap();
|
||||
let pos = *pr.translation();
|
||||
let angle = pr.rotation().angle();
|
||||
|
||||
match &projectile.content.impact_effect {
|
||||
None => {}
|
||||
Some(x) => {
|
||||
let r = ship.rigid_body;
|
||||
let sr = self.wrapper.get_rigid_body(r).unwrap();
|
||||
let parent_velocity = pr.velocity_at_point(pr.center_of_mass());
|
||||
let target_velocity =
|
||||
sr.velocity_at_point(&nalgebra::Point2::new(pos.x, pos.y));
|
||||
|
||||
self.effects.push(PhysEffect::new(
|
||||
res.ct,
|
||||
&mut self.wrapper,
|
||||
*x,
|
||||
pos,
|
||||
angle,
|
||||
parent_velocity,
|
||||
target_velocity,
|
||||
projectile.rigid_body,
|
||||
Some(ship.rigid_body),
|
||||
));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crossbeam::channel::Receiver;
|
||||
use rapier2d::{
|
||||
dynamics::{
|
||||
CCDSolver, ImpulseJointSet, IntegrationParameters, IslandManager, MultibodyJointSet,
|
||||
RigidBody, RigidBodyHandle, RigidBodySet,
|
||||
CCDSolver, GenericJoint, ImpulseJointSet, IntegrationParameters, IslandManager,
|
||||
MultibodyJointSet, RigidBody, RigidBodyHandle, RigidBodySet,
|
||||
},
|
||||
geometry::{BroadPhase, Collider, ColliderHandle, ColliderSet, CollisionEvent, NarrowPhase},
|
||||
na::vector,
|
||||
|
@ -16,12 +16,12 @@ pub struct PhysWrapper {
|
|||
im: IslandManager,
|
||||
bp: BroadPhase,
|
||||
np: NarrowPhase,
|
||||
ij: ImpulseJointSet,
|
||||
mj: MultibodyJointSet,
|
||||
ccd: CCDSolver,
|
||||
|
||||
rigid_body_set: RigidBodySet,
|
||||
collider_set: ColliderSet,
|
||||
joint_set: ImpulseJointSet,
|
||||
|
||||
collision_handler: ChannelEventCollector,
|
||||
|
||||
|
@ -42,7 +42,6 @@ impl PhysWrapper {
|
|||
im: IslandManager::new(),
|
||||
bp: BroadPhase::new(),
|
||||
np: NarrowPhase::new(),
|
||||
ij: ImpulseJointSet::new(),
|
||||
mj: MultibodyJointSet::new(),
|
||||
ccd: CCDSolver::new(),
|
||||
collision_queue,
|
||||
|
@ -50,6 +49,7 @@ impl PhysWrapper {
|
|||
|
||||
rigid_body_set: RigidBodySet::new(),
|
||||
collider_set: ColliderSet::new(),
|
||||
joint_set: ImpulseJointSet::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ impl PhysWrapper {
|
|||
&mut self.np,
|
||||
&mut self.rigid_body_set,
|
||||
&mut self.collider_set,
|
||||
&mut self.ij,
|
||||
&mut self.joint_set,
|
||||
&mut self.mj,
|
||||
&mut self.ccd,
|
||||
None,
|
||||
|
@ -79,7 +79,7 @@ impl PhysWrapper {
|
|||
body,
|
||||
&mut self.im,
|
||||
&mut self.collider_set,
|
||||
&mut self.ij,
|
||||
&mut self.joint_set,
|
||||
&mut self.mj,
|
||||
true,
|
||||
);
|
||||
|
@ -121,4 +121,14 @@ impl PhysWrapper {
|
|||
self.collider_set
|
||||
.insert_with_parent(collider, parent_handle, &mut self.rigid_body_set)
|
||||
}
|
||||
|
||||
/// Add an impulse joint between two bodies
|
||||
pub fn add_joint(
|
||||
&mut self,
|
||||
body1: RigidBodyHandle,
|
||||
body2: RigidBodyHandle,
|
||||
joint: impl Into<GenericJoint>,
|
||||
) {
|
||||
self.joint_set.insert(body1, body2, joint, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ impl Timing {
|
|||
let f = self.physics_sim.as_secs_f32();
|
||||
s.push_str(&format!("Phys {:6.00} fps\n", 1.0 / f));
|
||||
s.push_str(&format!(
|
||||
"Step {:6.02}%\n",
|
||||
"Step {:5.02}%\n",
|
||||
100.0 * self.physics_step.as_secs_f32() / f
|
||||
));
|
||||
s.push_str(&format!(
|
||||
|
|
Loading…
Reference in New Issue