Compare commits
17 commits
master
...
automatic+
Author | SHA1 | Date | |
---|---|---|---|
|
5e68a19066 | ||
|
f372bc9914 | ||
|
1480baae70 | ||
|
3adf8cdc19 | ||
|
e5211c759a | ||
|
af681c8f15 | ||
|
ce265b89ca | ||
|
b3c5e03786 | ||
|
5f4cac9da9 | ||
|
e9ea58bf75 | ||
4d9035b663 | |||
8af090bcac | |||
8bda4f0d01 | |||
8ec70fa371 | |||
b93485bee1 | |||
ffeda38057 | |||
|
5d3c0e90fc |
46 changed files with 1379 additions and 1984 deletions
30
.zed/settings.json
Normal file
30
.zed/settings.json
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// Folder-specific settings
|
||||||
|
//
|
||||||
|
// For a full list of overridable settings, and general information on folder-specific settings,
|
||||||
|
// see the documentation: https://zed.dev/docs/configuring-zed#settings-files
|
||||||
|
{
|
||||||
|
"lsp": {
|
||||||
|
"rust-analyzer": {
|
||||||
|
"initialization_options": {
|
||||||
|
// get more cargo-less diagnostics from rust-analyzer,
|
||||||
|
// which might include false-positives (those can be turned off by their names)
|
||||||
|
"diagnostics": {
|
||||||
|
"experimental": {
|
||||||
|
"enable": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// To disable the checking entirely
|
||||||
|
// (ignores all cargo and check settings below)
|
||||||
|
"checkOnSave": false,
|
||||||
|
// To check the `lib` target only.
|
||||||
|
"cargo": {
|
||||||
|
"allTargets": false
|
||||||
|
},
|
||||||
|
// Use `-p` instead of `--workspace` for cargo check
|
||||||
|
"check": {
|
||||||
|
"workspace": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
127
Cargo.lock
generated
127
Cargo.lock
generated
|
@ -276,9 +276,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.24"
|
version = "1.2.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "16595d3be041c03b09d08d0858631facccee9221e579704070e6e9e4915d3bc7"
|
checksum = "32db95edf998450acc7881c932f94cd9b05c87b4b2599e8bab064753da4acfd1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jobserver",
|
"jobserver",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -902,9 +902,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper-util"
|
name = "hyper-util"
|
||||||
version = "0.1.12"
|
version = "0.1.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf9f1e950e0d9d1d3c47184416723cf29c0d1f93bd8cccf37e4beb6b44f31710"
|
checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
@ -965,9 +965,9 @@ checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "icu_properties"
|
name = "icu_properties"
|
||||||
version = "2.0.1"
|
version = "2.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b"
|
checksum = "2549ca8c7241c82f59c80ba2a6f415d931c5b58d24fb8412caa1a1f02c49139a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"displaydoc",
|
"displaydoc",
|
||||||
"icu_collections",
|
"icu_collections",
|
||||||
|
@ -981,9 +981,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "icu_properties_data"
|
name = "icu_properties_data"
|
||||||
version = "2.0.1"
|
version = "2.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632"
|
checksum = "8197e866e47b68f8f7d95249e172903bec06004b18b2937f1095d40a0c57de04"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "icu_provider"
|
name = "icu_provider"
|
||||||
|
@ -1118,26 +1118,6 @@ dependencies = [
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "liblzma"
|
|
||||||
version = "0.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "66352d7a8ac12d4877b6e6ea5a9b7650ee094257dc40889955bea5bc5b08c1d0"
|
|
||||||
dependencies = [
|
|
||||||
"liblzma-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "liblzma-sys"
|
|
||||||
version = "0.4.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5839bad90c3cc2e0b8c4ed8296b80e86040240f81d46b9c0e9bc8dd51ddd3af1"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
"libc",
|
|
||||||
"pkg-config",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libm"
|
name = "libm"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
|
@ -1227,6 +1207,27 @@ version = "0.4.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lzma-rs"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"crc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lzma-sys"
|
||||||
|
version = "0.1.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matchers"
|
name = "matchers"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -1294,13 +1295,13 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "1.0.4"
|
version = "1.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
|
checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1871,9 +1872,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.21"
|
version = "1.0.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
|
checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
|
@ -2072,9 +2073,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlx"
|
name = "sqlx"
|
||||||
version = "0.8.6"
|
version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc"
|
checksum = "f3c3a85280daca669cfd3bcb68a337882a8bc57ec882f72c5d13a430613a738e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"sqlx-core",
|
"sqlx-core",
|
||||||
"sqlx-macros",
|
"sqlx-macros",
|
||||||
|
@ -2085,9 +2086,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlx-core"
|
name = "sqlx-core"
|
||||||
version = "0.8.6"
|
version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6"
|
checksum = "f743f2a3cea30a58cd479013f75550e879009e3a02f616f18ca699335aa248c3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
@ -2121,9 +2122,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlx-macros"
|
name = "sqlx-macros"
|
||||||
version = "0.8.6"
|
version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d"
|
checksum = "7f4200e0fde19834956d4252347c12a083bdcb237d7a1a1446bffd8768417dce"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2134,9 +2135,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlx-macros-core"
|
name = "sqlx-macros-core"
|
||||||
version = "0.8.6"
|
version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b"
|
checksum = "882ceaa29cade31beca7129b6beeb05737f44f82dbe2a9806ecea5a7093d00b7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"either",
|
"either",
|
||||||
|
@ -2153,15 +2154,16 @@ dependencies = [
|
||||||
"sqlx-postgres",
|
"sqlx-postgres",
|
||||||
"sqlx-sqlite",
|
"sqlx-sqlite",
|
||||||
"syn",
|
"syn",
|
||||||
|
"tempfile",
|
||||||
"tokio",
|
"tokio",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlx-mysql"
|
name = "sqlx-mysql"
|
||||||
version = "0.8.6"
|
version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526"
|
checksum = "0afdd3aa7a629683c2d750c2df343025545087081ab5942593a5288855b1b7a7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atoi",
|
"atoi",
|
||||||
"base64",
|
"base64",
|
||||||
|
@ -2201,9 +2203,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlx-postgres"
|
name = "sqlx-postgres"
|
||||||
version = "0.8.6"
|
version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46"
|
checksum = "a0bedbe1bbb5e2615ef347a5e9d8cd7680fb63e77d9dafc0f29be15e53f1ebe6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atoi",
|
"atoi",
|
||||||
"base64",
|
"base64",
|
||||||
|
@ -2238,9 +2240,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlx-sqlite"
|
name = "sqlx-sqlite"
|
||||||
version = "0.8.6"
|
version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea"
|
checksum = "c26083e9a520e8eb87a06b12347679b142dc2ea29e6e409f805644a7a979a5bc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atoi",
|
"atoi",
|
||||||
"flume",
|
"flume",
|
||||||
|
@ -2420,9 +2422,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.45.1"
|
version = "1.45.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779"
|
checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
@ -2737,13 +2739,11 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "1.17.0"
|
version = "1.16.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d"
|
checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.3.3",
|
"getrandom 0.3.3",
|
||||||
"js-sys",
|
|
||||||
"wasm-bindgen",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2793,7 +2793,6 @@ checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustversion",
|
|
||||||
"wasm-bindgen-macro",
|
"wasm-bindgen-macro",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -3027,7 +3026,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wicked-waifus-protocol"
|
name = "wicked-waifus-protocol"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.xeondev.com/wickedwaifus/wicked-waifus-proto#316e3ee06f5ee0405e4cab567e67f4315c0f2cfb"
|
source = "git+https://git.xeondev.com/wickedwaifus/wicked-waifus-proto#6f2733c09b78a6e874f379254c9b71fbef23c3a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
|
@ -3045,7 +3044,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wicked-waifus-protocol-derive"
|
name = "wicked-waifus-protocol-derive"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.xeondev.com/wickedwaifus/wicked-waifus-proto#316e3ee06f5ee0405e4cab567e67f4315c0f2cfb"
|
source = "git+https://git.xeondev.com/wickedwaifus/wicked-waifus-proto#6f2733c09b78a6e874f379254c9b71fbef23c3a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -3281,6 +3280,15 @@ version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
|
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xz2"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2"
|
||||||
|
dependencies = [
|
||||||
|
"lzma-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yoke"
|
name = "yoke"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
@ -3428,9 +3436,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zip"
|
name = "zip"
|
||||||
version = "4.0.0"
|
version = "3.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "153a6fff49d264c4babdcfa6b4d534747f520e56e8f0f384f3b808c4b64cc1fd"
|
checksum = "12598812502ed0105f607f941c386f43d441e00148fce9dec3ca5ffb0bde9308"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"arbitrary",
|
"arbitrary",
|
||||||
|
@ -3442,11 +3450,12 @@ dependencies = [
|
||||||
"getrandom 0.3.3",
|
"getrandom 0.3.3",
|
||||||
"hmac",
|
"hmac",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"liblzma",
|
"lzma-rs",
|
||||||
"memchr",
|
"memchr",
|
||||||
"pbkdf2",
|
"pbkdf2",
|
||||||
"sha1",
|
"sha1",
|
||||||
"time",
|
"time",
|
||||||
|
"xz2",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
"zopfli",
|
"zopfli",
|
||||||
"zstd",
|
"zstd",
|
||||||
|
|
|
@ -55,7 +55,7 @@ wicked-waifus-network = { path = "wicked-waifus-network" }
|
||||||
wicked-waifus-protocol-internal = { path = "wicked-waifus-protocol-internal" }
|
wicked-waifus-protocol-internal = { path = "wicked-waifus-protocol-internal" }
|
||||||
wicked-waifus-protokey = { path = "wicked-waifus-protokey" }
|
wicked-waifus-protokey = { path = "wicked-waifus-protokey" }
|
||||||
|
|
||||||
wicked-waifus-protocol = { git = "https://git.xeondev.com/wickedwaifus/wicked-waifus-proto", features = ["debug"] }
|
wicked-waifus-protocol = { git = "https://git.xeondev.com/wickedwaifus/wicked-waifus-proto" }
|
||||||
wicked-waifus-protocol-derive = { git = "https://git.xeondev.com/wickedwaifus/wicked-waifus-proto" }
|
wicked-waifus-protocol-derive = { git = "https://git.xeondev.com/wickedwaifus/wicked-waifus-proto" }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
|
|
12
wicked-waifus-data/src/buff.rs
Normal file
12
wicked-waifus-data/src/buff.rs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))]
|
||||||
|
#[serde(rename_all = "PascalCase")]
|
||||||
|
pub struct BuffData {
|
||||||
|
pub id: i64,
|
||||||
|
pub ge_desc: String,
|
||||||
|
pub duration_policy: i32,
|
||||||
|
pub extra_effect_parameters: Option<Vec<String>>,
|
||||||
|
pub game_attribute_i_d: i32
|
||||||
|
}
|
|
@ -1,55 +0,0 @@
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))]
|
|
||||||
#[serde(rename_all = "PascalCase")]
|
|
||||||
pub struct FlySkinConfigData {
|
|
||||||
pub id: i32,
|
|
||||||
pub skin_type: i32,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub model_id: i32,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub stand_anim: String,
|
|
||||||
pub quality_id: i32,
|
|
||||||
pub skin_grade: i32,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub name: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub type_description: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub attributes_description: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub bg_description: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub icon: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub icon_middle: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub icon_small: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub mesh: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub obtained_show_description: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub show_in_bag: bool,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub item_access: Vec<i32>,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub sort_index: i32,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub red_dot_disable_rule: i32,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub preview_texture_in_buy_view: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub preview_texture_in_pay_shop: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub preview_texture_in_pop: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub skin_obtain_color1: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub skin_obtain_color2: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub skin_obtain_image: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub is_special_view_after_obtain: bool,
|
|
||||||
}
|
|
|
@ -125,7 +125,6 @@ json_data! {
|
||||||
FavorLevel;
|
FavorLevel;
|
||||||
FavorStory;
|
FavorStory;
|
||||||
FavorWord;
|
FavorWord;
|
||||||
FlySkinConfig;
|
|
||||||
ForgeFormula;
|
ForgeFormula;
|
||||||
FunctionCondition;
|
FunctionCondition;
|
||||||
Gacha;
|
Gacha;
|
||||||
|
@ -139,6 +138,7 @@ json_data! {
|
||||||
LevelPlayNodeData;
|
LevelPlayNodeData;
|
||||||
LivenessTask;
|
LivenessTask;
|
||||||
LordGym;
|
LordGym;
|
||||||
|
ModelConfigPreload;
|
||||||
MonsterDetection;
|
MonsterDetection;
|
||||||
MonsterPropertyGrowth;
|
MonsterPropertyGrowth;
|
||||||
Motion;
|
Motion;
|
||||||
|
@ -146,6 +146,7 @@ json_data! {
|
||||||
ResonanceAmplification;
|
ResonanceAmplification;
|
||||||
ResonantChain;
|
ResonantChain;
|
||||||
RoleBreach;
|
RoleBreach;
|
||||||
|
RoleExpItem;
|
||||||
RoleInfo;
|
RoleInfo;
|
||||||
RoleLevelConsume;
|
RoleLevelConsume;
|
||||||
RolePropertyGrowth;
|
RolePropertyGrowth;
|
||||||
|
@ -159,7 +160,6 @@ json_data! {
|
||||||
WeaponLevel;
|
WeaponLevel;
|
||||||
WeaponPropertyGrowth;
|
WeaponPropertyGrowth;
|
||||||
WeaponReson;
|
WeaponReson;
|
||||||
WeaponSkin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
json_hash_table_data! {
|
json_hash_table_data! {
|
||||||
|
@ -168,10 +168,10 @@ json_hash_table_data! {
|
||||||
BlueprintConfig, blueprint_type, String;
|
BlueprintConfig, blueprint_type, String;
|
||||||
DragonPool, id, i32;
|
DragonPool, id, i32;
|
||||||
DropPackage, id, i32;
|
DropPackage, id, i32;
|
||||||
RoleExpItem, id, i32;
|
|
||||||
TemplateConfig, blueprint_type, String;
|
TemplateConfig, blueprint_type, String;
|
||||||
|
SummonCfg, blueprint_type, String;
|
||||||
|
Buff, id, i64;
|
||||||
}
|
}
|
||||||
|
|
||||||
mod level_entity_config;
|
mod level_entity_config;
|
||||||
|
|
||||||
pub mod level_entity_config_data {
|
pub mod level_entity_config_data {
|
||||||
|
|
26
wicked-waifus-data/src/model_config_preload.rs
Normal file
26
wicked-waifus-data/src/model_config_preload.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))]
|
||||||
|
#[serde(rename_all = "PascalCase")]
|
||||||
|
pub struct ModelConfigPreloadData {
|
||||||
|
pub id: i32,
|
||||||
|
pub actor_class_path: String,
|
||||||
|
#[cfg(feature = "strict_json_fields")]
|
||||||
|
pub actor_class: Vec<String>,
|
||||||
|
#[cfg(feature = "strict_json_fields")]
|
||||||
|
pub animations: Vec<String>,
|
||||||
|
#[cfg(feature = "strict_json_fields")]
|
||||||
|
pub effects: Vec<String>,
|
||||||
|
#[cfg(feature = "strict_json_fields")]
|
||||||
|
pub audios: Vec<String>,
|
||||||
|
#[cfg(feature = "strict_json_fields")]
|
||||||
|
pub meshes: Vec<String>,
|
||||||
|
#[cfg(feature = "strict_json_fields")]
|
||||||
|
pub materials: Vec<String>,
|
||||||
|
#[cfg(feature = "strict_json_fields")]
|
||||||
|
pub animation_blueprints: Vec<String>,
|
||||||
|
#[cfg(feature = "strict_json_fields")]
|
||||||
|
pub others: Vec<String>,
|
||||||
|
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ pub mod reward;
|
||||||
pub mod teleport;
|
pub mod teleport;
|
||||||
pub mod timer;
|
pub mod timer;
|
||||||
pub mod var;
|
pub mod var;
|
||||||
|
pub mod model;
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))]
|
#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))]
|
||||||
|
@ -28,6 +29,7 @@ pub struct ComponentsData {
|
||||||
pub interact_component: Option<interact::InteractComponent>,
|
pub interact_component: Option<interact::InteractComponent>,
|
||||||
pub entity_state_component: Option<entity_state::EntityStateComponent>,
|
pub entity_state_component: Option<entity_state::EntityStateComponent>,
|
||||||
pub reward_component: Option<reward::RewardComponent>,
|
pub reward_component: Option<reward::RewardComponent>,
|
||||||
|
pub model_component: Option<model::ModelComponent>,
|
||||||
// TODO: Implement this ones
|
// TODO: Implement this ones
|
||||||
#[cfg(feature = "strict_json_fields")]
|
#[cfg(feature = "strict_json_fields")]
|
||||||
pub scene_actor_ref_component: Option<serde_json::Value>,
|
pub scene_actor_ref_component: Option<serde_json::Value>,
|
||||||
|
@ -70,8 +72,6 @@ pub struct ComponentsData {
|
||||||
#[cfg(feature = "strict_json_fields")]
|
#[cfg(feature = "strict_json_fields")]
|
||||||
pub photo_target_component: Option<serde_json::Value>,
|
pub photo_target_component: Option<serde_json::Value>,
|
||||||
#[cfg(feature = "strict_json_fields")]
|
#[cfg(feature = "strict_json_fields")]
|
||||||
pub model_component: Option<serde_json::Value>,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub entity_group_component: Option<serde_json::Value>,
|
pub entity_group_component: Option<serde_json::Value>,
|
||||||
#[cfg(feature = "strict_json_fields")]
|
#[cfg(feature = "strict_json_fields")]
|
||||||
pub scene_item_life_cycle_component: Option<serde_json::Value>,
|
pub scene_item_life_cycle_component: Option<serde_json::Value>,
|
||||||
|
@ -230,6 +230,7 @@ impl ComponentsData {
|
||||||
interact_component: self.interact_component.as_ref().or(template.interact_component.as_ref()).cloned(),
|
interact_component: self.interact_component.as_ref().or(template.interact_component.as_ref()).cloned(),
|
||||||
entity_state_component: self.entity_state_component.as_ref().or(template.entity_state_component.as_ref()).cloned(),
|
entity_state_component: self.entity_state_component.as_ref().or(template.entity_state_component.as_ref()).cloned(),
|
||||||
reward_component: self.reward_component.as_ref().or(template.reward_component.as_ref()).cloned(),
|
reward_component: self.reward_component.as_ref().or(template.reward_component.as_ref()).cloned(),
|
||||||
|
model_component: self.model_component.as_ref().or(template.model_component.as_ref()).cloned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
18
wicked-waifus-data/src/pb_components/model.rs
Normal file
18
wicked-waifus-data/src/pb_components/model.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
|
#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))]
|
||||||
|
#[serde(rename_all = "PascalCase")]
|
||||||
|
pub struct ModelType {
|
||||||
|
pub r#type: Option<String>,
|
||||||
|
pub model_id: Option<i32>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
|
#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))]
|
||||||
|
#[serde(rename_all = "PascalCase")]
|
||||||
|
pub struct ModelComponent {
|
||||||
|
pub half_height: Option<i32>,
|
||||||
|
pub disabled: Option<bool>,
|
||||||
|
pub model_type: Option<ModelType>
|
||||||
|
}
|
|
@ -100,7 +100,6 @@ pub struct RoleInfoData {
|
||||||
pub role_guide: i32,
|
pub role_guide: i32,
|
||||||
#[cfg(feature = "strict_json_fields")]
|
#[cfg(feature = "strict_json_fields")]
|
||||||
pub red_dot_disable_rule: i32,
|
pub red_dot_disable_rule: i32,
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub skin_damage: Vec<String>,
|
pub skin_damage: Vec<String>,
|
||||||
#[cfg(feature = "strict_json_fields")]
|
#[cfg(feature = "strict_json_fields")]
|
||||||
pub hide_hu_lu: bool,
|
pub hide_hu_lu: bool,
|
||||||
|
|
12
wicked-waifus-data/src/summon_cfg.rs
Normal file
12
wicked-waifus-data/src/summon_cfg.rs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))]
|
||||||
|
#[serde(rename_all = "PascalCase")]
|
||||||
|
pub struct SummonCfgData {
|
||||||
|
pub id: i32,
|
||||||
|
pub blueprint_type: String,
|
||||||
|
#[cfg(feature = "strict_json_fields")]
|
||||||
|
pub name: String,
|
||||||
|
pub born_buff_id: Vec<i64>,
|
||||||
|
}
|
|
@ -1,54 +0,0 @@
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))]
|
|
||||||
#[serde(rename_all = "PascalCase")]
|
|
||||||
pub struct WeaponSkinData {
|
|
||||||
pub id: i32,
|
|
||||||
pub weapon_skin_type: i32,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub name: String,
|
|
||||||
pub hide_in_skin_view: bool,
|
|
||||||
pub quality_id: i32,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub model_id: i32,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub transform_id: i32,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub models: Vec<i32>,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub type_description: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub attributes_description: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub bg_description: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub card_icon_path: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub icon: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub icon_middle: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub icon_small: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
#[serde(rename = "MaxCapcity")] // kuro!
|
|
||||||
pub max_capacity: i32,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub item_access: Vec<i32>,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub obtained_show: i32,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub obtained_show_description: String,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub num_limit: i32,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub show_in_bag: bool,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub sort_index: i32,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub hidden_time: i32,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub destructible: bool,
|
|
||||||
#[cfg(feature = "strict_json_fields")]
|
|
||||||
pub red_dot_disable_rule: i32,
|
|
||||||
}
|
|
|
@ -19,7 +19,7 @@ load_textmaps = true
|
||||||
quadrant_size = 1000000
|
quadrant_size = 1000000
|
||||||
|
|
||||||
[asset_config]
|
[asset_config]
|
||||||
asset_url = "https://git.xeondev.com/wickedwaifus/wicked-waifus-data/releases/download/pioneer_2.4.4/bundle.zip"
|
asset_url = "https://git.xeondev.com/wickedwaifus/wicked-waifus-data/releases/download/pioneer_2.4.1/bundle.zip"
|
||||||
buffer_size = 268435456
|
buffer_size = 268435456
|
||||||
|
|
||||||
[default_unlocks]
|
[default_unlocks]
|
||||||
|
@ -28,15 +28,8 @@ unlock_all_roles_max_level = false
|
||||||
unlock_all_roles_all_sequences = false
|
unlock_all_roles_all_sequences = false
|
||||||
unlock_all_mc_elements = true
|
unlock_all_mc_elements = true
|
||||||
unlock_all_weapons = false
|
unlock_all_weapons = false
|
||||||
unlock_all_weapons_max_level = false
|
|
||||||
unlock_all_weapons_all_reson = false
|
|
||||||
unlock_all_adventures = false
|
unlock_all_adventures = false
|
||||||
unlock_all_functions = true
|
unlock_all_functions = true
|
||||||
unlock_all_guides = false
|
unlock_all_guides = false
|
||||||
unlock_all_tutorials = false
|
unlock_all_tutorials = false
|
||||||
unlock_all_teleporter = false
|
unlock_all_teleporter = false
|
||||||
unlock_all_role_skins = false
|
|
||||||
# TODO: Set this to the same value as unlock_all_role_skins, without it, it fails(maybe jinshi weapon skin problem??)
|
|
||||||
unlock_all_weapon_skins = false
|
|
||||||
unlock_all_fly_skins = false
|
|
||||||
unlock_all_wing_skins = false
|
|
|
@ -1 +0,0 @@
|
||||||
require('../Module/WaterMask/WaterMaskController').WaterMaskView.EOo();
|
|
41
wicked-waifus-game-server/scripts/watermask-edit.js
Normal file
41
wicked-waifus-game-server/scripts/watermask-edit.js
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
const UE = require("ue"),
|
||||||
|
Info_1 = require("../../../Core/Common/Info"),
|
||||||
|
MathUtils_1 = require("../../../Core/Utils/MathUtils"),
|
||||||
|
EventDefine_1 = require("../../Common/Event/EventDefine"),
|
||||||
|
EventSystem_1 = require("../../Common/Event/EventSystem"),
|
||||||
|
UiControllerBase_1 = require("../../Ui/Base/UiControllerBase"),
|
||||||
|
UiLayerType_1 = require("../../Ui/Define/UiLayerType"),
|
||||||
|
UiLayer_1 = require("../../Ui/UiLayer");
|
||||||
|
|
||||||
|
var _a = require('../Module/WaterMask/WaterMaskController').WaterMaskView;
|
||||||
|
_a.LOo = 0.18;
|
||||||
|
_a.yOo = 700;
|
||||||
|
_a.IOo = 700;
|
||||||
|
_a.vOo = function () {
|
||||||
|
void 0 !== _a.SOo && _a.EOo();
|
||||||
|
var e = UiLayer_1.UiLayer.GetLayerRootUiItem(UiLayerType_1.ELayerType.WaterMask),
|
||||||
|
t = (_a.SOo = UE.KuroActorManager.SpawnActor(Info_1.Info.World, UE.UIContainerActor.StaticClass(),
|
||||||
|
MathUtils_1.MathUtils.DefaultTransform, void 0), _a.SOo.RootComponent),
|
||||||
|
e = (t.SetDisplayName("WaterMaskContainer"), UE.KuroStaticLibrary.SetActorPermanent(_a.SOo, !0, !0), _a.SOo
|
||||||
|
.K2_AttachRootComponentTo(e), t.GetRootCanvas().GetOwner().RootComponent),
|
||||||
|
i = e.widget.width % _a.yOo / 2,
|
||||||
|
r = e.widget.height % _a.IOo / 2,
|
||||||
|
n = e.widget.width / 2,
|
||||||
|
_ = e.widget.height / 2,
|
||||||
|
s = Math.ceil(e.widget.width / _a.yOo),
|
||||||
|
o = Math.ceil(e.widget.height / _a.IOo),
|
||||||
|
v = " "; // EDIT ME!
|
||||||
|
for (let a = 0; a < s; a++)
|
||||||
|
for (let e = 0; e < o; e++) {
|
||||||
|
var E = UE.KuroActorManager.SpawnActor(Info_1.Info.World, UE.UITextActor.StaticClass(), MathUtils_1
|
||||||
|
.MathUtils.DefaultTransform, void 0),
|
||||||
|
U = E.RootComponent,
|
||||||
|
U = (E.K2_AttachRootComponentTo(t), U.SetDisplayName("WaterMaskText"), E.GetComponentByClass(UE
|
||||||
|
.UIText.StaticClass()));
|
||||||
|
U.SetFontSize(_a.vFt), U.SetOverflowType(0), U.SetAlpha(_a.LOo), U.SetFont(UE.LGUIFontData
|
||||||
|
.GetDefaultFont()), U.SetText(v), U.SetUIRelativeLocation(new UE.Vector(a * _a.yOo - n + i, e *
|
||||||
|
_a.IOo - _ + r, 0)), U.SetUIRelativeRotation(new UE.Rotator(0, _a.TOo, 0)), UE.KuroStaticLibrary
|
||||||
|
.SetActorPermanent(E, !0, !0)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
_a.vOo();
|
|
@ -37,18 +37,12 @@ pub struct DefaultUnlocks {
|
||||||
pub unlock_all_roles_max_level: bool,
|
pub unlock_all_roles_max_level: bool,
|
||||||
pub unlock_all_roles_all_sequences: bool,
|
pub unlock_all_roles_all_sequences: bool,
|
||||||
pub unlock_all_mc_elements: bool,
|
pub unlock_all_mc_elements: bool,
|
||||||
pub unlock_all_weapons: bool,
|
pub unlock_all_weapons: bool, // TODO:
|
||||||
pub unlock_all_weapons_max_level: bool,
|
|
||||||
pub unlock_all_weapons_all_reson: bool,
|
|
||||||
pub unlock_all_adventures: bool,
|
pub unlock_all_adventures: bool,
|
||||||
pub unlock_all_functions: bool,
|
pub unlock_all_functions: bool,
|
||||||
pub unlock_all_guides: bool,
|
pub unlock_all_guides: bool,
|
||||||
pub unlock_all_tutorials: bool,
|
pub unlock_all_tutorials: bool,
|
||||||
pub unlock_all_teleporter: bool,
|
pub unlock_all_teleporter: bool,
|
||||||
pub unlock_all_role_skins: bool,
|
|
||||||
pub unlock_all_weapon_skins: bool,
|
|
||||||
pub unlock_all_fly_skins: bool,
|
|
||||||
pub unlock_all_wing_skins: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TomlConfig for ServiceConfig {
|
impl TomlConfig for ServiceConfig {
|
||||||
|
|
|
@ -19,7 +19,6 @@ mod summoner;
|
||||||
mod tag;
|
mod tag;
|
||||||
mod visibility;
|
mod visibility;
|
||||||
mod vision_skill;
|
mod vision_skill;
|
||||||
mod weapon_skin;
|
|
||||||
|
|
||||||
pub use attribute::Attribute;
|
pub use attribute::Attribute;
|
||||||
pub use autonomous::Autonomous;
|
pub use autonomous::Autonomous;
|
||||||
|
@ -42,4 +41,3 @@ pub use summoner::Summoner;
|
||||||
pub use tag::Tag;
|
pub use tag::Tag;
|
||||||
pub use visibility::Visibility;
|
pub use visibility::Visibility;
|
||||||
pub use vision_skill::VisionSkill;
|
pub use vision_skill::VisionSkill;
|
||||||
pub use weapon_skin::WeaponSkin;
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
use wicked_waifus_protocol::entity_component_pb::ComponentPb;
|
|
||||||
use wicked_waifus_protocol::{EntityComponentPb, WeaponSkinComponentPb};
|
|
||||||
use crate::logic::ecs::component::Component;
|
|
||||||
|
|
||||||
pub struct WeaponSkin {
|
|
||||||
pub skin_id: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Component for WeaponSkin {
|
|
||||||
fn set_pb_data(&self, pb: &mut wicked_waifus_protocol::EntityPb) {
|
|
||||||
pb.component_pbs.push(EntityComponentPb {
|
|
||||||
component_pb: Some(ComponentPb::WeaponSkinComponentPb(WeaponSkinComponentPb {
|
|
||||||
weapon_skin_id: self.skin_id,
|
|
||||||
})),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,8 +8,7 @@ pub struct BufManager {
|
||||||
recycled_handles: HashMap<i32, VecDeque<i32>>,
|
recycled_handles: HashMap<i32, VecDeque<i32>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BufManager {
|
const OVERRIDE_BUFFS: &[i64] = &[
|
||||||
const PERMANENT_ROLE_BUFFS: &'static [i64] = &[
|
|
||||||
3003, // Remove wall run prohibition
|
3003, // Remove wall run prohibition
|
||||||
3004, // Remove gliding prohibition
|
3004, // Remove gliding prohibition
|
||||||
1213, // Reduce stamina while flying
|
1213, // Reduce stamina while flying
|
||||||
|
@ -17,8 +16,26 @@ impl BufManager {
|
||||||
1215, // Reduce stamina while flying up in sprint
|
1215, // Reduce stamina while flying up in sprint
|
||||||
1216, // Reduce stamina while flying down in sprint
|
1216, // Reduce stamina while flying down in sprint
|
||||||
640012051, // Allow flying -> tag: 1151923109
|
640012051, // Allow flying -> tag: 1151923109
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const ROLE_OVERRIDES: &[(i32, &[i64])] = &[
|
||||||
|
(1407, &[
|
||||||
|
// ciaconna's forte buffs are completely fucked to get from an algorithm and i hate kuro!
|
||||||
|
1407900003,
|
||||||
|
1407500040,
|
||||||
|
]),
|
||||||
|
];
|
||||||
|
|
||||||
|
fn get_role_buff_overrides(role_id: i32) -> Option<&'static [i64]> {
|
||||||
|
for &(role, buff) in ROLE_OVERRIDES {
|
||||||
|
if role == role_id {
|
||||||
|
return Some(buff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BufManager {
|
||||||
pub fn create(&mut self, buf: &mut FightBuffInformation) {
|
pub fn create(&mut self, buf: &mut FightBuffInformation) {
|
||||||
let handle = self
|
let handle = self
|
||||||
.recycled_handles
|
.recycled_handles
|
||||||
|
@ -35,7 +52,9 @@ impl BufManager {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn remove_entity_buffs(&mut self, entity_id: i64) {
|
pub fn remove_entity_buffs(&mut self, entity_id: i64) {
|
||||||
let handles = self.active_buf_set.iter()
|
let handles = self
|
||||||
|
.active_buf_set
|
||||||
|
.iter()
|
||||||
.filter(|(_, buff)| buff.entity_id == entity_id)
|
.filter(|(_, buff)| buff.entity_id == entity_id)
|
||||||
.map(|(&handle, _)| handle)
|
.map(|(&handle, _)| handle)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
@ -57,13 +76,33 @@ impl BufManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_permanent_buffs(&mut self, origin_id: i64) -> Vec<FightBuffInformation> {
|
pub fn create_permanent_buffs(&mut self, origin_id: i64, role_id: i32) -> Vec<FightBuffInformation> {
|
||||||
Self::PERMANENT_ROLE_BUFFS
|
let mut buffs = wicked_waifus_data::buff_data::iter().filter(|(id, buf)| {
|
||||||
|
id.to_string().starts_with(&role_id.to_string()) // must be part of char kit :)
|
||||||
|
&&
|
||||||
|
!id.to_string().contains("666")// KURO IS EVIL
|
||||||
|
&&
|
||||||
|
buf.duration_policy == 1
|
||||||
|
&&
|
||||||
|
!buf.ge_desc.contains("【废弃】") // remove "deprecated" buffs
|
||||||
|
})
|
||||||
|
.map(|x| *x.0)
|
||||||
|
.collect::<Vec<i64>>();
|
||||||
|
|
||||||
|
tracing::debug!("adding roleid {:#?}", buffs);
|
||||||
|
|
||||||
|
buffs.extend(OVERRIDE_BUFFS.iter().copied());
|
||||||
|
if let Some(role_buff_overrides) = get_role_buff_overrides(role_id) {
|
||||||
|
buffs.extend(role_buff_overrides.iter().copied());
|
||||||
|
}
|
||||||
|
buffs.dedup();
|
||||||
|
|
||||||
|
buffs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&id| {
|
.map(|id| {
|
||||||
let mut buff = FightBuffInformation {
|
let mut buff = FightBuffInformation {
|
||||||
handle_id: 0,
|
handle_id: 0,
|
||||||
buff_id: id,
|
buff_id: *id,
|
||||||
level: 1,
|
level: 1,
|
||||||
stack_count: 1,
|
stack_count: 1,
|
||||||
instigator_id: origin_id,
|
instigator_id: origin_id,
|
||||||
|
@ -81,6 +120,26 @@ impl BufManager {
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_buff(&mut self, origin_id: i64, buff_id: i64) -> FightBuffInformation {
|
||||||
|
let mut buff = FightBuffInformation {
|
||||||
|
handle_id: 0,
|
||||||
|
buff_id,
|
||||||
|
level: 1,
|
||||||
|
stack_count: 1,
|
||||||
|
instigator_id: origin_id,
|
||||||
|
entity_id: origin_id,
|
||||||
|
apply_type: 0,
|
||||||
|
duration: -1f32,
|
||||||
|
left_duration: -1f32,
|
||||||
|
context: vec![],
|
||||||
|
is_active: true,
|
||||||
|
server_id: 0,
|
||||||
|
message_id: 0,
|
||||||
|
};
|
||||||
|
self.create(&mut buff);
|
||||||
|
buff
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for BufManager {
|
impl Default for BufManager {
|
||||||
|
|
|
@ -44,7 +44,6 @@ impl_component_container! {
|
||||||
Summoner;
|
Summoner;
|
||||||
SoarWingSkin;
|
SoarWingSkin;
|
||||||
ParaglidingSkin;
|
ParaglidingSkin;
|
||||||
WeaponSkin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Component {
|
pub trait Component {
|
||||||
|
|
|
@ -7,6 +7,7 @@ use std::collections::hash_map::{Keys, Values};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use wicked_waifus_protocol::FightBuffInformation;
|
use wicked_waifus_protocol::FightBuffInformation;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
pub struct WorldEntity {
|
pub struct WorldEntity {
|
||||||
components: HashMap<i32, Vec<RefCell<ComponentContainer>>>,
|
components: HashMap<i32, Vec<RefCell<ComponentContainer>>>,
|
||||||
entity_manager: EntityManager,
|
entity_manager: EntityManager,
|
||||||
|
@ -107,21 +108,15 @@ impl WorldEntity {
|
||||||
self.components.remove(&entity_id).is_some() && self.entity_manager.remove(entity_id)
|
self.components.remove(&entity_id).is_some() && self.entity_manager.remove(entity_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn active_entity_empty(&self) -> bool {
|
pub fn get_all_entity_ids(&mut self) -> Vec<i32> {
|
||||||
self.entity_manager.active_entity_empty()
|
self.entity_manager.get_all_entity_id()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_role_permanent_buffs(&mut self, entity_id: i64) -> Vec<FightBuffInformation> {
|
pub fn generate_role_permanent_buffs(&mut self, entity_id: i32, role_id: i32) -> Vec<FightBuffInformation> {
|
||||||
self.buff_manager.create_permanent_buffs(entity_id)
|
self.buff_manager.create_permanent_buffs(entity_id as i64, role_id)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for WorldEntity {
|
pub fn create_buff(&mut self, entity_id: i32, buff_id: i64) -> FightBuffInformation {
|
||||||
fn default() -> Self {
|
self.buff_manager.create_buff(entity_id as i64, buff_id)
|
||||||
Self {
|
|
||||||
components: HashMap::new(),
|
|
||||||
entity_manager: EntityManager::default(),
|
|
||||||
buff_manager: BufManager::default(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,13 +113,7 @@ impl GachaPool {
|
||||||
match player.role_list.get(&item_id) {
|
match player.role_list.get(&item_id) {
|
||||||
None => {
|
None => {
|
||||||
if required_role_ids.contains(&item_id) {
|
if required_role_ids.contains(&item_id) {
|
||||||
let role = Role::new(item_id);
|
player.role_list.insert(item_id, Role::new(item_id));
|
||||||
let role_id = role.role_id;
|
|
||||||
let weapon_id = role.equip_weapon;
|
|
||||||
player.role_list.insert(item_id, role);
|
|
||||||
// TODO notifies player update
|
|
||||||
player.inventory.add_weapon(role_id, 0, 1, 0, 0, 0, weapon_id).unwrap();
|
|
||||||
// TODO notifies weapon update
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(role) => {
|
Some(role) => {
|
||||||
|
|
255
wicked-waifus-game-server/src/logic/handler/action.rs
Normal file
255
wicked-waifus-game-server/src/logic/handler/action.rs
Normal file
|
@ -0,0 +1,255 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use wicked_waifus_protocol::{
|
||||||
|
CommonTagData, EntityCommonTagNotify, EntityStateReadyNotify, FightBuffInformation, ItemRewardNotify, NormalItemUpdateNotify, RewardItemInfo, WR
|
||||||
|
};
|
||||||
|
|
||||||
|
use wicked_waifus_data::pb_components::action::{
|
||||||
|
AddBuffToEntity, AddBuffToPlayer, ChangeSelfEntityState, CollectParams, RemoveBuffFromEntity, RemoveBuffFromPlayer, UnlockTeleportTrigger
|
||||||
|
};
|
||||||
|
use wicked_waifus_data::pb_components::entity_state::EntityStateComponent;
|
||||||
|
|
||||||
|
use crate::logic::ecs::component::ComponentContainer;
|
||||||
|
use crate::logic::ecs::world::WorldEntity;
|
||||||
|
use crate::logic::handler::handle_action;
|
||||||
|
use crate::logic::player::{ItemUsage, Player};
|
||||||
|
use crate::logic::utils::tag_utils;
|
||||||
|
use crate::query_components;
|
||||||
|
|
||||||
|
pub fn collect_action(
|
||||||
|
player: &mut Player,
|
||||||
|
_entity_id: i64,
|
||||||
|
level_entity_data: &wicked_waifus_data::LevelEntityConfigData,
|
||||||
|
template_config: &wicked_waifus_data::TemplateConfigData,
|
||||||
|
_: CollectParams
|
||||||
|
) {
|
||||||
|
if let Some(reward_component) = level_entity_data
|
||||||
|
.components_data
|
||||||
|
.reward_component
|
||||||
|
.as_ref()
|
||||||
|
.or(template_config.components_data.reward_component.as_ref())
|
||||||
|
{
|
||||||
|
if reward_component.disabled.unwrap_or(false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// TODO: check the use of reward_type and drop_on_event
|
||||||
|
// Seems type 0 is reward from preview, while 1 and 2 is unknown
|
||||||
|
if let Some(reward_id) = reward_component.reward_id {
|
||||||
|
let drop = wicked_waifus_data::drop_package_data::get(&reward_id).unwrap();
|
||||||
|
let usages = drop
|
||||||
|
.drop_preview
|
||||||
|
.iter()
|
||||||
|
.map(|(&id, &quantity)| ItemUsage { id, quantity })
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let updated_items = player.inventory.add_items(&usages);
|
||||||
|
let normal_item_list = player
|
||||||
|
.inventory
|
||||||
|
.to_normal_item_list_filtered(updated_items.keys().cloned().collect::<Vec<i32>>());
|
||||||
|
player.notify(NormalItemUpdateNotify {
|
||||||
|
normal_item_list,
|
||||||
|
no_tips: false,
|
||||||
|
});
|
||||||
|
// UpdateHandBookActiveStateMapNotify
|
||||||
|
let mut rewards: HashMap<i32, WR> = HashMap::new();
|
||||||
|
rewards.insert(
|
||||||
|
0,
|
||||||
|
WR {
|
||||||
|
item_list: drop
|
||||||
|
.drop_preview
|
||||||
|
.iter()
|
||||||
|
.map(|(&id, &quantity)| RewardItemInfo {
|
||||||
|
show_plan_id: 0, // TODO: Check how to get this
|
||||||
|
item_id: id,
|
||||||
|
count: quantity,
|
||||||
|
incr_id: 0,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
player.notify(ItemRewardNotify {
|
||||||
|
drop_id: reward_id,
|
||||||
|
reason: 15000,
|
||||||
|
magnification: 1,
|
||||||
|
reward_items: rewards,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// TODO: Should we remove entity?? get pcap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn unlock_teleport_trigger_action(
|
||||||
|
player: &mut Player,
|
||||||
|
_entity_id: i64,
|
||||||
|
_level_entity_data: &wicked_waifus_data::LevelEntityConfigData,
|
||||||
|
_template_config: &wicked_waifus_data::TemplateConfigData,
|
||||||
|
action: UnlockTeleportTrigger
|
||||||
|
) {
|
||||||
|
player.unlock_teleport(action.teleport_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn change_self_entity_state_action(
|
||||||
|
player: &mut Player,
|
||||||
|
entity_id: i64,
|
||||||
|
level_entity_data: &wicked_waifus_data::LevelEntityConfigData,
|
||||||
|
template_config: &wicked_waifus_data::TemplateConfigData,
|
||||||
|
action: ChangeSelfEntityState,
|
||||||
|
) {
|
||||||
|
let state = tag_utils::get_tag_id_by_name(action.entity_state.as_str());
|
||||||
|
|
||||||
|
// TODO: update Tag::CommonEntityTags too??
|
||||||
|
let old_state = {
|
||||||
|
let world_ref = player.world.borrow();
|
||||||
|
let world = world_ref.get_world_entity();
|
||||||
|
let mut state_tag = query_components!(world, entity_id, StateTag).0.unwrap();
|
||||||
|
let old_state = state_tag.state_tag_id;
|
||||||
|
tracing::debug!("ChangeSelfEntityState: old state {old_state} -> new state: {state}");
|
||||||
|
state_tag.state_tag_id = state;
|
||||||
|
old_state
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(entity_state_component) = level_entity_data
|
||||||
|
.components_data
|
||||||
|
.entity_state_component
|
||||||
|
.as_ref()
|
||||||
|
.or(template_config
|
||||||
|
.components_data
|
||||||
|
.entity_state_component
|
||||||
|
.as_ref())
|
||||||
|
.cloned()
|
||||||
|
{
|
||||||
|
let entity_state_component: EntityStateComponent = entity_state_component; // TODO: Remove this line, used for casting only
|
||||||
|
|
||||||
|
// TODO: implement rest of cases
|
||||||
|
if let Some(state_change_behaviors) = entity_state_component.state_change_behaviors {
|
||||||
|
for state_change_behavior in state_change_behaviors {
|
||||||
|
// TODO: implement rest of cases
|
||||||
|
let expected = tag_utils::get_tag_id_by_name(state_change_behavior.state.as_str());
|
||||||
|
|
||||||
|
if expected == state {
|
||||||
|
if let Some(actions) = state_change_behavior.action {
|
||||||
|
for sub in actions {
|
||||||
|
handle_action(
|
||||||
|
player,
|
||||||
|
entity_id,
|
||||||
|
level_entity_data,
|
||||||
|
template_config,
|
||||||
|
sub,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
player.notify(EntityCommonTagNotify {
|
||||||
|
id: entity_id,
|
||||||
|
tags: vec![
|
||||||
|
CommonTagData {
|
||||||
|
tag_id: old_state,
|
||||||
|
remove_tag_ids: false,
|
||||||
|
}, // Remove
|
||||||
|
CommonTagData {
|
||||||
|
tag_id: state,
|
||||||
|
remove_tag_ids: true,
|
||||||
|
}, // Add
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
player.notify(EntityStateReadyNotify {
|
||||||
|
entity_id,
|
||||||
|
tag_id: state,
|
||||||
|
ready: true, // TODO: Always true? or shall we compare it to something??
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_buff_to_entity(
|
||||||
|
world: &mut WorldEntity,
|
||||||
|
entity_ids: Vec<i64>,
|
||||||
|
buff_ids: Vec<i64>,
|
||||||
|
) {
|
||||||
|
for entity_id in entity_ids {
|
||||||
|
let (Some(mut buff_component),) = query_components!(world, entity_id, FightBuff) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
for buff_id in &buff_ids {
|
||||||
|
buff_component.fight_buff_infos.push(FightBuffInformation {
|
||||||
|
handle_id: 1,
|
||||||
|
buff_id: *buff_id,
|
||||||
|
level: 1,
|
||||||
|
stack_count: 1,
|
||||||
|
instigator_id: 0,
|
||||||
|
entity_id: 0,
|
||||||
|
apply_type: 0,
|
||||||
|
duration: -1.0,
|
||||||
|
left_duration: -1.0,
|
||||||
|
context: vec![],
|
||||||
|
is_active: true,
|
||||||
|
server_id: 1,
|
||||||
|
message_id: 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_buff_to_entity_action(
|
||||||
|
player: &mut Player,
|
||||||
|
entity_id: i64,
|
||||||
|
level_entity_data: &wicked_waifus_data::LevelEntityConfigData,
|
||||||
|
template_config: &wicked_waifus_data::TemplateConfigData,
|
||||||
|
params: AddBuffToEntity
|
||||||
|
) {
|
||||||
|
tracing::info!("entity buff request received with the following details: {:#?}.", params);
|
||||||
|
let mut world_ref = player.world.borrow_mut();
|
||||||
|
let world = world_ref.get_mut_world_entity();
|
||||||
|
|
||||||
|
match params {
|
||||||
|
AddBuffToEntity::SingleEntityBuffs(single_entity_buffs) => {
|
||||||
|
add_buff_to_entity(world, vec![single_entity_buffs.entity_id], single_entity_buffs.buff_ids)
|
||||||
|
},
|
||||||
|
AddBuffToEntity::MultipleEntitiesBuff(multiple_entities_buff) => {
|
||||||
|
add_buff_to_entity(world, multiple_entities_buff.entity_ids, multiple_entities_buff.buff_ids)
|
||||||
|
},
|
||||||
|
AddBuffToEntity::SelfEntityBuff(self_entity_buff) => {
|
||||||
|
add_buff_to_entity(world, vec![entity_id], self_entity_buff.buff_ids)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_buff_from_entity_action(
|
||||||
|
player: &mut Player,
|
||||||
|
entity_id: i64,
|
||||||
|
level_entity_data: &wicked_waifus_data::LevelEntityConfigData,
|
||||||
|
template_config: &wicked_waifus_data::TemplateConfigData,
|
||||||
|
params: RemoveBuffFromEntity
|
||||||
|
) {
|
||||||
|
tracing::info!("entity buff request received with the following details: {:#?}.", params);
|
||||||
|
let mut world_ref = player.world.borrow_mut();
|
||||||
|
let world = world_ref.get_mut_world_entity();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_buff_to_player_action(
|
||||||
|
player: &mut Player,
|
||||||
|
entity_id: i64,
|
||||||
|
level_entity_data: &wicked_waifus_data::LevelEntityConfigData,
|
||||||
|
template_config: &wicked_waifus_data::TemplateConfigData,
|
||||||
|
params: AddBuffToPlayer
|
||||||
|
) {
|
||||||
|
tracing::info!("entity buff request received with the following details: {:#?}.", params);
|
||||||
|
let mut world_ref = player.world.borrow_mut();
|
||||||
|
let world = world_ref.get_mut_world_entity();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_buff_from_player_action(
|
||||||
|
player: &mut Player,
|
||||||
|
entity_id: i64,
|
||||||
|
level_entity_data: &wicked_waifus_data::LevelEntityConfigData,
|
||||||
|
template_config: &wicked_waifus_data::TemplateConfigData,
|
||||||
|
params: RemoveBuffFromPlayer
|
||||||
|
) {
|
||||||
|
tracing::info!("entity buff request received with the following details: {:#?}.", params);
|
||||||
|
let mut world_ref = player.world.borrow_mut();
|
||||||
|
let world = world_ref.get_mut_world_entity();
|
||||||
|
}
|
58
wicked-waifus-game-server/src/logic/handler/attribute.rs
Normal file
58
wicked-waifus-game-server/src/logic/handler/attribute.rs
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
use wicked_waifus_protocol::{AttributeChangedRequest, AttributeChangedResponse, EAttributeType, ErrorCode, FormationAttrRequest, FormationAttrResponse};
|
||||||
|
|
||||||
|
use crate::{logic::{ecs::component::ComponentContainer, player::Player}, query_components};
|
||||||
|
|
||||||
|
pub fn on_attribute_changed_request(
|
||||||
|
player: &mut Player,
|
||||||
|
request: AttributeChangedRequest,
|
||||||
|
response: &mut AttributeChangedResponse,
|
||||||
|
) {
|
||||||
|
let mut world_ref = player.world.borrow_mut();
|
||||||
|
let world = world_ref.get_mut_world_entity();
|
||||||
|
|
||||||
|
let id = request.id;
|
||||||
|
|
||||||
|
if let (Some(mut component),) = query_components!(world, id, Attribute) {
|
||||||
|
for needs_editing in request.attributes {
|
||||||
|
if let Ok(attr_type) = EAttributeType::try_from(needs_editing.attribute_type) {
|
||||||
|
component.attr_map.get_mut(&attr_type).unwrap().0 = needs_editing.current_value;
|
||||||
|
component.attr_map.get_mut(&attr_type).unwrap().1 = needs_editing.value_increment;
|
||||||
|
} else {
|
||||||
|
tracing::warn!("Attribute skipped!");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response.error_code = ErrorCode::Success.into()
|
||||||
|
} else {
|
||||||
|
response.error_code = ErrorCode::ErrEntityNotFound.into()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn on_formation_attr_request(
|
||||||
|
player: &mut Player,
|
||||||
|
request: FormationAttrRequest,
|
||||||
|
response: &mut FormationAttrResponse,
|
||||||
|
) {
|
||||||
|
let mut world_ref = player.world.borrow_mut();
|
||||||
|
let world = world_ref.get_mut_world_entity();
|
||||||
|
|
||||||
|
let formation = &player.formation_list[&player.cur_formation_id];
|
||||||
|
|
||||||
|
for role_id in formation.role_ids.clone() {
|
||||||
|
if let (Some(mut component),) = query_components!(world, role_id as i64, Attribute) {
|
||||||
|
for needs_editing in &request.formation_attrs {
|
||||||
|
if let Ok(attr_type) = EAttributeType::try_from(needs_editing.attr_id) {
|
||||||
|
component.attr_map.get_mut(&attr_type).unwrap().0 = needs_editing.current_value;
|
||||||
|
component.attr_map.get_mut(&attr_type).unwrap().1 = needs_editing.max_value;
|
||||||
|
} else {
|
||||||
|
tracing::warn!("Attribute skipped!");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response.error_code = ErrorCode::Success.into()
|
||||||
|
} else {
|
||||||
|
response.error_code = ErrorCode::ErrEntityNotFound.into()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -160,38 +160,38 @@ fn handle_damage_execute_request(
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
if let Some((value, _)) = query_components!(world, request.target_entity_id, Attribute)
|
// if let Some((value, _)) = query_components!(world, request.target_entity_id, Attribute)
|
||||||
.0
|
// .0
|
||||||
.unwrap()
|
// .unwrap()
|
||||||
.attr_map
|
// .attr_map
|
||||||
.get(&EAttributeType::Life)
|
// .get(&EAttributeType::Life)
|
||||||
{
|
// {
|
||||||
let updated_value = match value - damage >= 0 {
|
// let updated_value = match value - damage >= 0 {
|
||||||
true => value - damage,
|
// true => value - damage,
|
||||||
false => 0,
|
// false => 0,
|
||||||
};
|
// };
|
||||||
receive_pack.data.push(create_combat_notify(
|
// receive_pack.data.push(create_combat_notify(
|
||||||
CombatCommon {
|
// CombatCommon {
|
||||||
entity_id: request.target_entity_id,
|
// entity_id: request.target_entity_id,
|
||||||
..Default::default()
|
// ..Default::default()
|
||||||
},
|
// },
|
||||||
combat_notify_data::Message::AttributeChangedNotify(AttributeChangedNotify {
|
// combat_notify_data::Message::AttributeChangedNotify(AttributeChangedNotify {
|
||||||
id: request.target_entity_id,
|
// id: request.target_entity_id,
|
||||||
attributes: vec![GameplayAttributeData {
|
// attributes: vec![GameplayAttributeData {
|
||||||
current_value: updated_value,
|
// current_value: updated_value,
|
||||||
value_increment: updated_value,
|
// value_increment: updated_value,
|
||||||
attribute_type: EAttributeType::Life.into(),
|
// attribute_type: EAttributeType::Life.into(),
|
||||||
}],
|
// }],
|
||||||
}),
|
// }),
|
||||||
));
|
// ));
|
||||||
if updated_value == 0 {
|
// if updated_value == 0 {
|
||||||
world_util::remove_entity(
|
// world_util::remove_entity(
|
||||||
player,
|
// player,
|
||||||
request.target_entity_id,
|
// request.target_entity_id,
|
||||||
ERemoveEntityType::HpIsZero,
|
// ERemoveEntityType::HpIsZero,
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
response.error_code = ErrorCode::Success.into();
|
response.error_code = ErrorCode::Success.into();
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ dummy_handler! {
|
||||||
ExchangeReward;
|
ExchangeReward;
|
||||||
Liveness;
|
Liveness;
|
||||||
PhotoMemory;
|
PhotoMemory;
|
||||||
|
WeaponSkin;
|
||||||
VisionEquipGroupInfo;
|
VisionEquipGroupInfo;
|
||||||
UpdatePlayStationBlockAccount;
|
UpdatePlayStationBlockAccount;
|
||||||
AdventureManual;
|
AdventureManual;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use wicked_waifus_protocol::{EntityAccessInfo, EntityAccessRangeRequest, EntityAccessRangeResponse, EntityActiveRequest, EntityActiveResponse, EntityFollowTrackRequest, EntityFollowTrackResponse, EntityInteractRequest, EntityInteractResponse, EntityOnLandedRequest, EntityOnLandedResponse, EntityPb, EntityPositionRequest, EntityPositionResponse, ErrorCode, GetRewardTreasureBoxRequest, GetRewardTreasureBoxResponse, MovePackagePush};
|
use wicked_waifus_protocol::{ApplyGameplayEffectPush, ApplyGameplayEffectRequest, ApplyGameplayEffectResponse, EntityAccessInfo, EntityAccessRangeRequest, EntityAccessRangeResponse, EntityActiveRequest, EntityActiveResponse, EntityFollowTrackRequest, EntityFollowTrackResponse, EntityInteractRequest, EntityInteractResponse, EntityOnLandedRequest, EntityOnLandedResponse, EntityPb, EntityPositionRequest, EntityPositionResponse, ErrorCode, GetRewardTreasureBoxRequest, GetRewardTreasureBoxResponse, MovePackagePush, OrderApplyBuffRequest, OrderApplyBuffResponse, OrderRemoveBuffRequest, OrderRemoveBuffResponse, RemoveGameplayEffectPush, RemoveGameplayEffectRequest, RemoveGameplayEffectResponse};
|
||||||
|
|
||||||
use wicked_waifus_data::pb_components::option::OptionType;
|
use wicked_waifus_data::pb_components::option::OptionType;
|
||||||
|
|
||||||
|
use crate::logic::handler::handle_action;
|
||||||
use crate::{logic, logic::ecs::component::ComponentContainer, logic::player::Player, query_components};
|
use crate::{logic, logic::ecs::component::ComponentContainer, logic::player::Player, query_components};
|
||||||
use crate::logic::utils::action_utils::perform_action;
|
|
||||||
use crate::logic::utils::condition_utils::check_condition;
|
use crate::logic::utils::condition_utils::check_condition;
|
||||||
|
|
||||||
pub fn on_entity_active_request(
|
pub fn on_entity_active_request(
|
||||||
|
@ -190,7 +190,7 @@ pub fn on_entity_interact_request(
|
||||||
match option_type {
|
match option_type {
|
||||||
OptionType::Actions(actions) => {
|
OptionType::Actions(actions) => {
|
||||||
for action in actions.actions {
|
for action in actions.actions {
|
||||||
perform_action(player, request.entity_id, &entity, template_config, action);
|
handle_action(player, request.entity_id, &entity, template_config, action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
OptionType::Flow(_) => {
|
OptionType::Flow(_) => {
|
||||||
|
@ -234,6 +234,52 @@ pub fn on_get_reward_treasure_box_request(
|
||||||
tracing::debug!("GetRewardTreasureBoxRequest with ID: {} and ConfigID {config_id}", request.entity_id);
|
tracing::debug!("GetRewardTreasureBoxRequest with ID: {} and ConfigID {config_id}", request.entity_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn on_order_apply_buff_request(
|
||||||
|
player: &Player,
|
||||||
|
request: OrderApplyBuffRequest,
|
||||||
|
_response: &mut OrderApplyBuffResponse,
|
||||||
|
) {
|
||||||
|
tracing::info!("OrderApplyBuffRequest receuived");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn on_order_remove_buff_request(
|
||||||
|
player: &Player,
|
||||||
|
request: OrderRemoveBuffRequest,
|
||||||
|
_response: &mut OrderRemoveBuffResponse,
|
||||||
|
) {
|
||||||
|
tracing::info!("OrderRemoveBuffRequest receuived");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn on_apply_gameplay_effect_request(
|
||||||
|
player: &Player,
|
||||||
|
request: ApplyGameplayEffectRequest,
|
||||||
|
response: &mut ApplyGameplayEffectResponse
|
||||||
|
) {
|
||||||
|
tracing::info!("applygameplayeffect receuived");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn on_apply_gameplay_effect_push(
|
||||||
|
player: &Player,
|
||||||
|
push: ApplyGameplayEffectPush
|
||||||
|
) {
|
||||||
|
tracing::info!("applygameplayeffect receuived");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn on_remove_gameplay_effect_request(
|
||||||
|
player: &Player,
|
||||||
|
request: RemoveGameplayEffectRequest,
|
||||||
|
response: &mut RemoveGameplayEffectResponse
|
||||||
|
) {
|
||||||
|
tracing::info!("applygameplayeffect receuived");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn on_remove_gameplay_effect_push(
|
||||||
|
player: &Player,
|
||||||
|
push: RemoveGameplayEffectPush
|
||||||
|
) {
|
||||||
|
tracing::info!("applygameplayeffect receuived");
|
||||||
|
}
|
||||||
|
|
||||||
fn get_config_id_from_entity_id(player: &Player, entity_id: i64) -> i64 {
|
fn get_config_id_from_entity_id(player: &Player, entity_id: i64) -> i64 {
|
||||||
let world_ref = player.world.borrow();
|
let world_ref = player.world.borrow();
|
||||||
let world = world_ref.get_world_entity();
|
let world = world_ref.get_world_entity();
|
||||||
|
|
|
@ -12,11 +12,12 @@ pub fn on_normal_item_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_weapon_item_request(
|
pub fn on_weapon_item_request(
|
||||||
player: &mut Player,
|
_player: &mut Player,
|
||||||
_: WeaponItemRequest,
|
_: WeaponItemRequest,
|
||||||
response: &mut WeaponItemResponse,
|
_response: &mut WeaponItemResponse,
|
||||||
) {
|
) {
|
||||||
response.weapon_item_list = player.inventory.to_weapon_item_list();
|
// TODO: Implement this
|
||||||
|
tracing::warn!("Unhandled WeaponItemRequest");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_phantom_item_request(
|
pub fn on_phantom_item_request(
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
pub use action::*;
|
||||||
|
pub use attribute::*;
|
||||||
pub use advice::*;
|
pub use advice::*;
|
||||||
pub use animal::*;
|
pub use animal::*;
|
||||||
pub use chat::*;
|
pub use chat::*;
|
||||||
|
@ -19,8 +21,9 @@ use wicked_waifus_protocol::message::Message;
|
||||||
pub use skill::*;
|
pub use skill::*;
|
||||||
pub use teleport::*;
|
pub use teleport::*;
|
||||||
pub use tutorial::*;
|
pub use tutorial::*;
|
||||||
pub use weapon::*;
|
|
||||||
|
|
||||||
|
mod action;
|
||||||
|
mod attribute;
|
||||||
mod advice;
|
mod advice;
|
||||||
mod animal;
|
mod animal;
|
||||||
mod chat;
|
mod chat;
|
||||||
|
@ -41,7 +44,6 @@ mod scene;
|
||||||
mod skill;
|
mod skill;
|
||||||
mod teleport;
|
mod teleport;
|
||||||
mod tutorial;
|
mod tutorial;
|
||||||
mod weapon;
|
|
||||||
|
|
||||||
macro_rules! handle_request {
|
macro_rules! handle_request {
|
||||||
($($name:ident $(, $inner_package:ident)?;)*) => {
|
($($name:ident $(, $inner_package:ident)?;)*) => {
|
||||||
|
@ -57,7 +59,7 @@ macro_rules! handle_request {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
tracing::debug!("logic: processing request {}", stringify!($($inner_package::)?[<$name Request>]));
|
// tracing::debug!("logic: processing request {}", stringify!($($inner_package::)?[<$name Request>]));
|
||||||
|
|
||||||
let mut response = ::wicked_waifus_protocol::$($inner_package::)?[<$name Response>]::default();
|
let mut response = ::wicked_waifus_protocol::$($inner_package::)?[<$name Response>]::default();
|
||||||
[<on_ $($inner_package:snake _)? $name:snake _request>](player, request, &mut response);
|
[<on_ $($inner_package:snake _)? $name:snake _request>](player, request, &mut response);
|
||||||
|
@ -112,6 +114,40 @@ macro_rules! handle_push {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! handle_action {
|
||||||
|
($($variant:ident),* $(,)?) => {
|
||||||
|
use wicked_waifus_data::pb_components::action::Action;
|
||||||
|
use crate::logic::player::Player;
|
||||||
|
|
||||||
|
fn perform_action(
|
||||||
|
player: &mut Player,
|
||||||
|
entity_id: i64,
|
||||||
|
level_entity_data: &wicked_waifus_data::LevelEntityConfigData,
|
||||||
|
template_config: &wicked_waifus_data::TemplateConfigData,
|
||||||
|
action: Action
|
||||||
|
) {
|
||||||
|
::paste::paste! {
|
||||||
|
match action {
|
||||||
|
$(
|
||||||
|
Action::$variant(inner) => {
|
||||||
|
[<$variant:snake _action>](
|
||||||
|
player,
|
||||||
|
entity_id,
|
||||||
|
level_entity_data,
|
||||||
|
template_config,
|
||||||
|
inner.params
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)*
|
||||||
|
_ => {
|
||||||
|
::tracing::warn!("Action not implemented for: {:?}", action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
handle_request! {
|
handle_request! {
|
||||||
// Advice
|
// Advice
|
||||||
Advice;
|
Advice;
|
||||||
|
@ -122,6 +158,10 @@ handle_request! {
|
||||||
AnimalDrop;
|
AnimalDrop;
|
||||||
AnimalDestroy;
|
AnimalDestroy;
|
||||||
|
|
||||||
|
// Attribute
|
||||||
|
AttributeChanged;
|
||||||
|
FormationAttr;
|
||||||
|
|
||||||
// Chat (TODO: Review TODOs)
|
// Chat (TODO: Review TODOs)
|
||||||
PrivateChat;
|
PrivateChat;
|
||||||
PrivateChatData;
|
PrivateChatData;
|
||||||
|
@ -143,6 +183,10 @@ handle_request! {
|
||||||
EntityInteract;
|
EntityInteract;
|
||||||
EntityFollowTrack;
|
EntityFollowTrack;
|
||||||
GetRewardTreasureBox;
|
GetRewardTreasureBox;
|
||||||
|
OrderApplyBuff;
|
||||||
|
OrderRemoveBuff;
|
||||||
|
ApplyGameplayEffect;
|
||||||
|
RemoveGameplayEffect;
|
||||||
|
|
||||||
// Friend (TODO: Implement them)
|
// Friend (TODO: Implement them)
|
||||||
FriendAll;
|
FriendAll;
|
||||||
|
@ -200,21 +244,14 @@ handle_request! {
|
||||||
RoleShowListUpdate;
|
RoleShowListUpdate;
|
||||||
ClientCurrentRoleReport;
|
ClientCurrentRoleReport;
|
||||||
RoleFavorList;
|
RoleFavorList;
|
||||||
FormationAttr;
|
|
||||||
UpdateFormation;
|
UpdateFormation;
|
||||||
UnlockRoleSkinList;
|
|
||||||
RoleSkinChange;
|
|
||||||
FlySkinWear;
|
|
||||||
FlySkinWearAllRole;
|
|
||||||
RoleLevelUpView;
|
|
||||||
PbUpLevelRole;
|
|
||||||
RoleBreakThroughView;
|
|
||||||
|
|
||||||
// Scene (TODO: Review this on_..., port some from go)
|
// Scene (TODO: Review this on_..., port some from go)
|
||||||
SceneTrace;
|
SceneTrace;
|
||||||
SceneLoadingFinish;
|
SceneLoadingFinish;
|
||||||
UpdateSceneDate;
|
UpdateSceneDate;
|
||||||
AccessPathTimeServerConfig;
|
AccessPathTimeServerConfig;
|
||||||
|
UnlockRoleSkinList;
|
||||||
PlayerHeadData;
|
PlayerHeadData;
|
||||||
|
|
||||||
// Shop (TODO: Review this on_..., port some from go)
|
// Shop (TODO: Review this on_..., port some from go)
|
||||||
|
@ -245,12 +282,6 @@ handle_request! {
|
||||||
TutorialReceive;
|
TutorialReceive;
|
||||||
TutorialUnlock;
|
TutorialUnlock;
|
||||||
|
|
||||||
// Weapon
|
|
||||||
WeaponSkin;
|
|
||||||
EquipWeaponSkin;
|
|
||||||
SendEquipSkin;
|
|
||||||
EquipTakeOn;
|
|
||||||
|
|
||||||
// TODO: Implement all this properly, workaround for game enter
|
// TODO: Implement all this properly, workaround for game enter
|
||||||
EntityPatrolStop;
|
EntityPatrolStop;
|
||||||
InitRange;
|
InitRange;
|
||||||
|
@ -278,6 +309,7 @@ handle_request! {
|
||||||
Liveness;
|
Liveness;
|
||||||
WebSign;
|
WebSign;
|
||||||
PhotoMemory;
|
PhotoMemory;
|
||||||
|
WeaponSkin;
|
||||||
VisionEquipGroupInfo;
|
VisionEquipGroupInfo;
|
||||||
UpdatePlayStationBlockAccount;
|
UpdatePlayStationBlockAccount;
|
||||||
AdventureManual;
|
AdventureManual;
|
||||||
|
@ -293,10 +325,200 @@ handle_push! {
|
||||||
// Entity
|
// Entity
|
||||||
MovePackage;
|
MovePackage;
|
||||||
|
|
||||||
|
ApplyGameplayEffect;
|
||||||
|
RemoveGameplayEffect;
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
VersionInfo;
|
VersionInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handle_action! {
|
||||||
|
// ExecBattleAction,
|
||||||
|
// WaitBattleCondition,
|
||||||
|
// SetBattleState,
|
||||||
|
// PlayFlow,
|
||||||
|
Collect,
|
||||||
|
// LeisureInteract,
|
||||||
|
UnlockTeleportTrigger,
|
||||||
|
// EnableTemporaryTeleport,
|
||||||
|
// OpenSystemBoard,
|
||||||
|
// OpenSystemFunction,
|
||||||
|
ChangeSelfEntityState,
|
||||||
|
// SetPlayerOperationRestriction,
|
||||||
|
// Wait,
|
||||||
|
// ChangeEntityState,
|
||||||
|
// Log,
|
||||||
|
// EnableNearbyTracking,
|
||||||
|
// TeleportDungeon,
|
||||||
|
// DestroySelf,
|
||||||
|
// CameraLookAt,
|
||||||
|
// StopCameraLookAt,
|
||||||
|
// EnterOrbitalCamera,
|
||||||
|
// ExitOrbitalCamera,
|
||||||
|
// SendAiEvent,
|
||||||
|
// SetInteractionLockState,
|
||||||
|
// AwakeEntity,
|
||||||
|
// ChangeLiftTarget,
|
||||||
|
// CalculateVar,
|
||||||
|
AddBuffToPlayer,
|
||||||
|
RemoveBuffFromPlayer,
|
||||||
|
AddBuffToEntity,
|
||||||
|
RemoveBuffFromEntity,
|
||||||
|
// Prompt,
|
||||||
|
// SetEntityVisible,
|
||||||
|
// DestroyEntity,
|
||||||
|
// GuideTrigger,
|
||||||
|
// TriggerCameraShake,
|
||||||
|
// SetVar,
|
||||||
|
// VehicleEnter,
|
||||||
|
// VehicleExitPlayer,
|
||||||
|
// LockEntity,
|
||||||
|
// UnlockEntity,
|
||||||
|
// CommonTip,
|
||||||
|
// CommonTip2,
|
||||||
|
// PostAkEvent,
|
||||||
|
// VehicleEnterNpc,
|
||||||
|
// VehicleExitNpc,
|
||||||
|
// PlayerLookAt,
|
||||||
|
// PlayBubble,
|
||||||
|
// AddPlayBubble,
|
||||||
|
// ClearPlayBubble,
|
||||||
|
// ExecRiskHarvestEffect,
|
||||||
|
// EnableLevelPlay,
|
||||||
|
// ClaimLevelPlayReward,
|
||||||
|
// SettlementDungeon,
|
||||||
|
// ExitDungeon,
|
||||||
|
// FinishDungeon,
|
||||||
|
// RecordDungeonEvent,
|
||||||
|
// RecoverDurability,
|
||||||
|
// FadeInScreen,
|
||||||
|
// FadeOutScreen,
|
||||||
|
// ChangeNpcPerformState,
|
||||||
|
// EntityTurnTo,
|
||||||
|
// EntityLookAt,
|
||||||
|
// ToggleMapMarkState,
|
||||||
|
// RandomVar,
|
||||||
|
// ModifySceneItemAttributeTag,
|
||||||
|
// VehicleWaterfallClimbing,
|
||||||
|
// VehicleTeleport,
|
||||||
|
// RogueGotoNextFloor,
|
||||||
|
// RogueReceiveReward,
|
||||||
|
// RogueSelectRoom,
|
||||||
|
// RogueActivatePortal,
|
||||||
|
// MowingTowerGotoNextFloor,
|
||||||
|
// SlashAndTowerGotoNextFloor,
|
||||||
|
// PlayMontage,
|
||||||
|
// OpenSystemBoardWithReturn,
|
||||||
|
// UnlockSystemItem,
|
||||||
|
// SetSportsState,
|
||||||
|
// OpenSimpleGameplay,
|
||||||
|
// PlayEffect,
|
||||||
|
// PlayEffect2,
|
||||||
|
// RestorePlayerCameraAdjustment,
|
||||||
|
// AdjustPlayerCamera,
|
||||||
|
// SetPlayerPos,
|
||||||
|
// MoveWithSpline,
|
||||||
|
// EnableSplineMoveModel,
|
||||||
|
// ToggleScanSplineEffect,
|
||||||
|
// MoveSceneItem,
|
||||||
|
// StopSceneItemMove,
|
||||||
|
// FireBullet,
|
||||||
|
// ClearFishingCabinInSaleItems,
|
||||||
|
// AcceptFishingEntrust,
|
||||||
|
// DestroyFishingBoat,
|
||||||
|
// SetJigsawItem,
|
||||||
|
// SetJigsawFoundation,
|
||||||
|
// SetTeleControl,
|
||||||
|
// SetEntityClientVisible,
|
||||||
|
// ToggleHighlightExploreUi,
|
||||||
|
// ExecAlertSystemAction,
|
||||||
|
// AddFlowInteractOption,
|
||||||
|
// RemoveFlowInteractOption,
|
||||||
|
// EnableHostility,
|
||||||
|
// ChangePhantomFormation,
|
||||||
|
// RestorePhantomFormation,
|
||||||
|
// ChangeTimer,
|
||||||
|
// ToggleTimerPauseState,
|
||||||
|
// ChangeFightTeam,
|
||||||
|
// AddTrialFollowShooter,
|
||||||
|
// RemoveTrialFollowShooter,
|
||||||
|
// AddTrialCharacter,
|
||||||
|
// RemoveTrialCharacter,
|
||||||
|
// SetAreaState,
|
||||||
|
// SwitchSubLevels,
|
||||||
|
// ChangeTeamPosition,
|
||||||
|
// GetItem,
|
||||||
|
// CreatePrefab,
|
||||||
|
// DestroyPrefab,
|
||||||
|
// CompleteGuide,
|
||||||
|
// PlayDynamicSettlement,
|
||||||
|
// UsePhantomSkill,
|
||||||
|
// HideTargetRange,
|
||||||
|
// ChangeOtherState,
|
||||||
|
// SetRegionConfig,
|
||||||
|
// SetReviveRegion,
|
||||||
|
// ExecResurrection,
|
||||||
|
// ShowTargetRange,
|
||||||
|
// SetTime,
|
||||||
|
// SetTimeLockState,
|
||||||
|
// EnableSystem,
|
||||||
|
// EnableAoiNotify,
|
||||||
|
// SetForceLock,
|
||||||
|
// PlayRegisteredMontage,
|
||||||
|
// SetAudioState,
|
||||||
|
// HideGroup,
|
||||||
|
// ShowHidedGroup,
|
||||||
|
// HideSpecificEntities,
|
||||||
|
// ShowSpecificEntities,
|
||||||
|
// RemovePreloadResource,
|
||||||
|
// Preload,
|
||||||
|
// EnableAI,
|
||||||
|
// SwitchDataLayers,
|
||||||
|
// DestroyQuest,
|
||||||
|
// DestroyQuestItem,
|
||||||
|
// PromptQuestChapterUI,
|
||||||
|
// TakePlotPhoto,
|
||||||
|
// SetWuYinQuState,
|
||||||
|
// RunActions,
|
||||||
|
// ManualOccupations,
|
||||||
|
// SetWeather,
|
||||||
|
// SendNpcMail,
|
||||||
|
// EnableFunction,
|
||||||
|
// FocusOnMapMark,
|
||||||
|
// CharacterLookAt,
|
||||||
|
// AddGuestCharacter,
|
||||||
|
// RemoveGuestCharacter,
|
||||||
|
// TeleportToAndEnterVehicle,
|
||||||
|
// SetAreaTimeState,
|
||||||
|
// ResetPlayerCameraFocus,
|
||||||
|
// ResetLevelPlay,
|
||||||
|
// VehicleSprint,
|
||||||
|
// VehicleMoveWithPathLine,
|
||||||
|
// ClientPreEnableSubLevels,
|
||||||
|
// GuestOperateUiAnimation,
|
||||||
|
// ChangeEntityCamp,
|
||||||
|
// NewMoveWithSpline,
|
||||||
|
// DangoAbyssActivatePortal,
|
||||||
|
// DangoAbyssCreateRewardTreasureBox,
|
||||||
|
// DangoAbyssGotoNextFloor,
|
||||||
|
// DangoAbyssReceiveReward,
|
||||||
|
// SummonEntity,
|
||||||
|
// GetRewardByInteract,
|
||||||
|
// OpenQte,
|
||||||
|
// ActiveAntiGravitySafePoint,
|
||||||
|
// BvbPlayDialog,
|
||||||
|
// BvbSendSystemEvent,
|
||||||
|
// BvbSendAiEvent,
|
||||||
|
// BvbPlayerOperationConstraint,
|
||||||
|
// ExecClientBattleAction,
|
||||||
|
// TriggerSpecificScanEffect,
|
||||||
|
// SetActorVar,
|
||||||
|
// RunActorCustomEvent,
|
||||||
|
// StopUiScreenEffect,
|
||||||
|
// StopNewMoveWithSpline,
|
||||||
|
// RequestSystemFunction
|
||||||
|
}
|
||||||
|
|
||||||
pub fn handle_logic_message(player: &mut super::player::Player, msg: Message) {
|
pub fn handle_logic_message(player: &mut super::player::Player, msg: Message) {
|
||||||
match msg {
|
match msg {
|
||||||
Message::Request { .. } => handle_request(player, msg),
|
Message::Request { .. } => handle_request(player, msg),
|
||||||
|
@ -309,3 +531,13 @@ pub fn handle_logic_message(player: &mut super::player::Player, msg: Message) {
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn handle_action(
|
||||||
|
player: &mut Player,
|
||||||
|
entity_id: i64,
|
||||||
|
level_entity_data: &wicked_waifus_data::LevelEntityConfigData,
|
||||||
|
template_config: &wicked_waifus_data::TemplateConfigData,
|
||||||
|
element: Action
|
||||||
|
) {
|
||||||
|
perform_action(player, entity_id, level_entity_data, template_config, element)
|
||||||
|
}
|
|
@ -1,11 +1,18 @@
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use crate::logic::components::{ParaglidingSkin, RoleSkin, SoarWingSkin, WeaponSkin};
|
use wicked_waifus_protocol::{
|
||||||
use crate::logic::ecs::component::ComponentContainer;
|
ClientCurrentRoleReportRequest, ClientCurrentRoleReportResponse, ERemoveEntityType, ErrorCode,
|
||||||
use crate::logic::player::{ItemUsage, Player};
|
FormationAttrRequest, FormationAttrResponse, PlayerMotionRequest, PlayerMotionResponse,
|
||||||
|
RoleFavorListRequest, RoleFavorListResponse, RoleShowListUpdateRequest,
|
||||||
|
RoleShowListUpdateResponse, UpdateFormationRequest, UpdateFormationResponse,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::logic::ecs::world;
|
||||||
|
use crate::logic::player::Player;
|
||||||
use crate::logic::role::{Role, RoleFormation};
|
use crate::logic::role::{Role, RoleFormation};
|
||||||
use crate::modify_component;
|
use crate::logic::utils::world_util::{add_player_entities, summon_concomitant};
|
||||||
use wicked_waifus_protocol::{ArrayIntInt, ClientCurrentRoleReportRequest, ClientCurrentRoleReportResponse, ERemoveEntityType, EntityAddNotify, EntityEquipSkinChangeNotify, EntityFlySkinChangeData, EntityPb, EntityRemoveInfo, EntityRemoveNotify, EquipFlySkinData, ErrorCode, FlySkinConfigData, FlySkinWearAllRoleRequest, FlySkinWearAllRoleResponse, FlySkinWearRequest, FlySkinWearResponse, FormationAttrRequest, FormationAttrResponse, PbUpLevelRoleRequest, PbUpLevelRoleResponse, PlayerMotionRequest, PlayerMotionResponse, RoleBreakThroughViewRequest, RoleBreakThroughViewResponse, RoleFavorListRequest, RoleFavorListResponse, RoleFlyEquipChangeNotify, RoleLevelUpViewRequest, RoleLevelUpViewResponse, RoleShowListUpdateRequest, RoleShowListUpdateResponse, RoleSkinChangeRequest, RoleSkinChangeResponse, SoarWingOrParaglidingSkinChangeNotify, UnlockRoleSkinListRequest, UnlockRoleSkinListResponse, UpdateFormationRequest, UpdateFormationResponse, WeaponSkinComponentPb};
|
use crate::query_components;
|
||||||
|
use crate::logic::ecs::component::ComponentContainer;
|
||||||
|
|
||||||
pub fn on_role_show_list_update_request(
|
pub fn on_role_show_list_update_request(
|
||||||
player: &mut Player,
|
player: &mut Player,
|
||||||
|
@ -41,14 +48,6 @@ pub fn on_role_favor_list_request(
|
||||||
response.error_code = ErrorCode::Success.into();
|
response.error_code = ErrorCode::Success.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_formation_attr_request(
|
|
||||||
_player: &Player,
|
|
||||||
_request: FormationAttrRequest,
|
|
||||||
response: &mut FormationAttrResponse,
|
|
||||||
) {
|
|
||||||
response.error_code = ErrorCode::Success.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn on_update_formation_request(
|
pub fn on_update_formation_request(
|
||||||
player: &mut Player,
|
player: &mut Player,
|
||||||
request: UpdateFormationRequest,
|
request: UpdateFormationRequest,
|
||||||
|
@ -62,6 +61,22 @@ pub fn on_update_formation_request(
|
||||||
let cur_role = formation.cur_role;
|
let cur_role = formation.cur_role;
|
||||||
let is_current = formation.is_current;
|
let is_current = formation.is_current;
|
||||||
|
|
||||||
|
// update all formation and check formation_list
|
||||||
|
player
|
||||||
|
.formation_list
|
||||||
|
.entry(formation_id)
|
||||||
|
.and_modify(|r| {
|
||||||
|
r.cur_role = formation.cur_role;
|
||||||
|
r.role_ids = formation.role_ids.clone();
|
||||||
|
r.is_current = is_current;
|
||||||
|
})
|
||||||
|
.or_insert(RoleFormation {
|
||||||
|
id: formation_id,
|
||||||
|
cur_role: formation.cur_role,
|
||||||
|
role_ids: formation.role_ids.clone(),
|
||||||
|
is_current,
|
||||||
|
});
|
||||||
|
|
||||||
if is_current {
|
if is_current {
|
||||||
// update player current formation id
|
// update player current formation id
|
||||||
player.cur_formation_id = formation_id;
|
player.cur_formation_id = formation_id;
|
||||||
|
@ -78,30 +93,26 @@ pub fn on_update_formation_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(old_formation) = player.formation_list.get(&real_formation_id) {
|
if let Some(old_formation) = player.formation_list.get(&real_formation_id) {
|
||||||
let removed_entities: Vec<i64> = old_formation
|
let mut removed_entities: Vec<i64> = old_formation
|
||||||
.role_ids
|
.role_ids
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&role_id| world.get_entity_id(role_id))
|
.map(|&role_id| world.get_entity_id(role_id))
|
||||||
.collect();
|
.collect();
|
||||||
|
for id in removed_entities.clone() {
|
||||||
|
if let (Some(concomitant),) = query_components!(world, id, Concomitant) {
|
||||||
|
removed_entities.extend(concomitant.custom_entity_ids.clone());
|
||||||
|
};
|
||||||
|
}
|
||||||
removed_entities.iter().for_each(|&entity_id| {
|
removed_entities.iter().for_each(|&entity_id| {
|
||||||
world.remove_entity(entity_id as i32);
|
world.remove_entity(entity_id as i32);
|
||||||
});
|
});
|
||||||
player.notify(player.build_player_entity_remove_notify(
|
player.notify(player.build_player_entity_remove_notify(
|
||||||
removed_entities,
|
removed_entities,
|
||||||
ERemoveEntityType::RemoveTypeNormal,
|
ERemoveEntityType::RemoveTypeForce,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let added_roles: Vec<Role> = formation
|
player.build_player_entity_add_notify(world);
|
||||||
.role_ids
|
|
||||||
.iter()
|
|
||||||
.map(|&role_id| Role::new(role_id))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
if !added_roles.is_empty() {
|
|
||||||
// add new roles
|
|
||||||
player.notify(player.build_player_entity_add_notify(added_roles, world));
|
|
||||||
}
|
|
||||||
|
|
||||||
// send update group formation notify
|
// send update group formation notify
|
||||||
player.notify(player.build_update_group_formation_notify(
|
player.notify(player.build_update_group_formation_notify(
|
||||||
|
@ -116,22 +127,6 @@ pub fn on_update_formation_request(
|
||||||
|
|
||||||
response.formation = Some(formation.clone());
|
response.formation = Some(formation.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
// update all formation and check formation_list
|
|
||||||
player
|
|
||||||
.formation_list
|
|
||||||
.entry(formation_id)
|
|
||||||
.and_modify(|r| {
|
|
||||||
r.cur_role = formation.cur_role;
|
|
||||||
r.role_ids = formation.role_ids.clone();
|
|
||||||
r.is_current = is_current;
|
|
||||||
})
|
|
||||||
.or_insert(RoleFormation {
|
|
||||||
id: formation_id,
|
|
||||||
cur_role: formation.cur_role,
|
|
||||||
role_ids: formation.role_ids,
|
|
||||||
is_current,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
player.notify(player.build_update_formation_notify());
|
player.notify(player.build_update_formation_notify());
|
||||||
|
@ -149,421 +144,3 @@ pub fn on_player_motion_request(
|
||||||
Some(_) => response.error_id = ErrorCode::Success.into(),
|
Some(_) => response.error_id = ErrorCode::Success.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_unlock_role_skin_list_request(
|
|
||||||
player: &Player,
|
|
||||||
_request: UnlockRoleSkinListRequest,
|
|
||||||
response: &mut UnlockRoleSkinListResponse,
|
|
||||||
) {
|
|
||||||
response.role_skin_list = player.unlocked_skins.role_skins.iter().cloned().collect();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn on_role_skin_change_request(
|
|
||||||
player: &mut Player,
|
|
||||||
request: RoleSkinChangeRequest,
|
|
||||||
response: &mut RoleSkinChangeResponse,
|
|
||||||
) {
|
|
||||||
// TODO: Should we verify role id first against bindata?
|
|
||||||
let role = player.role_list.get_mut(&request.role_id);
|
|
||||||
let Some(role) = role else {
|
|
||||||
response.error_code = ErrorCode::NotValidRole.into();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Verify Id exist in bindata
|
|
||||||
let Some(skin_data) =
|
|
||||||
wicked_waifus_data::role_skin_data::iter().find(|data| data.id == request.skin_id)
|
|
||||||
else {
|
|
||||||
response.error_code = ErrorCode::ErrRoleSkinConfig.into();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Verify Skin is unlocked
|
|
||||||
if !player.unlocked_skins.role_skins.contains(&skin_data.id) {
|
|
||||||
response.error_code = ErrorCode::ErrRoleSkinLocked.into();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that role has this skin
|
|
||||||
if skin_data.role_id != role.role_id {
|
|
||||||
response.error_code = ErrorCode::ErrRoleSkinNotMatch.into();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
role.skin_id = request.skin_id;
|
|
||||||
if request.is_wear_weapon_skin {
|
|
||||||
if skin_data.suit_weapon_skin_id == 0 {
|
|
||||||
response.error_code = ErrorCode::ErrRoleSkinWeaponNotSuit.into();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
role.weapon_skin_id = skin_data.suit_weapon_skin_id;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
let world_ref = player.world.borrow();
|
|
||||||
let world = world_ref.get_world_entity();
|
|
||||||
let entity_id = world.get_entity_id(request.role_id);
|
|
||||||
modify_component!(
|
|
||||||
world.get_entity_components(entity_id as i32),
|
|
||||||
RoleSkin,
|
|
||||||
|skin_component: &mut RoleSkin| {
|
|
||||||
skin_component.skin_id = role.skin_id;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
if request.is_wear_weapon_skin {
|
|
||||||
// Check for suit_weapon_skin_id == 0 has already been done
|
|
||||||
modify_component!(
|
|
||||||
world.get_entity_components(entity_id as i32),
|
|
||||||
WeaponSkin,
|
|
||||||
|skin_component: &mut WeaponSkin| {
|
|
||||||
skin_component.skin_id = skin_data.suit_weapon_skin_id;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// Since the whole entity is recreated this shouldn't be needed but meh, whatever
|
|
||||||
player.notify(EntityEquipSkinChangeNotify {
|
|
||||||
entity_id,
|
|
||||||
weapon_skin_component_pb: Some(WeaponSkinComponentPb {
|
|
||||||
weapon_skin_id:skin_data.suit_weapon_skin_id,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
player.notify(EntityRemoveNotify {
|
|
||||||
remove_infos: vec![EntityRemoveInfo {
|
|
||||||
entity_id,
|
|
||||||
r#type: 0,
|
|
||||||
}],
|
|
||||||
is_remove: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut pb = EntityPb {
|
|
||||||
id: entity_id,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
world
|
|
||||||
.get_entity_components(entity_id as i32)
|
|
||||||
.into_iter()
|
|
||||||
.for_each(|comp| comp.set_pb_data(&mut pb));
|
|
||||||
|
|
||||||
player.notify(EntityAddNotify {
|
|
||||||
entity_pbs: vec![pb],
|
|
||||||
remove_tag_ids: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
player.notify(player.build_update_formation_notify());
|
|
||||||
response.error_code = ErrorCode::Success.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn on_fly_skin_wear_request(
|
|
||||||
player: &mut Player,
|
|
||||||
request: FlySkinWearRequest,
|
|
||||||
response: &mut FlySkinWearResponse,
|
|
||||||
) {
|
|
||||||
let role = player.role_list.get_mut(&request.role_id);
|
|
||||||
let Some(role) = role else {
|
|
||||||
response.error_code = ErrorCode::NotValidRole.into();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Verify Id exist in bindata
|
|
||||||
let skin =
|
|
||||||
wicked_waifus_data::fly_skin_config_data::iter().find(|&skin| skin.id == request.skin_id);
|
|
||||||
let Some(skin) = skin else {
|
|
||||||
response.error_code = ErrorCode::NoFlySkinItem.into();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
match skin.skin_type {
|
|
||||||
0 => {
|
|
||||||
// Verify Skin is unlocked
|
|
||||||
if !player.unlocked_skins.fly_skins.contains(&skin.id) {
|
|
||||||
response.error_code = ErrorCode::ErrRoleSkinLocked.into();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
role.fly_skin_id = request.skin_id
|
|
||||||
}
|
|
||||||
1 => {
|
|
||||||
if !player.unlocked_skins.wing_skins.contains(&skin.id) {
|
|
||||||
response.error_code = ErrorCode::ErrRoleSkinLocked.into();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
role.wing_skin_id = request.skin_id
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
response.error_code = ErrorCode::FlySkinTypeErr.into();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
let world_ref = player.world.borrow();
|
|
||||||
let world = world_ref.get_world_entity();
|
|
||||||
let entity_id = world.get_entity_id(request.role_id);
|
|
||||||
match skin.skin_type {
|
|
||||||
0 => {
|
|
||||||
modify_component!(
|
|
||||||
world.get_entity_components(entity_id as i32),
|
|
||||||
SoarWingSkin,
|
|
||||||
|skin_component: &mut SoarWingSkin| {
|
|
||||||
skin_component.skin_id = role.skin_id;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
1 => {
|
|
||||||
modify_component!(
|
|
||||||
world.get_entity_components(entity_id as i32),
|
|
||||||
ParaglidingSkin,
|
|
||||||
|skin_component: &mut ParaglidingSkin| {
|
|
||||||
skin_component.skin_id = role.skin_id;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
_ => unreachable!("Already tested above"),
|
|
||||||
}
|
|
||||||
player.notify(SoarWingOrParaglidingSkinChangeNotify {
|
|
||||||
fly_skin_data: vec![EntityFlySkinChangeData {
|
|
||||||
entity_id,
|
|
||||||
fly_skin_config_data: vec![FlySkinConfigData {
|
|
||||||
skin_id: request.skin_id,
|
|
||||||
fly_skin_id: skin.skin_type,
|
|
||||||
}],
|
|
||||||
}],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
player.notify(RoleFlyEquipChangeNotify {
|
|
||||||
fly_skin_data: vec![EquipFlySkinData {
|
|
||||||
role_id: request.role_id,
|
|
||||||
skin_id: request.skin_id,
|
|
||||||
}],
|
|
||||||
});
|
|
||||||
response.error_code = ErrorCode::Success.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn on_fly_skin_wear_all_role_request(
|
|
||||||
player: &mut Player,
|
|
||||||
request: FlySkinWearAllRoleRequest,
|
|
||||||
response: &mut FlySkinWearAllRoleResponse,
|
|
||||||
) {
|
|
||||||
let skin =
|
|
||||||
wicked_waifus_data::fly_skin_config_data::iter().find(|&skin| skin.id == request.skin_id);
|
|
||||||
let Some(skin) = skin else {
|
|
||||||
response.error_code = ErrorCode::NoFlySkinItem.into();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
match skin.skin_type {
|
|
||||||
0 => {
|
|
||||||
// Verify Skin is unlocked
|
|
||||||
if !player.unlocked_skins.fly_skins.contains(&skin.id) {
|
|
||||||
response.error_code = ErrorCode::ErrRoleSkinLocked.into();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for role in player.role_list.values_mut() {
|
|
||||||
role.fly_skin_id = request.skin_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1 => {
|
|
||||||
if !player.unlocked_skins.wing_skins.contains(&skin.id) {
|
|
||||||
response.error_code = ErrorCode::ErrRoleSkinLocked.into();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for role in player.role_list.values_mut() {
|
|
||||||
role.wing_skin_id = request.skin_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
response.error_code = ErrorCode::FlySkinTypeErr.into();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
player.notify(RoleFlyEquipChangeNotify {
|
|
||||||
fly_skin_data: player
|
|
||||||
.role_list
|
|
||||||
.values()
|
|
||||||
.map(|r| EquipFlySkinData {
|
|
||||||
role_id: r.role_id,
|
|
||||||
skin_id: request.skin_id,
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
});
|
|
||||||
{
|
|
||||||
let world_ref = player.world.borrow();
|
|
||||||
let world = world_ref.get_world_entity();
|
|
||||||
let data = player
|
|
||||||
.role_list
|
|
||||||
.values()
|
|
||||||
.filter_map(|role| {
|
|
||||||
let entity_id = world.get_entity_id(role.role_id);
|
|
||||||
if entity_id == -1 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
match skin.skin_type {
|
|
||||||
0 => {
|
|
||||||
modify_component!(
|
|
||||||
world.get_entity_components(entity_id as i32),
|
|
||||||
SoarWingSkin,
|
|
||||||
|skin_component: &mut SoarWingSkin| {
|
|
||||||
skin_component.skin_id = role.skin_id;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
1 => {
|
|
||||||
modify_component!(
|
|
||||||
world.get_entity_components(entity_id as i32),
|
|
||||||
ParaglidingSkin,
|
|
||||||
|skin_component: &mut ParaglidingSkin| {
|
|
||||||
skin_component.skin_id = role.skin_id;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
_ => unreachable!("Already tested above"),
|
|
||||||
}
|
|
||||||
Some(EntityFlySkinChangeData {
|
|
||||||
entity_id,
|
|
||||||
fly_skin_config_data: vec![FlySkinConfigData {
|
|
||||||
skin_id: request.skin_id,
|
|
||||||
fly_skin_id: skin.skin_type,
|
|
||||||
}],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
player.notify(SoarWingOrParaglidingSkinChangeNotify {
|
|
||||||
fly_skin_data: data,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
response.error_code = ErrorCode::Success.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn on_role_level_up_view_request(
|
|
||||||
player: &mut Player,
|
|
||||||
request: RoleLevelUpViewRequest,
|
|
||||||
response: &mut RoleLevelUpViewResponse,
|
|
||||||
) {
|
|
||||||
let role = player.role_list.get(&request.role_id);
|
|
||||||
let Some(role) = role else {
|
|
||||||
response.error_code = ErrorCode::NotValidRole.into();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
response.level = role.level;
|
|
||||||
// TODO: shall we get from data? seems client can do it by himself
|
|
||||||
response.level_exp_info = vec![ArrayIntInt { key: 1, value: 200 }];
|
|
||||||
response.exp = role.exp;
|
|
||||||
// it seems add_exp, final_prop, cost_list amd overflow_list are handled by client, so skip
|
|
||||||
|
|
||||||
let items = wicked_waifus_data::role_exp_item_data::iter()
|
|
||||||
.map(|(&id, _)| id)
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
response.item_list = player.inventory.to_array_int_int_filtered(&items);
|
|
||||||
response.error_code = ErrorCode::Success.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn on_pb_up_level_role_request(
|
|
||||||
player: &mut Player,
|
|
||||||
request: PbUpLevelRoleRequest,
|
|
||||||
response: &mut PbUpLevelRoleResponse,
|
|
||||||
) {
|
|
||||||
response.role_id = request.role_id;
|
|
||||||
let role = player.role_list.get(&request.role_id);
|
|
||||||
let Some(role) = role else {
|
|
||||||
response.error_code = ErrorCode::NotValidRole.into();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: no shell_credit??? :turtle_skull:
|
|
||||||
let items = player.inventory.consume_items(
|
|
||||||
&request
|
|
||||||
.item_list
|
|
||||||
.iter()
|
|
||||||
.map(|item| ItemUsage {
|
|
||||||
id: item.key,
|
|
||||||
quantity: -item.value,
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
);
|
|
||||||
let Ok(_items) = items else {
|
|
||||||
response.error_code = ErrorCode::ErrConsumeNotEnough.into();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut total_exp = request
|
|
||||||
.item_list
|
|
||||||
.iter()
|
|
||||||
.filter_map(|item| {
|
|
||||||
wicked_waifus_data::role_exp_item_data::get(&item.key)
|
|
||||||
.map(|exp| exp.basic_exp * item.value)
|
|
||||||
})
|
|
||||||
.sum();
|
|
||||||
|
|
||||||
let role_level_consume_id = wicked_waifus_data::role_info_data::iter()
|
|
||||||
.find(|role| role.id == request.role_id)
|
|
||||||
.map(|role| role.level_consume_id)
|
|
||||||
.unwrap_or(10001);
|
|
||||||
|
|
||||||
let mut levels_consume = wicked_waifus_data::role_level_consume_data::iter()
|
|
||||||
.filter(|consume| {
|
|
||||||
consume.consume_group_id == role_level_consume_id && consume.level > role.level
|
|
||||||
}) // TODO: add upper bound too(till breakthrough)
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
levels_consume.sort_by_key(|item| item.level);
|
|
||||||
|
|
||||||
let mut level = role.level;
|
|
||||||
for level_consume in levels_consume {
|
|
||||||
if level_consume.exp_count > total_exp {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
total_exp -= level_consume.exp_count;
|
|
||||||
level = level_consume.level;
|
|
||||||
}
|
|
||||||
response.level = level;
|
|
||||||
response.exp = total_exp;
|
|
||||||
|
|
||||||
// TODO is item_map the overflowing items or all items used? also should we sent more notifies?
|
|
||||||
response.error_code = ErrorCode::Success.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
// on_role_break_through_view_request
|
|
||||||
|
|
||||||
pub fn on_role_break_through_view_request(
|
|
||||||
player: &mut Player,
|
|
||||||
request: RoleBreakThroughViewRequest,
|
|
||||||
response: &mut RoleBreakThroughViewResponse,
|
|
||||||
) {
|
|
||||||
let role = player.role_list.get(&request.role_id);
|
|
||||||
let Some(role) = role else {
|
|
||||||
response.error_code = ErrorCode::NotValidRole.into();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO:
|
|
||||||
// if !condition {
|
|
||||||
// response.error_code = ErrorCode::ErrRoleConditionNotFind.into();
|
|
||||||
// response.is_condition_finish = false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
let role_breach_id = wicked_waifus_data::role_info_data::iter()
|
|
||||||
.find(|role| role.id == request.role_id)
|
|
||||||
.map(|role| role.breach_id)
|
|
||||||
.unwrap_or(request.role_id);
|
|
||||||
|
|
||||||
let condition = wicked_waifus_data::role_breach_data::iter()
|
|
||||||
.find(|role_breach_data| {
|
|
||||||
role_breach_data.breach_group_id == role_breach_id
|
|
||||||
&& role_breach_data.breach_level == role.breakthrough
|
|
||||||
})
|
|
||||||
.unwrap(); // TODO: handling
|
|
||||||
|
|
||||||
response.error_code = ErrorCode::Success.into();
|
|
||||||
response.level_limit = condition.max_level;
|
|
||||||
|
|
||||||
response.cost_list = condition
|
|
||||||
.breach_consume
|
|
||||||
.iter()
|
|
||||||
.map(|(&id, &count)| ArrayIntInt {
|
|
||||||
key: id,
|
|
||||||
value: count,
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
// TODO: un_lock_skill_id, reward_list, final_prop
|
|
||||||
response.is_condition_finish = true; // is this last??
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
use wicked_waifus_protocol::{
|
use wicked_waifus_protocol::{ErrorCode, SceneLoadingFinishRequest, SceneLoadingFinishResponse, SceneTraceRequest, SceneTraceResponse, UpdateSceneDateRequest, UpdateSceneDateResponse, AccessPathTimeServerConfigRequest, AccessPathTimeServerConfigResponse, PlayerHeadDataRequest, PlayerHeadDataResponse, UnlockRoleSkinListRequest, UnlockRoleSkinListResponse, JsPatchNotify};
|
||||||
AccessPathTimeServerConfigRequest, AccessPathTimeServerConfigResponse, ErrorCode,
|
|
||||||
JsPatchNotify, PlayerHeadDataRequest, PlayerHeadDataResponse, SceneLoadingFinishRequest,
|
|
||||||
SceneLoadingFinishResponse, SceneTraceRequest, SceneTraceResponse, UpdateSceneDateRequest,
|
|
||||||
UpdateSceneDateResponse,
|
|
||||||
};
|
|
||||||
|
|
||||||
const WATER_MASK: &str = include_str!("../../../scripts/watermask-disable.js");
|
//const WATER_MASK: &str = include_str!("../../../scripts/watermask-disable.js");
|
||||||
|
const WATER_MASK: &str = include_str!("../../../scripts/watermask-edit.js");
|
||||||
const UID_FIX: &str = include_str!("../../../scripts/uidfix.js");
|
const UID_FIX: &str = include_str!("../../../scripts/uidfix.js");
|
||||||
const CENSORSHIP_FIX: &str = include_str!("../../../scripts/censorshipfix.js");
|
const CENSORSHIP_FIX: &str = include_str!("../../../scripts/censorshipfix.js");
|
||||||
const DEBUG_DISABLE: &str = include_str!("../../../scripts/debug_disable.js");
|
const DEBUG_DISABLE: &str = include_str!("../../../scripts/debug_disable.js");
|
||||||
|
@ -70,3 +66,14 @@ pub fn on_player_head_data_request(
|
||||||
// TODO: port this from golang
|
// TODO: port this from golang
|
||||||
response.pi = vec![];
|
response.pi = vec![];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn on_unlock_role_skin_list_request(
|
||||||
|
_player: &Player,
|
||||||
|
_request: UnlockRoleSkinListRequest,
|
||||||
|
response: &mut UnlockRoleSkinListResponse,
|
||||||
|
) {
|
||||||
|
// TODO: port this from golang
|
||||||
|
response.role_skin_list = wicked_waifus_data::role_skin_data::iter()
|
||||||
|
.map(|data| data.id)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
}
|
|
@ -1,175 +0,0 @@
|
||||||
use crate::logic::components::{Equip, WeaponSkin};
|
|
||||||
use crate::logic::ecs::component::ComponentContainer;
|
|
||||||
use crate::logic::player::Player;
|
|
||||||
use crate::modify_component;
|
|
||||||
use wicked_waifus_protocol::{EntityEquipChangeNotify, EntityEquipSkinChangeNotify, EquipComponentPb, EquipTakeOnNotify, EquipTakeOnRequest, EquipTakeOnResponse, EquipWeaponSkinRequest, EquipWeaponSkinResponse, ErrorCode, LoadEquipData, SendEquipSkinRequest, SendEquipSkinResponse, WeaponSkinComponentPb, WeaponSkinDeleteNotify, WeaponSkinRequest, WeaponSkinResponse};
|
|
||||||
|
|
||||||
pub fn on_weapon_skin_request(
|
|
||||||
player: &Player,
|
|
||||||
_request: WeaponSkinRequest,
|
|
||||||
response: &mut WeaponSkinResponse,
|
|
||||||
) {
|
|
||||||
response.equip_list = player
|
|
||||||
.role_list
|
|
||||||
.values()
|
|
||||||
.filter(|role| role.weapon_skin_id != 0)
|
|
||||||
.map(|role| LoadEquipData {
|
|
||||||
role_id: role.role_id,
|
|
||||||
skin_id: role.weapon_skin_id,
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
response.error_code = ErrorCode::Success.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn on_equip_weapon_skin_request(
|
|
||||||
player: &mut Player,
|
|
||||||
request: EquipWeaponSkinRequest,
|
|
||||||
response: &mut EquipWeaponSkinResponse,
|
|
||||||
) {
|
|
||||||
let Some(equip_data) = request.data else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let role = player.role_list.get_mut(&equip_data.role_id);
|
|
||||||
let Some(role) = role else {
|
|
||||||
response.error_code = ErrorCode::NotValidRole.into();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Verify Id exist in bindata
|
|
||||||
let Some(skin_data) =
|
|
||||||
wicked_waifus_data::weapon_skin_data::iter().find(|data| data.id == equip_data.skin_id)
|
|
||||||
else {
|
|
||||||
response.error_code = ErrorCode::WeaponSkinDataErr.into();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Verify Skin is unlocked
|
|
||||||
if !player.unlocked_skins.weapon_skins.contains(&skin_data.id) {
|
|
||||||
response.error_code = ErrorCode::WeaponSkinUnLockErr.into();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
role.weapon_skin_id = equip_data.skin_id;
|
|
||||||
{
|
|
||||||
let world_ref = player.world.borrow();
|
|
||||||
let world = world_ref.get_world_entity();
|
|
||||||
let entity_id = world.get_entity_id(equip_data.role_id);
|
|
||||||
modify_component!(
|
|
||||||
world.get_entity_components(entity_id as i32),
|
|
||||||
WeaponSkin,
|
|
||||||
|skin_component: &mut WeaponSkin| {
|
|
||||||
skin_component.skin_id = equip_data.skin_id;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
player.notify(EntityEquipSkinChangeNotify {
|
|
||||||
entity_id,
|
|
||||||
weapon_skin_component_pb: Some(WeaponSkinComponentPb {
|
|
||||||
weapon_skin_id: equip_data.skin_id,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is the all list needed or only the new one??
|
|
||||||
response.data_list = player
|
|
||||||
.role_list
|
|
||||||
.values()
|
|
||||||
.filter(|role| role.weapon_skin_id != 0)
|
|
||||||
.map(|role| LoadEquipData {
|
|
||||||
role_id: role.role_id,
|
|
||||||
skin_id: role.weapon_skin_id,
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
response.error_code = ErrorCode::Success.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn on_send_equip_skin_request(
|
|
||||||
player: &mut Player,
|
|
||||||
request: SendEquipSkinRequest,
|
|
||||||
response: &mut SendEquipSkinResponse,
|
|
||||||
) {
|
|
||||||
let role = player.role_list.get_mut(&request.role_id);
|
|
||||||
let Some(role) = role else {
|
|
||||||
response.error_code = ErrorCode::NotValidRole.into();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let old_skin_id = role.weapon_skin_id;
|
|
||||||
role.weapon_skin_id = 0;
|
|
||||||
{
|
|
||||||
let world_ref = player.world.borrow();
|
|
||||||
let world = world_ref.get_world_entity();
|
|
||||||
let entity_id = world.get_entity_id(request.role_id);
|
|
||||||
modify_component!(
|
|
||||||
world.get_entity_components(entity_id as i32),
|
|
||||||
WeaponSkin,
|
|
||||||
|skin_component: &mut WeaponSkin| {
|
|
||||||
skin_component.skin_id = 0;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
player.notify(EntityEquipSkinChangeNotify {
|
|
||||||
entity_id,
|
|
||||||
weapon_skin_component_pb: Some(WeaponSkinComponentPb {
|
|
||||||
weapon_skin_id: 0,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
player.notify(WeaponSkinDeleteNotify {
|
|
||||||
role_id: request.role_id,
|
|
||||||
skin_id: old_skin_id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
response.error_code = ErrorCode::Success.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn on_equip_take_on_request(
|
|
||||||
player: &mut Player,
|
|
||||||
request: EquipTakeOnRequest,
|
|
||||||
response: &mut EquipTakeOnResponse,
|
|
||||||
) {
|
|
||||||
let Some(equip_data) = request.data else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: Add sanity checks(add from another role, a.k.a.: switch from roles)
|
|
||||||
player.notify(EquipTakeOnNotify { data_list: vec![equip_data] });
|
|
||||||
|
|
||||||
let role = player.role_list.get_mut(&equip_data.role_id);
|
|
||||||
let Some(role) = role else {
|
|
||||||
response.error_code = ErrorCode::NotValidRole.into();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let Some((id, breach)) = player.inventory.get_weapon_equip_info(equip_data.equip_inc_id) else {
|
|
||||||
response.error_code = ErrorCode::ErrItemNotFound.into();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
role.equip_weapon = id;
|
|
||||||
|
|
||||||
// TODO: Change attributes based on weapon (PbRolePropsNotify + buffs + CombatNotifyAttributeChangedNotify)
|
|
||||||
|
|
||||||
{
|
|
||||||
// TODO: remove from old one if in scene in case of weapon switch
|
|
||||||
let world_ref = player.world.borrow();
|
|
||||||
let world = world_ref.get_world_entity();
|
|
||||||
let entity_id = world.get_entity_id(equip_data.role_id);
|
|
||||||
modify_component!(
|
|
||||||
world.get_entity_components(entity_id as i32),
|
|
||||||
Equip,
|
|
||||||
|equip_component: &mut Equip| {
|
|
||||||
equip_component.weapon_id = id;
|
|
||||||
equip_component.weapon_breach_level = breach;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
player.notify(EntityEquipChangeNotify {
|
|
||||||
entity_id,
|
|
||||||
equip_component: Some(EquipComponentPb {
|
|
||||||
weapon_id: id,
|
|
||||||
weapon_breach_level: breach,
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// TODO: Should we return all of them??
|
|
||||||
response.data_list = vec![equip_data];
|
|
||||||
response.error_code = ErrorCode::Success.into();
|
|
||||||
}
|
|
|
@ -12,6 +12,10 @@ pub struct ExploreTools {
|
||||||
pub roulette: Roulette,
|
pub roulette: Roulette,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ADDITIONAL_ROULETTE: &[i32] = &[
|
||||||
|
1015 // flight
|
||||||
|
];
|
||||||
|
|
||||||
impl ExploreTools {
|
impl ExploreTools {
|
||||||
pub fn build_save_data(&self) -> PlayerExploreToolsData {
|
pub fn build_save_data(&self) -> PlayerExploreToolsData {
|
||||||
PlayerExploreToolsData {
|
PlayerExploreToolsData {
|
||||||
|
@ -63,6 +67,16 @@ impl ExploreTools {
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.for_each(|(i, e)| roulette[i] = e.phantom_skill_id);
|
.for_each(|(i, e)| roulette[i] = e.phantom_skill_id);
|
||||||
|
|
||||||
|
let mut count = 2;
|
||||||
|
|
||||||
|
explore_tools_data::iter()
|
||||||
|
.for_each(|e| {
|
||||||
|
if ADDITIONAL_ROULETTE.contains(&e.phantom_skill_id) {
|
||||||
|
count += 1;
|
||||||
|
roulette[count] = e.phantom_skill_id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
roulette
|
roulette
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,26 +9,27 @@ use wicked_waifus_protocol::message::Message;
|
||||||
use wicked_waifus_protocol::player_attr::Value;
|
use wicked_waifus_protocol::player_attr::Value;
|
||||||
use wicked_waifus_protocol::{
|
use wicked_waifus_protocol::{
|
||||||
AdventreTask, AdventureManualData, AdventureUpdateNotify, AdviceSettingNotify, BuffItemNotify,
|
AdventreTask, AdventureManualData, AdventureUpdateNotify, AdviceSettingNotify, BuffItemNotify,
|
||||||
ControlInfoNotify, EEntityType, ERemoveEntityType, EnergyInfo, EnergyUpdateNotify,
|
ControlInfoNotify, ERemoveEntityType, EnergyInfo, EnergyUpdateNotify,
|
||||||
EntityAddNotify, EntityConfigType, EntityPb, EntityRemoveInfo, EntityRemoveNotify, EntityState,
|
EntityRemoveInfo, EntityRemoveNotify,
|
||||||
FavorItem, FightFormationNotifyInfo, FightRoleInfo, FightRoleInfos, FlyEquipAddNotify,
|
FavorItem, FightFormationNotifyInfo, FightRoleInfo, FightRoleInfos, FormationRoleInfo,
|
||||||
FlySkinEquipData, GroupFormation, HostTeleportUnlockNotify, InstDataNotify, ItemPkgOpenNotify,
|
GroupFormation, HostTeleportUnlockNotify, InstDataNotify, ItemPkgOpenNotify,
|
||||||
LevelPlayInfoNotify, LivingStatus, MailInfosNotify, MonthCardDailyRewardNotify,
|
LevelPlayInfoNotify, LivingStatus, MailInfosNotify,
|
||||||
MoonChasingTargetGetCountNotify, MoonChasingTrackMoonHandbookRewardNotify,
|
MonthCardDailyRewardNotify, MoonChasingTargetGetCountNotify,
|
||||||
NormalItemUpdateNotify, PassiveSkillNotify, PbGetRoleListNotify, PlayerAttr, PlayerAttrKey,
|
MoonChasingTrackMoonHandbookRewardNotify, NormalItemUpdateNotify, PassiveSkillNotify,
|
||||||
PlayerAttrNotify, PlayerAttrType, PlayerFightFormations, PlayerVarNotify, ProtocolUnit,
|
PbGetRoleListNotify, PlayerAttr, PlayerAttrKey, PlayerAttrNotify, PlayerAttrType,
|
||||||
PushContextIdNotify, PushDataCompleteNotify, RoguelikeCurrencyNotify, RoleChangeUnlockNotify,
|
PlayerFightFormations, PlayerVarNotify, ProtocolUnit, PushContextIdNotify,
|
||||||
RoleFavor, RoleFavorListNotify, RoleFlyEquipNotify, RoleMotion, RoleMotionListNotify,
|
PushDataCompleteNotify, RoguelikeCurrencyNotify, RoleChangeUnlockNotify, RoleFavor,
|
||||||
SettingNotify, TeleportUpdateNotify, UnlockSkinDataNotify, UpdateFormationNotify,
|
RoleFavorListNotify, RoleMotion, RoleMotionListNotify, SettingNotify, TeleportUpdateNotify,
|
||||||
UpdateGroupFormationNotify,
|
UpdateFormationNotify, UpdateGroupFormationNotify,
|
||||||
};
|
};
|
||||||
use wicked_waifus_protocol_internal::{PlayerBasicData, PlayerRoleData, PlayerSaveData};
|
use wicked_waifus_protocol_internal::{PlayerBasicData, PlayerRoleData, PlayerSaveData};
|
||||||
|
|
||||||
|
use super::ecs::component::ComponentContainer;
|
||||||
|
use super::utils::world_util::add_player_entities;
|
||||||
use super::{
|
use super::{
|
||||||
ecs::world::World,
|
ecs::world::World,
|
||||||
role::{Role, RoleFormation},
|
role::{Role, RoleFormation},
|
||||||
};
|
};
|
||||||
use crate::logic::components::RoleSkin;
|
|
||||||
use crate::logic::ecs::world::WorldEntity;
|
use crate::logic::ecs::world::WorldEntity;
|
||||||
use crate::logic::player::basic_info::PlayerBasicInfo;
|
use crate::logic::player::basic_info::PlayerBasicInfo;
|
||||||
use crate::logic::player::explore_tools::ExploreTools;
|
use crate::logic::player::explore_tools::ExploreTools;
|
||||||
|
@ -46,17 +47,9 @@ use crate::logic::player::player_mc_element::PlayerMcElement;
|
||||||
use crate::logic::player::player_month_card::PlayerMonthCard;
|
use crate::logic::player::player_month_card::PlayerMonthCard;
|
||||||
use crate::logic::player::player_teleports::{PlayerTeleport, PlayerTeleports};
|
use crate::logic::player::player_teleports::{PlayerTeleport, PlayerTeleports};
|
||||||
use crate::logic::player::player_tutorials::{PlayerTutorial, PlayerTutorials};
|
use crate::logic::player::player_tutorials::{PlayerTutorial, PlayerTutorials};
|
||||||
use crate::logic::player::Element::Spectro;
|
|
||||||
use crate::logic::{
|
|
||||||
components::{
|
|
||||||
Attribute, EntityConfig, Equip, FightBuff, Movement, OwnerPlayer, ParaglidingSkin,
|
|
||||||
PlayerOwnedEntityMarker, Position, SoarWingSkin, Visibility, VisionSkill, WeaponSkin,
|
|
||||||
},
|
|
||||||
ecs::component::ComponentContainer,
|
|
||||||
};
|
|
||||||
use crate::session::Session;
|
use crate::session::Session;
|
||||||
use crate::{config, create_player_entity_pb};
|
use crate::{config, query_components};
|
||||||
use crate::logic::player::player_unlocked_skins::PlayerUnlockedSkins;
|
use crate::logic::player::Element::Spectro;
|
||||||
|
|
||||||
mod basic_info;
|
mod basic_info;
|
||||||
mod explore_tools;
|
mod explore_tools;
|
||||||
|
@ -73,7 +66,6 @@ mod player_mc_element;
|
||||||
mod player_month_card;
|
mod player_month_card;
|
||||||
mod player_teleports;
|
mod player_teleports;
|
||||||
mod player_tutorials;
|
mod player_tutorials;
|
||||||
mod player_unlocked_skins;
|
|
||||||
|
|
||||||
pub struct Player {
|
pub struct Player {
|
||||||
session: Option<Arc<Session>>,
|
session: Option<Arc<Session>>,
|
||||||
|
@ -95,7 +87,6 @@ pub struct Player {
|
||||||
pub map_trace: PlayerMapTrace,
|
pub map_trace: PlayerMapTrace,
|
||||||
pub month_card: PlayerMonthCard,
|
pub month_card: PlayerMonthCard,
|
||||||
pub mc_element: PlayerMcElement,
|
pub mc_element: PlayerMcElement,
|
||||||
pub unlocked_skins: PlayerUnlockedSkins,
|
|
||||||
// Runtime
|
// Runtime
|
||||||
pub world: Rc<RefCell<World>>,
|
pub world: Rc<RefCell<World>>,
|
||||||
pub last_save_time: u64,
|
pub last_save_time: u64,
|
||||||
|
@ -126,10 +117,6 @@ impl Player {
|
||||||
self.notify(self.explore_tools.build_roulette_update_notify());
|
self.notify(self.explore_tools.build_roulette_update_notify());
|
||||||
self.notify(self.build_role_favor_list_notify());
|
self.notify(self.build_role_favor_list_notify());
|
||||||
self.notify(self.func.build_func_open_notify());
|
self.notify(self.func.build_func_open_notify());
|
||||||
self.notify(self.build_weapon_skin_notify());
|
|
||||||
self.notify(self.build_fly_equip_notify());
|
|
||||||
self.notify(self.build_role_fly_equip_notify());
|
|
||||||
|
|
||||||
self.notify(InstDataNotify {
|
self.notify(InstDataNotify {
|
||||||
enter_infos: vec![], // TODO: No effect in normal world, to implement for dungeon::logic()
|
enter_infos: vec![], // TODO: No effect in normal world, to implement for dungeon::logic()
|
||||||
});
|
});
|
||||||
|
@ -218,11 +205,6 @@ impl Player {
|
||||||
self.role_list.insert(role_id, Role::new(role_id));
|
self.role_list.insert(role_id, Role::new(role_id));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for role in self.role_list.values() {
|
|
||||||
self.inventory
|
|
||||||
.add_weapon(role.equip_weapon, 0, 1, 0, 0, 0, role.role_id)
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
self.formation_list.insert(1, RoleFormation::default());
|
self.formation_list.insert(1, RoleFormation::default());
|
||||||
self.cur_formation_id = 1;
|
self.cur_formation_id = 1;
|
||||||
|
@ -275,7 +257,7 @@ impl Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !rf.role_ids.contains(&rf.cur_role) {
|
if !rf.role_ids.contains(&rf.cur_role) {
|
||||||
rf.cur_role = *rf.role_ids.iter().nth(0).unwrap();
|
rf.cur_role = *rf.role_ids.first().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -316,9 +298,7 @@ impl Player {
|
||||||
pub fn build_role_favor_list_notify(&self) -> RoleFavorListNotify {
|
pub fn build_role_favor_list_notify(&self) -> RoleFavorListNotify {
|
||||||
RoleFavorListNotify {
|
RoleFavorListNotify {
|
||||||
favor_list: self
|
favor_list: self
|
||||||
.role_list
|
.role_list.values().map(|role| RoleFavor {
|
||||||
.values()
|
|
||||||
.map(|role| RoleFavor {
|
|
||||||
role_id: role.role_id,
|
role_id: role.role_id,
|
||||||
level: role.favor_level,
|
level: role.favor_level,
|
||||||
exp: role.favor_exp,
|
exp: role.favor_exp,
|
||||||
|
@ -350,73 +330,10 @@ impl Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_weapon_skin_notify(&self) -> UnlockSkinDataNotify {
|
|
||||||
UnlockSkinDataNotify {
|
|
||||||
phantom_skin_list: self.unlocked_skins.weapon_skins.iter().cloned().collect(),
|
|
||||||
is_login: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build_fly_equip_notify(&self) -> FlyEquipAddNotify {
|
|
||||||
FlyEquipAddNotify {
|
|
||||||
unlock_fly_skin_ids: self
|
|
||||||
.unlocked_skins
|
|
||||||
.fly_skins
|
|
||||||
.iter()
|
|
||||||
.chain(&self.unlocked_skins.wing_skins)
|
|
||||||
.cloned()
|
|
||||||
.collect(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build_role_fly_equip_notify(&self) -> RoleFlyEquipNotify {
|
|
||||||
let merged: Vec<_> = self
|
|
||||||
.unlocked_skins
|
|
||||||
.fly_skins
|
|
||||||
.iter()
|
|
||||||
.chain(&self.unlocked_skins.wing_skins)
|
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let mut equipped_skins: HashMap<i32, Vec<i32>> = HashMap::new();
|
|
||||||
for role in self.role_list.values() {
|
|
||||||
if role.fly_skin_id != 0 {
|
|
||||||
equipped_skins
|
|
||||||
.entry(role.fly_skin_id)
|
|
||||||
.or_default()
|
|
||||||
.push(role.role_id);
|
|
||||||
}
|
|
||||||
if role.wing_skin_id != 0 {
|
|
||||||
equipped_skins
|
|
||||||
.entry(role.wing_skin_id)
|
|
||||||
.or_default()
|
|
||||||
.push(role.role_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RoleFlyEquipNotify {
|
|
||||||
fly_skin_equip_data: merged
|
|
||||||
.iter()
|
|
||||||
.map(|&skin| match equipped_skins.get(&skin) {
|
|
||||||
Some(role_list) => FlySkinEquipData {
|
|
||||||
role_ids: role_list.to_vec(),
|
|
||||||
skin_id: skin,
|
|
||||||
},
|
|
||||||
None => FlySkinEquipData {
|
|
||||||
role_ids: vec![],
|
|
||||||
skin_id: skin,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build_motion_list_notify(&self) -> RoleMotionListNotify {
|
pub fn build_motion_list_notify(&self) -> RoleMotionListNotify {
|
||||||
RoleMotionListNotify {
|
RoleMotionListNotify {
|
||||||
motion_list: self
|
motion_list: self
|
||||||
.role_list
|
.role_list.values().map(|role| {
|
||||||
.values()
|
|
||||||
.map(|role| {
|
|
||||||
RoleMotion {
|
RoleMotion {
|
||||||
role_id: role.role_id,
|
role_id: role.role_id,
|
||||||
motion_ids: motion_data::iter()
|
motion_ids: motion_data::iter()
|
||||||
|
@ -435,16 +352,8 @@ impl Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_player_entity_add_notify(&self, role_list: Vec<Role>, world: &mut WorldEntity) -> EntityAddNotify {
|
pub fn build_player_entity_add_notify(&self, world: &mut WorldEntity) {
|
||||||
create_player_entity_pb!(
|
add_player_entities(self, self.formation_list.get(&self.cur_formation_id).unwrap(), Some(world))
|
||||||
role_list,
|
|
||||||
self.basic_info.cur_map_id,
|
|
||||||
self,
|
|
||||||
self.basic_info.id,
|
|
||||||
self.location.position.clone(),
|
|
||||||
self.explore_tools,
|
|
||||||
world
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_player_entity_remove_notify(
|
pub fn build_player_entity_remove_notify(
|
||||||
|
@ -478,10 +387,14 @@ impl Player {
|
||||||
fight_role_infos: cur_formation
|
fight_role_infos: cur_formation
|
||||||
.role_ids
|
.role_ids
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&role_id| FightRoleInfo {
|
.map(|&role_id| {
|
||||||
|
let entity_id = world.get_entity_id(role_id);
|
||||||
|
let _role_skin = query_components!(world, entity_id, RoleSkin).0.unwrap();
|
||||||
|
FightRoleInfo {
|
||||||
role_id,
|
role_id,
|
||||||
entity_id: world.get_entity_id(role_id),
|
entity_id: world.get_entity_id(role_id),
|
||||||
on_stage_without_control: false,
|
on_stage_without_control: false,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
cur_role: cur_formation.cur_role,
|
cur_role: cur_formation.cur_role,
|
||||||
|
@ -518,7 +431,14 @@ impl Player {
|
||||||
tracing::warn!("Role {} not found in use role list", role_id);
|
tracing::warn!("Role {} not found in use role list", role_id);
|
||||||
return Default::default();
|
return Default::default();
|
||||||
}
|
}
|
||||||
role_map.get(role_id).unwrap().to_formation_protobuf()
|
let role = *role_map.get(role_id).unwrap();
|
||||||
|
FormationRoleInfo {
|
||||||
|
role_id: role.role_id,
|
||||||
|
max_hp: 0,
|
||||||
|
cur_hp: 0,
|
||||||
|
level: role.level,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
is_current: formation.is_current,
|
is_current: formation.is_current,
|
||||||
|
@ -576,7 +496,7 @@ impl Player {
|
||||||
}],
|
}],
|
||||||
});
|
});
|
||||||
self.notify(NormalItemUpdateNotify {
|
self.notify(NormalItemUpdateNotify {
|
||||||
normal_item_list: self.inventory.to_normal_item_list_filtered(&[3]),
|
normal_item_list: self.inventory.to_normal_item_list_filtered(vec![3]),
|
||||||
no_tips: false,
|
no_tips: false,
|
||||||
});
|
});
|
||||||
self.notify(MonthCardDailyRewardNotify {
|
self.notify(MonthCardDailyRewardNotify {
|
||||||
|
@ -658,10 +578,6 @@ impl Player {
|
||||||
.mc_element
|
.mc_element
|
||||||
.map(PlayerMcElement::load_from_save)
|
.map(PlayerMcElement::load_from_save)
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
unlocked_skins: save_data
|
|
||||||
.unlocked_skins
|
|
||||||
.map(PlayerUnlockedSkins::load_from_save)
|
|
||||||
.unwrap_or_default(),
|
|
||||||
world: Rc::new(RefCell::new(World::new())),
|
world: Rc::new(RefCell::new(World::new())),
|
||||||
last_save_time: time_util::unix_timestamp(),
|
last_save_time: time_util::unix_timestamp(),
|
||||||
quadrant_id: 0,
|
quadrant_id: 0,
|
||||||
|
@ -673,9 +589,7 @@ impl Player {
|
||||||
basic_data: Some(self.basic_info.build_save_data()),
|
basic_data: Some(self.basic_info.build_save_data()),
|
||||||
role_data: Some(PlayerRoleData {
|
role_data: Some(PlayerRoleData {
|
||||||
role_list: self
|
role_list: self
|
||||||
.role_list
|
.role_list.values().map(|role| role.build_save_data())
|
||||||
.iter()
|
|
||||||
.map(|(_, role)| role.build_save_data())
|
|
||||||
.collect(),
|
.collect(),
|
||||||
role_formation_list: self
|
role_formation_list: self
|
||||||
.formation_list
|
.formation_list
|
||||||
|
@ -697,7 +611,6 @@ impl Player {
|
||||||
map_trace: Some(self.map_trace.build_save_data()),
|
map_trace: Some(self.map_trace.build_save_data()),
|
||||||
month_card: Some(self.month_card.build_save_data()),
|
month_card: Some(self.month_card.build_save_data()),
|
||||||
mc_element: Some(self.mc_element.build_save_data()),
|
mc_element: Some(self.mc_element.build_save_data()),
|
||||||
unlocked_skins: Some(self.unlocked_skins.build_save_data()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -706,11 +619,10 @@ impl Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_role_list_notify(&self) -> PbGetRoleListNotify {
|
pub fn build_role_list_notify(&self) -> PbGetRoleListNotify {
|
||||||
|
// TODO: There is a bug we are investigating with several resonators, this is a workaround
|
||||||
PbGetRoleListNotify {
|
PbGetRoleListNotify {
|
||||||
role_list: self
|
role_list: self
|
||||||
.role_list
|
.role_list.values().map(|role| role.to_protobuf())
|
||||||
.values()
|
|
||||||
.map(|role| role.to_protobuf())
|
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::atomic::AtomicI32;
|
|
||||||
use wicked_waifus_protocol::{ArrayIntInt, NormalItem, WeaponItem};
|
|
||||||
|
|
||||||
use crate::config;
|
use wicked_waifus_protocol::NormalItem;
|
||||||
use crate::logic::utils::seq_utils::{SequenceGenerator, Sequencer};
|
|
||||||
use wicked_waifus_protocol_internal::{PlayerInventoryData, PlayerInventoryWeaponData};
|
use wicked_waifus_protocol_internal::PlayerInventoryData;
|
||||||
|
|
||||||
pub struct PlayerInventory {
|
pub struct PlayerInventory {
|
||||||
items: HashMap<i32, i32>,
|
items: HashMap<i32, i32>,
|
||||||
weapons_seq: SequenceGenerator<i32, AtomicI32>,
|
|
||||||
weapons: HashMap<i32, PlayerInventoryWeaponData>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ItemUsage {
|
pub struct ItemUsage {
|
||||||
|
@ -37,16 +33,13 @@ impl PlayerInventory {
|
||||||
|
|
||||||
pub fn load_from_save(data: PlayerInventoryData) -> Self {
|
pub fn load_from_save(data: PlayerInventoryData) -> Self {
|
||||||
Self {
|
Self {
|
||||||
weapons_seq: SequenceGenerator::from_data(&data.weapons),
|
|
||||||
items: data.items.clone(),
|
items: data.items.clone(),
|
||||||
weapons: data.weapons.clone(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_save_data(&self) -> PlayerInventoryData {
|
pub fn build_save_data(&self) -> PlayerInventoryData {
|
||||||
PlayerInventoryData {
|
PlayerInventoryData {
|
||||||
items: self.items.clone(),
|
items: self.items.clone(),
|
||||||
weapons: self.weapons.clone(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,19 +52,10 @@ impl PlayerInventory {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn consume_item(&mut self, id: i32, quantity: i32) -> Result<i32, InventoryError> {
|
pub fn consume_item(&mut self, id: i32, quantity: i32) -> Result<i32, InventoryError> {
|
||||||
Ok(*self
|
Ok(*self.consume_items(&[ItemUsage { id, quantity: -quantity }])?.get(&id).unwrap())
|
||||||
.consume_items(&[ItemUsage {
|
|
||||||
id,
|
|
||||||
quantity: -quantity,
|
|
||||||
}])?
|
|
||||||
.get(&id)
|
|
||||||
.unwrap())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn consume_items(
|
pub fn consume_items(&mut self, usages: &[ItemUsage]) -> Result<HashMap<i32, i32>, InventoryError> {
|
||||||
&mut self,
|
|
||||||
usages: &[ItemUsage],
|
|
||||||
) -> Result<HashMap<i32, i32>, InventoryError> {
|
|
||||||
if !self.has_enough_items(usages) {
|
if !self.has_enough_items(usages) {
|
||||||
return Err(InventoryError::ItemsNotEnough());
|
return Err(InventoryError::ItemsNotEnough());
|
||||||
}
|
}
|
||||||
|
@ -84,11 +68,6 @@ impl PlayerInventory {
|
||||||
self.items.get(&Self::UNION_EXP_ID).copied().unwrap_or(0)
|
self.items.get(&Self::UNION_EXP_ID).copied().unwrap_or(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn add_shell_credits(&mut self, count: i32) -> i32 {
|
|
||||||
self.add_internal(Self::SHELL_CREDIT_ID, count)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn get_shell_credits(&self) -> i32 {
|
pub fn get_shell_credits(&self) -> i32 {
|
||||||
self.items.get(&Self::SHELL_CREDIT_ID).copied().unwrap_or(0)
|
self.items.get(&Self::SHELL_CREDIT_ID).copied().unwrap_or(0)
|
||||||
|
@ -118,113 +97,35 @@ impl PlayerInventory {
|
||||||
// TODO: Check if this is item or not
|
// TODO: Check if this is item or not
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn get_waveplate_crystal(&self) -> i32 {
|
pub fn get_waveplate_crystal(&self) -> i32 {
|
||||||
self.items
|
self.items.get(&Self::WAVEPLATE_CRYSTAL_ID).copied().unwrap_or(0)
|
||||||
.get(&Self::WAVEPLATE_CRYSTAL_ID)
|
|
||||||
.copied()
|
|
||||||
.unwrap_or(0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_normal_item_list(&self) -> Vec<NormalItem> {
|
pub fn to_normal_item_list(&self) -> Vec<NormalItem> {
|
||||||
self.items
|
self.items.iter()
|
||||||
.iter()
|
|
||||||
.filter(|(&id, _)| Self::WAVEPLATE_ID != id && Self::WAVEPLATE_CRYSTAL_ID != id)
|
.filter(|(&id, _)| Self::WAVEPLATE_ID != id && Self::WAVEPLATE_CRYSTAL_ID != id)
|
||||||
// TODO: Implement expiration
|
// TODO: Implement expiration
|
||||||
.map(|(&id, &count)| NormalItem {
|
.map(|(&id, &count)| NormalItem { id, count, expire_time: 0 })
|
||||||
id,
|
|
||||||
count,
|
|
||||||
expire_time: 0,
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_normal_item_list_filtered(&self, ids: &[i32]) -> Vec<NormalItem> {
|
pub fn to_normal_item_list_filtered(&self, ids: Vec<i32>) -> Vec<NormalItem> {
|
||||||
self.items
|
self.items.iter()
|
||||||
.iter()
|
|
||||||
.filter(|(&id, _)| ids.contains(&id))
|
.filter(|(&id, _)| ids.contains(&id))
|
||||||
// TODO: Implement expiration
|
// TODO: Implement expiration
|
||||||
.map(|(&id, &count)| NormalItem {
|
.map(|(&id, &count)| NormalItem { id, count, expire_time: 0 })
|
||||||
id,
|
|
||||||
count,
|
|
||||||
expire_time: 0,
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_array_int_int_filtered(&self, ids: &[i32]) -> Vec<ArrayIntInt> {
|
|
||||||
ids.iter()
|
|
||||||
.map(|id| ArrayIntInt {
|
|
||||||
key: *id,
|
|
||||||
value: self.items.get(id).copied().unwrap_or(0),
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_weapon(
|
|
||||||
&mut self,
|
|
||||||
id: i32,
|
|
||||||
func: i32,
|
|
||||||
level: i32,
|
|
||||||
exp: i32,
|
|
||||||
breach: i32,
|
|
||||||
reson: i32,
|
|
||||||
role: i32,
|
|
||||||
) -> Result<i32, InventoryError> {
|
|
||||||
let inc_id = self.weapons_seq.take_id();
|
|
||||||
self.weapons.insert(
|
|
||||||
inc_id,
|
|
||||||
PlayerInventoryWeaponData {
|
|
||||||
id,
|
|
||||||
func_value: func,
|
|
||||||
level,
|
|
||||||
exp,
|
|
||||||
breach,
|
|
||||||
reson_level: reson,
|
|
||||||
role_id: role,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
Ok(inc_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn remove_weapon(&mut self, id: i32) {
|
|
||||||
self.weapons.remove(&id);
|
|
||||||
self.weapons_seq.give_id(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_weapon_item_list(&self) -> Vec<WeaponItem> {
|
|
||||||
self.weapons
|
|
||||||
.iter()
|
|
||||||
.map(|(&inc_id, data)| WeaponItem {
|
|
||||||
id: data.id,
|
|
||||||
incr_id: inc_id,
|
|
||||||
func_value: data.func_value,
|
|
||||||
weapon_level: data.level,
|
|
||||||
weapon_exp: data.exp,
|
|
||||||
weapon_breach: data.breach,
|
|
||||||
weapon_reson_level: data.reson_level,
|
|
||||||
role_id: data.role_id,
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_weapon_equip_info(&self, inc_id: i32) -> Option<(i32, i32)> {
|
|
||||||
self.weapons
|
|
||||||
.get(&inc_id)
|
|
||||||
.map(|weapon_data| (weapon_data.id, weapon_data.breach))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn add_internal(&mut self, id: i32, quantity: i32) -> i32 {
|
fn add_internal(&mut self, id: i32, quantity: i32) -> i32 {
|
||||||
*self
|
*self.items.entry(id)
|
||||||
.items
|
|
||||||
.entry(id)
|
|
||||||
.and_modify(|count| *count += quantity)
|
.and_modify(|count| *count += quantity)
|
||||||
.or_insert(quantity)
|
.or_insert(quantity)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn add_many_internal(&mut self, usages: &[ItemUsage]) -> HashMap<i32, i32> {
|
fn add_many_internal(&mut self, usages: &[ItemUsage]) -> HashMap<i32, i32> {
|
||||||
usages
|
usages.iter()
|
||||||
.iter()
|
|
||||||
.filter(|usage| usage.quantity != 0)
|
.filter(|usage| usage.quantity != 0)
|
||||||
.map(|delta| (delta.id, self.add_internal(delta.id, delta.quantity)))
|
.map(|delta| (delta.id, self.add_internal(delta.id, delta.quantity)))
|
||||||
.collect::<HashMap<_, _>>()
|
.collect::<HashMap<_, _>>()
|
||||||
|
@ -237,80 +138,17 @@ impl PlayerInventory {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn has_enough_items(&self, items_delta: &[ItemUsage]) -> bool {
|
fn has_enough_items(&self, items_delta: &[ItemUsage]) -> bool {
|
||||||
items_delta
|
items_delta.iter()
|
||||||
.iter()
|
.fold(true, |is_enough, delta| {
|
||||||
.all(|delta| self.has_enough_item(delta.id, -delta.quantity))
|
is_enough && self.has_enough_item(delta.id, -delta.quantity)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PlayerInventory {
|
impl Default for PlayerInventory {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let mut weapons_seq = SequenceGenerator::new();
|
|
||||||
let default_unlocks = &config::get_config().default_unlocks;
|
|
||||||
let weapons: HashMap<i32, PlayerInventoryWeaponData> =
|
|
||||||
match default_unlocks.unlock_all_weapons {
|
|
||||||
true => wicked_waifus_data::weapon_conf_data::iter()
|
|
||||||
.map(|data| {
|
|
||||||
let (level, breach) = if default_unlocks.unlock_all_weapons_max_level {
|
|
||||||
(
|
|
||||||
wicked_waifus_data::weapon_level_data::iter()
|
|
||||||
.filter(|level_data| level_data.level_id == data.level_id)
|
|
||||||
.map(|level_data| level_data.level)
|
|
||||||
.max()
|
|
||||||
.unwrap_or(1),
|
|
||||||
wicked_waifus_data::weapon_breach_data::iter()
|
|
||||||
.filter(|level_data| level_data.breach_id == data.breach_id)
|
|
||||||
.map(|level_data| level_data.level)
|
|
||||||
.max()
|
|
||||||
.unwrap_or(0),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
(
|
|
||||||
wicked_waifus_data::weapon_level_data::iter()
|
|
||||||
.filter(|level_data| level_data.level_id == data.level_id)
|
|
||||||
.map(|level_data| level_data.level)
|
|
||||||
.min()
|
|
||||||
.unwrap_or(1),
|
|
||||||
wicked_waifus_data::weapon_breach_data::iter()
|
|
||||||
.filter(|level_data| level_data.breach_id == data.breach_id)
|
|
||||||
.map(|level_data| level_data.level)
|
|
||||||
.min()
|
|
||||||
.unwrap_or(0),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
let reson_level = if default_unlocks.unlock_all_weapons_all_reson {
|
|
||||||
wicked_waifus_data::weapon_reson_data::iter()
|
|
||||||
.filter(|level_data| level_data.reson_id == data.reson_id)
|
|
||||||
.map(|level_data| level_data.level)
|
|
||||||
.max()
|
|
||||||
.unwrap_or(0)
|
|
||||||
} else {
|
|
||||||
wicked_waifus_data::weapon_reson_data::iter()
|
|
||||||
.filter(|level_data| level_data.reson_id == data.reson_id)
|
|
||||||
.map(|level_data| level_data.level)
|
|
||||||
.min()
|
|
||||||
.unwrap_or(0)
|
|
||||||
};
|
|
||||||
(
|
|
||||||
weapons_seq.take_id(),
|
|
||||||
PlayerInventoryWeaponData {
|
|
||||||
id: data.item_id,
|
|
||||||
func_value: 0,
|
|
||||||
level,
|
|
||||||
exp: 0,
|
|
||||||
breach,
|
|
||||||
reson_level,
|
|
||||||
role_id: 0,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect::<HashMap<_, _>>(),
|
|
||||||
false => Default::default(),
|
|
||||||
};
|
|
||||||
Self {
|
Self {
|
||||||
items: HashMap::new(),
|
items: HashMap::new(),
|
||||||
weapons_seq,
|
|
||||||
weapons,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,72 +0,0 @@
|
||||||
use crate::config;
|
|
||||||
use std::collections::HashSet;
|
|
||||||
use wicked_waifus_protocol_internal::PlayerUnlockedSkinsData;
|
|
||||||
|
|
||||||
pub struct PlayerUnlockedSkins {
|
|
||||||
pub role_skins: HashSet<i32>,
|
|
||||||
pub weapon_skins: HashSet<i32>,
|
|
||||||
pub fly_skins: HashSet<i32>,
|
|
||||||
pub wing_skins: HashSet<i32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PlayerUnlockedSkins {
|
|
||||||
pub fn load_from_save(data: PlayerUnlockedSkinsData) -> Self {
|
|
||||||
Self {
|
|
||||||
role_skins: data.role_skins.iter().cloned().collect(),
|
|
||||||
weapon_skins: data.weapon_skins.iter().cloned().collect(),
|
|
||||||
fly_skins: data.fly_skins.iter().cloned().collect(),
|
|
||||||
wing_skins: data.wing_skins.iter().cloned().collect(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build_save_data(&self) -> PlayerUnlockedSkinsData {
|
|
||||||
PlayerUnlockedSkinsData {
|
|
||||||
role_skins: self.role_skins.iter().cloned().collect(),
|
|
||||||
weapon_skins: self.weapon_skins.iter().cloned().collect(),
|
|
||||||
fly_skins: self.fly_skins.iter().cloned().collect(),
|
|
||||||
wing_skins: self.wing_skins.iter().cloned().collect(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for PlayerUnlockedSkins {
|
|
||||||
fn default() -> Self {
|
|
||||||
let unlocks = &config::get_config().default_unlocks;
|
|
||||||
|
|
||||||
Self {
|
|
||||||
role_skins: if unlocks.unlock_all_role_skins {
|
|
||||||
wicked_waifus_data::role_skin_data::iter()
|
|
||||||
.map(|skin| skin.id)
|
|
||||||
.collect()
|
|
||||||
} else {
|
|
||||||
HashSet::new()
|
|
||||||
},
|
|
||||||
|
|
||||||
weapon_skins: if unlocks.unlock_all_weapon_skins {
|
|
||||||
wicked_waifus_data::weapon_skin_data::iter()
|
|
||||||
.map(|skin| skin.id)
|
|
||||||
.collect()
|
|
||||||
} else {
|
|
||||||
HashSet::new()
|
|
||||||
},
|
|
||||||
|
|
||||||
fly_skins: if unlocks.unlock_all_fly_skins {
|
|
||||||
wicked_waifus_data::fly_skin_config_data::iter()
|
|
||||||
.filter(|skin| skin.skin_type == 0)
|
|
||||||
.map(|skin| skin.id)
|
|
||||||
.collect()
|
|
||||||
} else {
|
|
||||||
HashSet::new()
|
|
||||||
},
|
|
||||||
|
|
||||||
wing_skins: if unlocks.unlock_all_wing_skins {
|
|
||||||
wicked_waifus_data::fly_skin_config_data::iter()
|
|
||||||
.filter(|skin| skin.skin_type == 1)
|
|
||||||
.map(|skin| skin.id)
|
|
||||||
.collect()
|
|
||||||
} else {
|
|
||||||
HashSet::new()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -9,7 +9,7 @@ pub struct RoleFormation {
|
||||||
|
|
||||||
// Will be updated every version
|
// Will be updated every version
|
||||||
// const DEFAULT_FORMATION: &[i32] = &[5101, 1407, 1507];
|
// const DEFAULT_FORMATION: &[i32] = &[5101, 1407, 1507];
|
||||||
const DEFAULT_FORMATION: &[i32] = &[1205, 1207, 1409];
|
const DEFAULT_FORMATION: &[i32] = &[1506, 1207, 1409];
|
||||||
|
|
||||||
impl RoleFormation {
|
impl RoleFormation {
|
||||||
pub fn default_roles() -> &'static [i32] {
|
pub fn default_roles() -> &'static [i32] {
|
||||||
|
@ -29,7 +29,7 @@ impl RoleFormation {
|
||||||
RoleFormationData {
|
RoleFormationData {
|
||||||
formation_id: self.id,
|
formation_id: self.id,
|
||||||
cur_role: self.cur_role,
|
cur_role: self.cur_role,
|
||||||
role_id_list: self.role_ids.iter().copied().collect(),
|
role_id_list: self.role_ids.to_vec(),
|
||||||
is_current: self.is_current,
|
is_current: self.is_current,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use wicked_waifus_protocol::{ArrayIntInt, FormationRoleInfo, RoleInfo};
|
use wicked_waifus_protocol::{ArrayIntInt, RoleInfo};
|
||||||
|
|
||||||
use crate::config;
|
use crate::config;
|
||||||
use crate::logic::utils::growth_utils::get_role_props_by_level;
|
use crate::logic::utils::growth_utils::get_role_props_by_level;
|
||||||
|
@ -50,9 +50,6 @@ pub struct Role {
|
||||||
pub element_energy: i32,
|
pub element_energy: i32,
|
||||||
pub favor_level: i32,
|
pub favor_level: i32,
|
||||||
pub favor_exp: i32,
|
pub favor_exp: i32,
|
||||||
pub wing_skin_id: i32,
|
|
||||||
pub fly_skin_id: i32,
|
|
||||||
pub weapon_skin_id: i32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Role {
|
impl Role {
|
||||||
|
@ -122,44 +119,21 @@ impl Role {
|
||||||
|
|
||||||
let default_unlocks = &config::get_config().default_unlocks;
|
let default_unlocks = &config::get_config().default_unlocks;
|
||||||
let (level, breakthrough) = if default_unlocks.unlock_all_roles_max_level {
|
let (level, breakthrough) = if default_unlocks.unlock_all_roles_max_level {
|
||||||
(
|
(data.max_level, 6)
|
||||||
data.max_level,
|
|
||||||
wicked_waifus_data::role_breach_data::iter()
|
|
||||||
.filter(|level_data| level_data.breach_group_id == data.breach_id)
|
|
||||||
.map(|level_data| level_data.breach_level)
|
|
||||||
.max()
|
|
||||||
.unwrap_or(0),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
(
|
(1, 0)
|
||||||
1,
|
|
||||||
wicked_waifus_data::role_breach_data::iter()
|
|
||||||
.filter(|level_data| level_data.breach_group_id == data.breach_id)
|
|
||||||
.map(|level_data| level_data.breach_level)
|
|
||||||
.min()
|
|
||||||
.unwrap_or(0),
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
let resonant_chain_group_index = if default_unlocks.unlock_all_roles_all_sequences {
|
let resonant_chain_group_index = if default_unlocks.unlock_all_roles_all_sequences {
|
||||||
wicked_waifus_data::resonant_chain_data::iter()
|
6
|
||||||
.filter(|level_data| level_data.group_id == data.resonant_chain_group_id)
|
|
||||||
.map(|level_data| level_data.group_index)
|
|
||||||
.max()
|
|
||||||
.unwrap_or(0)
|
|
||||||
} else {
|
} else {
|
||||||
wicked_waifus_data::resonant_chain_data::iter()
|
0
|
||||||
.filter(|level_data| level_data.group_id == data.resonant_chain_group_id)
|
|
||||||
.map(|level_data| level_data.group_index)
|
|
||||||
.min()
|
|
||||||
.unwrap_or(0)
|
|
||||||
};
|
};
|
||||||
// TODO: add weapon and echo stats
|
|
||||||
let base_stats = &get_role_props_by_level(role_id, level, breakthrough);
|
let base_stats = &get_role_props_by_level(role_id, level, breakthrough);
|
||||||
Self {
|
Self {
|
||||||
role_id,
|
role_id,
|
||||||
name: String::with_capacity(0),
|
name: String::with_capacity(0),
|
||||||
level,
|
level,
|
||||||
exp: 0,
|
exp: 0, // TODO: Compute based on level??
|
||||||
breakthrough,
|
breakthrough,
|
||||||
skill_map: HashMap::new(), // TODO!
|
skill_map: HashMap::new(), // TODO!
|
||||||
star: 0,
|
star: 0,
|
||||||
|
@ -177,29 +151,24 @@ impl Role {
|
||||||
element_energy: base_stats.element_energy,
|
element_energy: base_stats.element_energy,
|
||||||
favor_level: 0,
|
favor_level: 0,
|
||||||
favor_exp: 0,
|
favor_exp: 0,
|
||||||
wing_skin_id: 0,
|
|
||||||
fly_skin_id: 0,
|
|
||||||
weapon_skin_id: 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_base_properties(&self) -> BasePropertyData {
|
pub fn get_base_properties(&self) -> BasePropertyData {
|
||||||
// Overwrite dynamic attributes with stores values
|
// Overwrite dynamic attributes with stores values
|
||||||
let mut base_stats = get_role_props_by_level(self.role_id, self.level, self.breakthrough);
|
let mut base_stats = get_role_props_by_level(self.role_id, self.level, self.breakthrough);
|
||||||
// TODO: add weapon and echo stats
|
|
||||||
// TODO: Integrity check, value has to be between 0 and max
|
// TODO: Integrity check, value has to be between 0 and max
|
||||||
base_stats.life = self.hp;
|
base_stats.life = base_stats.life_max;
|
||||||
base_stats.energy = self.energy;
|
base_stats.energy = base_stats.energy_max;
|
||||||
base_stats.special_energy_1 = self.special_energy_1;
|
base_stats.special_energy_1 = self.special_energy_1;
|
||||||
base_stats.special_energy_2 = self.special_energy_2;
|
base_stats.special_energy_2 = self.special_energy_2;
|
||||||
base_stats.special_energy_3 = self.special_energy_3;
|
base_stats.special_energy_3 = self.special_energy_3;
|
||||||
base_stats.special_energy_4 = self.special_energy_4;
|
base_stats.special_energy_4 = self.special_energy_4;
|
||||||
base_stats.element_energy = self.element_energy;
|
base_stats.element_energy = base_stats.element_energy_max;
|
||||||
base_stats
|
base_stats
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_protobuf(&self) -> RoleInfo {
|
pub fn to_protobuf(&self) -> RoleInfo {
|
||||||
// TODO: add weapon and echo stats
|
|
||||||
let base_prop: HashMap<i32, i32> = load_key_value(&self.get_base_properties());
|
let base_prop: HashMap<i32, i32> = load_key_value(&self.get_base_properties());
|
||||||
RoleInfo {
|
RoleInfo {
|
||||||
role_id: self.role_id,
|
role_id: self.role_id,
|
||||||
|
@ -223,17 +192,6 @@ impl Role {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_formation_protobuf(&self) -> FormationRoleInfo {
|
|
||||||
let base_stats = get_role_props_by_level(self.role_id, self.level, self.breakthrough);
|
|
||||||
FormationRoleInfo {
|
|
||||||
role_id: self.role_id,
|
|
||||||
max_hp: base_stats.life_max,
|
|
||||||
cur_hp: base_stats.life,
|
|
||||||
level: self.level,
|
|
||||||
role_skin_id: self.skin_id,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn load_from_save(data: RoleData) -> (i32, Self) {
|
pub fn load_from_save(data: RoleData) -> (i32, Self) {
|
||||||
(
|
(
|
||||||
data.role_id,
|
data.role_id,
|
||||||
|
@ -259,9 +217,6 @@ impl Role {
|
||||||
element_energy: data.stats.unwrap().element_energy,
|
element_energy: data.stats.unwrap().element_energy,
|
||||||
favor_level: data.favor_level,
|
favor_level: data.favor_level,
|
||||||
favor_exp: data.favor_exp,
|
favor_exp: data.favor_exp,
|
||||||
wing_skin_id: data.wing_skin_id,
|
|
||||||
fly_skin_id: data.fly_skin_id,
|
|
||||||
weapon_skin_id: data.weapon_skin_id,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -295,9 +250,6 @@ impl Role {
|
||||||
}),
|
}),
|
||||||
favor_level: self.favor_level,
|
favor_level: self.favor_level,
|
||||||
favor_exp: self.favor_exp,
|
favor_exp: self.favor_exp,
|
||||||
wing_skin_id: self.wing_skin_id,
|
|
||||||
fly_skin_id: self.fly_skin_id,
|
|
||||||
weapon_skin_id: self.weapon_skin_id,
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
use wicked_waifus_commons::time_util;
|
use super::{ecs::world::World, player::Player, utils::world_util};
|
||||||
use wicked_waifus_protocol_internal::PlayerSaveData;
|
use crate::logic::ecs::world::WorldEntity;
|
||||||
use wicked_waifus_protocol::{message::Message, AfterJoinSceneNotify, EnterGameResponse, JoinSceneNotify, SilenceNpcNotify, TransitionOptionPb};
|
use crate::{
|
||||||
|
logic,
|
||||||
|
player_save_task::{self, PlayerSaveReason},
|
||||||
|
session::Session,
|
||||||
|
};
|
||||||
use std::collections::hash_map::Entry::Vacant;
|
use std::collections::hash_map::Entry::Vacant;
|
||||||
use std::{
|
use std::{
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
|
@ -13,16 +17,20 @@ use std::{
|
||||||
thread,
|
thread,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
use super::{ecs::world::World, player::Player, utils::world_util};
|
use wicked_waifus_commons::time_util;
|
||||||
use crate::logic::ecs::world::WorldEntity;
|
use wicked_waifus_protocol::{
|
||||||
use crate::{logic, player_save_task::{self, PlayerSaveReason}, session::Session};
|
message::Message, AfterJoinSceneNotify, EnterGameResponse, JoinSceneNotify, SilenceNpcNotify,
|
||||||
|
TransitionOptionPb,
|
||||||
|
};
|
||||||
|
use wicked_waifus_protocol::{FormationAttr, FormationAttrNotify};
|
||||||
|
use wicked_waifus_protocol_internal::PlayerSaveData;
|
||||||
|
|
||||||
pub enum LogicInput {
|
pub enum LogicInput {
|
||||||
AddPlayer {
|
AddPlayer {
|
||||||
player_id: i32,
|
player_id: i32,
|
||||||
enter_rpc_id: u16,
|
enter_rpc_id: u16,
|
||||||
session: Arc<Session>,
|
session: Arc<Session>,
|
||||||
player_save_data: PlayerSaveData,
|
player_save_data: Box<PlayerSaveData>,
|
||||||
},
|
},
|
||||||
RemovePlayer {
|
RemovePlayer {
|
||||||
player_id: i32,
|
player_id: i32,
|
||||||
|
@ -132,16 +140,14 @@ fn handle_logic_input(state: &mut LogicState, input: LogicInput) {
|
||||||
} => {
|
} => {
|
||||||
let (player, is_player) = if let Vacant(e) = state.players.entry(player_id) {
|
let (player, is_player) = if let Vacant(e) = state.players.entry(player_id) {
|
||||||
(
|
(
|
||||||
e.insert(RefCell::new(Player::load_from_save(player_save_data))),
|
e.insert(RefCell::new(Player::load_from_save(*player_save_data))),
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
} else {
|
} else if let Some(player) = state.players.get_mut(&player_id) {
|
||||||
if let Some(player) = state.players.get_mut(&player_id) {
|
|
||||||
(player, false)
|
(player, false)
|
||||||
} else {
|
} else {
|
||||||
tracing::warn!("logic_thread: get player requested, but player {player_id} with data doesn't exist");
|
tracing::warn!("logic_thread: get player requested, but player {player_id} with data doesn't exist");
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut player = player.borrow_mut();
|
let mut player = player.borrow_mut();
|
||||||
|
@ -163,8 +169,7 @@ fn handle_logic_input(state: &mut LogicState, input: LogicInput) {
|
||||||
.world
|
.world
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.set_in_world_player_data(player.build_in_world_player());
|
.set_in_world_player_data(player.build_in_world_player());
|
||||||
|
world_util::add_player_entities(&player, player.formation_list.get(&player.cur_formation_id).unwrap(), None);
|
||||||
world_util::add_player_entities(&player);
|
|
||||||
let scene_info = world_util::build_scene_information(&player);
|
let scene_info = world_util::build_scene_information(&player);
|
||||||
|
|
||||||
player.notify(SilenceNpcNotify::default());
|
player.notify(SilenceNpcNotify::default());
|
||||||
|
@ -175,6 +180,26 @@ fn handle_logic_input(state: &mut LogicState, input: LogicInput) {
|
||||||
transition_option: Some(TransitionOptionPb::default()),
|
transition_option: Some(TransitionOptionPb::default()),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
player.notify(FormationAttrNotify {
|
||||||
|
duration: 1534854458,
|
||||||
|
formation_attrs: vec![
|
||||||
|
FormationAttr {
|
||||||
|
attr_id: 1,
|
||||||
|
ratio: 2400,
|
||||||
|
base_max_value: 24000,
|
||||||
|
max_value: 24000,
|
||||||
|
current_value: 24000,
|
||||||
|
},
|
||||||
|
FormationAttr {
|
||||||
|
attr_id: 10,
|
||||||
|
ratio: 2400,
|
||||||
|
base_max_value: 15000,
|
||||||
|
max_value: 15000,
|
||||||
|
current_value: 15000,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
player.notify(AfterJoinSceneNotify::default());
|
player.notify(AfterJoinSceneNotify::default());
|
||||||
player.notify(player.build_update_formation_notify());
|
player.notify(player.build_update_formation_notify());
|
||||||
|
|
||||||
|
@ -211,10 +236,14 @@ fn handle_logic_input(state: &mut LogicState, input: LogicInput) {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let _ = state.worlds.remove(&player_id);
|
let removed_world = state.worlds.remove(&player_id).unwrap();
|
||||||
// TODO: kick co-op players from removed world
|
let mut removed_world_ref = removed_world.borrow_mut();
|
||||||
// TODO: Remove all entities
|
let world = removed_world_ref.get_mut_world_entity();
|
||||||
|
for entity_id in world.get_all_entity_ids() {
|
||||||
|
world.remove_entity(entity_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: kick co-op players from removed world
|
||||||
player_save_task::push(
|
player_save_task::push(
|
||||||
player_id,
|
player_id,
|
||||||
player.borrow().build_save_data(),
|
player.borrow().build_save_data(),
|
||||||
|
|
|
@ -1,315 +0,0 @@
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use wicked_waifus_protocol::{CommonTagData, EntityCommonTagNotify, EntityStateReadyNotify, ItemRewardNotify, NormalItemUpdateNotify, RewardItemInfo, WR};
|
|
||||||
|
|
||||||
use wicked_waifus_data::pb_components::action::{Action, ChangeSelfEntityState, UnlockTeleportTrigger};
|
|
||||||
use wicked_waifus_data::pb_components::entity_state::EntityStateComponent;
|
|
||||||
|
|
||||||
use crate::logic::ecs::component::ComponentContainer;
|
|
||||||
use crate::logic::player::{ItemUsage, Player};
|
|
||||||
use crate::logic::utils::tag_utils;
|
|
||||||
use crate::query_components;
|
|
||||||
|
|
||||||
macro_rules! unimplemented_action {
|
|
||||||
($action:ident) => {
|
|
||||||
{
|
|
||||||
tracing::warn!("Action not implemented for: {:?}", $action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn perform_action(player: &mut Player,
|
|
||||||
entity_id: i64,
|
|
||||||
level_entity_data: &wicked_waifus_data::LevelEntityConfigData,
|
|
||||||
template_config: &wicked_waifus_data::TemplateConfigData,
|
|
||||||
element: Action) {
|
|
||||||
match element {
|
|
||||||
Action::SetBattleState(action) => unimplemented_action! { action },
|
|
||||||
Action::ExecBattleAction(action) => unimplemented_action! { action },
|
|
||||||
Action::WaitBattleCondition(action) => unimplemented_action! { action },
|
|
||||||
Action::PlayFlow(action) => unimplemented_action! { action },
|
|
||||||
Action::Collect(_) => collect_action(player, level_entity_data, template_config),
|
|
||||||
Action::LeisureInteract(action) => unimplemented_action! { action },
|
|
||||||
Action::UnlockTeleportTrigger(action) => unlock_teleport_trigger(player, action.params),
|
|
||||||
Action::EnableTemporaryTeleport(action) => unimplemented_action! { action },
|
|
||||||
Action::OpenSystemBoard(action) => unimplemented_action! { action },
|
|
||||||
Action::OpenSystemFunction(action) => unimplemented_action! { action },
|
|
||||||
Action::ChangeSelfEntityState(action) => change_self_entity_state(player, entity_id, level_entity_data, template_config, action.params),
|
|
||||||
Action::SetPlayerOperationRestriction(action) => unimplemented_action! { action },
|
|
||||||
Action::Wait(action) => unimplemented_action! { action },
|
|
||||||
Action::ChangeEntityState(action) => unimplemented_action! { action },
|
|
||||||
Action::Log(action) => unimplemented_action! { action },
|
|
||||||
Action::EnableNearbyTracking(action) => unimplemented_action! { action },
|
|
||||||
Action::TeleportDungeon(action) => unimplemented_action! { action },
|
|
||||||
Action::DestroySelf(action) => unimplemented_action! { action },
|
|
||||||
Action::CameraLookAt(action) => unimplemented_action! { action },
|
|
||||||
Action::StopCameraLookAt(action) => unimplemented_action! { action },
|
|
||||||
Action::EnterOrbitalCamera(action) => unimplemented_action! { action },
|
|
||||||
Action::ExitOrbitalCamera(action) => unimplemented_action! { action },
|
|
||||||
Action::SendAiEvent(action) => unimplemented_action! { action },
|
|
||||||
Action::SetInteractionLockState(action) => unimplemented_action! { action },
|
|
||||||
Action::AwakeEntity(action) => unimplemented_action! { action },
|
|
||||||
Action::ChangeLiftTarget(action) => unimplemented_action! { action },
|
|
||||||
Action::CalculateVar(action) => unimplemented_action! { action },
|
|
||||||
Action::AddBuffToPlayer(action) => unimplemented_action! { action },
|
|
||||||
Action::RemoveBuffFromPlayer(action) => unimplemented_action! { action },
|
|
||||||
Action::AddBuffToEntity(action) => unimplemented_action! { action },
|
|
||||||
Action::RemoveBuffFromEntity(action) => unimplemented_action! { action },
|
|
||||||
Action::Prompt(action) => unimplemented_action! { action },
|
|
||||||
Action::SetEntityVisible(action) => unimplemented_action! { action },
|
|
||||||
Action::DestroyEntity(action) => unimplemented_action! { action },
|
|
||||||
Action::GuideTrigger(action) => unimplemented_action! { action },
|
|
||||||
Action::TriggerCameraShake(action) => unimplemented_action! { action },
|
|
||||||
Action::SetVar(action) => unimplemented_action! { action },
|
|
||||||
Action::VehicleEnter(action) => unimplemented_action! { action },
|
|
||||||
Action::VehicleExitPlayer(action) => unimplemented_action! { action },
|
|
||||||
Action::LockEntity(action) => unimplemented_action! { action },
|
|
||||||
Action::UnlockEntity(action) => unimplemented_action! { action },
|
|
||||||
Action::CommonTip(action) => unimplemented_action! { action },
|
|
||||||
Action::CommonTip2(action) => unimplemented_action! { action },
|
|
||||||
Action::PostAkEvent(action) => unimplemented_action! { action },
|
|
||||||
Action::VehicleEnterNpc(action) => unimplemented_action! { action },
|
|
||||||
Action::VehicleExitNpc(action) => unimplemented_action! { action },
|
|
||||||
Action::PlayerLookAt(action) => unimplemented_action! { action },
|
|
||||||
Action::PlayBubble(action) => unimplemented_action! { action },
|
|
||||||
Action::AddPlayBubble(action) => unimplemented_action! { action },
|
|
||||||
Action::ClearPlayBubble(action) => unimplemented_action! { action },
|
|
||||||
Action::ExecRiskHarvestEffect(action) => unimplemented_action! { action },
|
|
||||||
Action::EnableLevelPlay(action) => unimplemented_action! { action },
|
|
||||||
Action::ClaimLevelPlayReward(action) => unimplemented_action! { action },
|
|
||||||
Action::SettlementDungeon(action) => unimplemented_action! { action },
|
|
||||||
Action::ExitDungeon(action) => unimplemented_action! { action },
|
|
||||||
Action::FinishDungeon(action) => unimplemented_action! { action },
|
|
||||||
Action::RecordDungeonEvent(action) => unimplemented_action! { action },
|
|
||||||
Action::RecoverDurability(action) => unimplemented_action! { action },
|
|
||||||
Action::FadeInScreen(action) => unimplemented_action! { action },
|
|
||||||
Action::FadeOutScreen(action) => unimplemented_action! { action },
|
|
||||||
Action::ChangeNpcPerformState(action) => unimplemented_action! { action },
|
|
||||||
Action::EntityTurnTo(action) => unimplemented_action! { action },
|
|
||||||
Action::EntityLookAt(action) => unimplemented_action! { action },
|
|
||||||
Action::ToggleMapMarkState(action) => unimplemented_action! { action },
|
|
||||||
Action::RandomVar(action) => unimplemented_action! { action },
|
|
||||||
Action::ModifySceneItemAttributeTag(action) => unimplemented_action! { action },
|
|
||||||
Action::VehicleWaterfallClimbing(action) => unimplemented_action! { action },
|
|
||||||
Action::VehicleTeleport(action) => unimplemented_action! { action },
|
|
||||||
Action::RogueGotoNextFloor(action) => unimplemented_action! { action },
|
|
||||||
Action::RogueReceiveReward(action) => unimplemented_action! { action },
|
|
||||||
Action::RogueSelectRoom(action) => unimplemented_action! { action },
|
|
||||||
Action::RogueActivatePortal(action) => unimplemented_action! { action },
|
|
||||||
Action::MowingTowerGotoNextFloor(action) => unimplemented_action! { action },
|
|
||||||
Action::SlashAndTowerGotoNextFloor(action) => unimplemented_action! { action },
|
|
||||||
Action::PlayMontage(action) => unimplemented_action! { action },
|
|
||||||
Action::OpenSystemBoardWithReturn(action) => unimplemented_action! { action },
|
|
||||||
Action::UnlockSystemItem(action) => unimplemented_action! { action },
|
|
||||||
Action::SetSportsState(action) => unimplemented_action! { action },
|
|
||||||
Action::OpenSimpleGameplay(action) => unimplemented_action! { action },
|
|
||||||
Action::PlayEffect(action) => unimplemented_action! { action },
|
|
||||||
Action::PlayEffect2(action) => unimplemented_action! { action },
|
|
||||||
Action::RestorePlayerCameraAdjustment(action) => unimplemented_action! { action },
|
|
||||||
Action::AdjustPlayerCamera(action) => unimplemented_action! { action },
|
|
||||||
Action::SetPlayerPos(action) => unimplemented_action! { action },
|
|
||||||
Action::MoveWithSpline(action) => unimplemented_action! { action },
|
|
||||||
Action::EnableSplineMoveModel(action) => unimplemented_action! { action },
|
|
||||||
Action::ToggleScanSplineEffect(action) => unimplemented_action! { action },
|
|
||||||
Action::MoveSceneItem(action) => unimplemented_action! { action },
|
|
||||||
Action::StopSceneItemMove(action) => unimplemented_action! { action },
|
|
||||||
Action::FireBullet(action) => unimplemented_action! { action },
|
|
||||||
Action::ClearFishingCabinInSaleItems(action) => unimplemented_action! { action },
|
|
||||||
Action::AcceptFishingEntrust(action) => unimplemented_action! { action },
|
|
||||||
Action::DestroyFishingBoat(action) => unimplemented_action! { action },
|
|
||||||
Action::SetJigsawItem(action) => unimplemented_action! { action },
|
|
||||||
Action::SetJigsawFoundation(action) => unimplemented_action! { action },
|
|
||||||
Action::SetTeleControl(action) => unimplemented_action! { action },
|
|
||||||
Action::SetEntityClientVisible(action) => unimplemented_action! { action },
|
|
||||||
Action::ToggleHighlightExploreUi(action) => unimplemented_action! { action },
|
|
||||||
Action::ExecAlertSystemAction(action) => unimplemented_action! { action },
|
|
||||||
Action::AddFlowInteractOption(action) => unimplemented_action! { action },
|
|
||||||
Action::RemoveFlowInteractOption(action) => unimplemented_action! { action },
|
|
||||||
Action::EnableHostility(action) => unimplemented_action! { action },
|
|
||||||
Action::ChangePhantomFormation(action) => unimplemented_action! { action },
|
|
||||||
Action::RestorePhantomFormation(action) => unimplemented_action! { action },
|
|
||||||
Action::ChangeTimer(action) => unimplemented_action! { action },
|
|
||||||
Action::ToggleTimerPauseState(action) => unimplemented_action! { action },
|
|
||||||
Action::ChangeFightTeam(action) => unimplemented_action! { action },
|
|
||||||
Action::AddTrialFollowShooter(action) => unimplemented_action! { action },
|
|
||||||
Action::RemoveTrialFollowShooter(action) => unimplemented_action! { action },
|
|
||||||
Action::AddTrialCharacter(action) => unimplemented_action! { action },
|
|
||||||
Action::RemoveTrialCharacter(action) => unimplemented_action! { action },
|
|
||||||
Action::SetAreaState(action) => unimplemented_action! { action },
|
|
||||||
Action::SwitchSubLevels(action) => unimplemented_action! { action },
|
|
||||||
Action::ChangeTeamPosition(action) => unimplemented_action! { action },
|
|
||||||
Action::GetItem(action) => unimplemented_action! { action },
|
|
||||||
Action::CreatePrefab(action) => unimplemented_action! { action },
|
|
||||||
Action::DestroyPrefab(action) => unimplemented_action! { action },
|
|
||||||
Action::CompleteGuide(action) => unimplemented_action! { action },
|
|
||||||
Action::PlayDynamicSettlement(action) => unimplemented_action! { action },
|
|
||||||
Action::UsePhantomSkill(action) => unimplemented_action! { action },
|
|
||||||
Action::HideTargetRange(action) => unimplemented_action! { action },
|
|
||||||
Action::ChangeOtherState(action) => unimplemented_action! { action },
|
|
||||||
Action::SetRegionConfig(action) => unimplemented_action! { action },
|
|
||||||
Action::SetReviveRegion(action) => unimplemented_action! { action },
|
|
||||||
Action::ExecResurrection(action) => unimplemented_action! { action },
|
|
||||||
Action::ShowTargetRange(action) => unimplemented_action! { action },
|
|
||||||
Action::SetTime(action) => unimplemented_action! { action },
|
|
||||||
Action::SetTimeLockState(action) => unimplemented_action! { action },
|
|
||||||
Action::EnableSystem(action) => unimplemented_action! { action },
|
|
||||||
Action::EnableAoiNotify(action) => unimplemented_action! { action },
|
|
||||||
Action::SetForceLock(action) => unimplemented_action! { action },
|
|
||||||
Action::PlayRegisteredMontage(action) => unimplemented_action! { action },
|
|
||||||
Action::SetAudioState(action) => unimplemented_action! { action },
|
|
||||||
Action::HideGroup(action) => unimplemented_action! { action },
|
|
||||||
Action::ShowHidedGroup(action) => unimplemented_action! { action },
|
|
||||||
Action::HideSpecificEntities(action) => unimplemented_action! { action },
|
|
||||||
Action::ShowSpecificEntities(action) => unimplemented_action! { action },
|
|
||||||
Action::RemovePreloadResource(action) => unimplemented_action! { action },
|
|
||||||
Action::Preload(action) => unimplemented_action! { action },
|
|
||||||
Action::EnableAI(action) => unimplemented_action! { action },
|
|
||||||
Action::SwitchDataLayers(action) => unimplemented_action! { action },
|
|
||||||
Action::DestroyQuest(action) => unimplemented_action! { action },
|
|
||||||
Action::DestroyQuestItem(action) => unimplemented_action! { action },
|
|
||||||
Action::PromptQuestChapterUI(action) => unimplemented_action! { action },
|
|
||||||
Action::TakePlotPhoto(action) => unimplemented_action! { action },
|
|
||||||
Action::SetWuYinQuState(action) => unimplemented_action! { action },
|
|
||||||
Action::RunActions(action) => unimplemented_action! { action },
|
|
||||||
Action::ManualOccupations(action) => unimplemented_action! { action },
|
|
||||||
Action::SetWeather(action) => unimplemented_action! { action },
|
|
||||||
Action::SendNpcMail(action) => unimplemented_action! { action },
|
|
||||||
Action::EnableFunction(action) => unimplemented_action! { action },
|
|
||||||
Action::FocusOnMapMark(action) => unimplemented_action! { action },
|
|
||||||
Action::CharacterLookAt(action) => unimplemented_action! { action },
|
|
||||||
Action::AddGuestCharacter(action) => unimplemented_action! { action },
|
|
||||||
Action::RemoveGuestCharacter(action) => unimplemented_action! { action },
|
|
||||||
Action::TeleportToAndEnterVehicle(action) => unimplemented_action! { action },
|
|
||||||
Action::SetAreaTimeState(action) => unimplemented_action! { action },
|
|
||||||
Action::ResetPlayerCameraFocus(action) => unimplemented_action! { action },
|
|
||||||
Action::ResetLevelPlay(action) => unimplemented_action! { action },
|
|
||||||
Action::VehicleSprint(action) => unimplemented_action! { action },
|
|
||||||
Action::VehicleMoveWithPathLine(action) => unimplemented_action! { action },
|
|
||||||
Action::ClientPreEnableSubLevels(action) => unimplemented_action! { action },
|
|
||||||
Action::GuestOperateUiAnimation(action) => unimplemented_action! { action },
|
|
||||||
Action::ChangeEntityCamp(action) => unimplemented_action! { action },
|
|
||||||
Action::NewMoveWithSpline(action) => unimplemented_action! { action },
|
|
||||||
Action::DangoAbyssActivatePortal(action) => unimplemented_action! { action },
|
|
||||||
Action::DangoAbyssCreateRewardTreasureBox(action) => unimplemented_action! { action },
|
|
||||||
Action::DangoAbyssGotoNextFloor(action) => unimplemented_action! { action },
|
|
||||||
Action::DangoAbyssReceiveReward(action) => unimplemented_action! { action },
|
|
||||||
Action::SummonEntity(action) => unimplemented_action! { action },
|
|
||||||
Action::GetRewardByInteract(action) => unimplemented_action! { action },
|
|
||||||
Action::OpenQte(action) => unimplemented_action! { action },
|
|
||||||
Action::ActiveAntiGravitySafePoint(action) => unimplemented_action! { action },
|
|
||||||
Action::BvbPlayDialog(action) => unimplemented_action! { action },
|
|
||||||
Action::BvbSendSystemEvent(action) => unimplemented_action! { action },
|
|
||||||
Action::BvbSendAiEvent(action) => unimplemented_action! { action },
|
|
||||||
Action::BvbPlayerOperationConstraint(action) => unimplemented_action! { action },
|
|
||||||
Action::ExecClientBattleAction(action) => unimplemented_action! { action },
|
|
||||||
Action::TriggerSpecificScanEffect(action) => unimplemented_action! { action },
|
|
||||||
Action::SetActorVar(action) => unimplemented_action! { action },
|
|
||||||
Action::RunActorCustomEvent(action) => unimplemented_action! { action },
|
|
||||||
Action::StopUiScreenEffect(action) => unimplemented_action! { action },
|
|
||||||
Action::StopNewMoveWithSpline(action) => unimplemented_action! { action },
|
|
||||||
Action::RequestSystemFunction(action) => unimplemented_action! { action },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn collect_action(player: &mut Player,
|
|
||||||
level_entity_data: &wicked_waifus_data::LevelEntityConfigData,
|
|
||||||
template_config: &wicked_waifus_data::TemplateConfigData) {
|
|
||||||
if let Some(reward_component) = level_entity_data.components_data.reward_component
|
|
||||||
.as_ref()
|
|
||||||
.or(template_config.components_data.reward_component.as_ref()) {
|
|
||||||
if reward_component.disabled.unwrap_or(false) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// TODO: check the use of reward_type and drop_on_event
|
|
||||||
// Seems type 0 is reward from preview, while 1 and 2 is unknown
|
|
||||||
if let Some(reward_id) = reward_component.reward_id {
|
|
||||||
let drop = wicked_waifus_data::drop_package_data::get(&reward_id).unwrap();
|
|
||||||
let usages = drop.drop_preview.iter()
|
|
||||||
.map(|(&id, &quantity)| ItemUsage { id, quantity })
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
let updated_items = player.inventory.add_items(&usages);
|
|
||||||
let normal_item_list = player.inventory.to_normal_item_list_filtered(
|
|
||||||
&updated_items.keys().cloned().collect::<Vec<i32>>()
|
|
||||||
);
|
|
||||||
player.notify(NormalItemUpdateNotify { normal_item_list, no_tips: false });
|
|
||||||
// UpdateHandBookActiveStateMapNotify
|
|
||||||
let mut rewards: HashMap<i32, WR> = HashMap::new();
|
|
||||||
rewards.insert(0, WR {
|
|
||||||
item_list: drop.drop_preview.iter()
|
|
||||||
.map(|(&id, &quantity)| RewardItemInfo {
|
|
||||||
show_plan_id: 0, // TODO: Check how to get this
|
|
||||||
item_id: id,
|
|
||||||
count: quantity,
|
|
||||||
incr_id: 0,
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
});
|
|
||||||
player.notify(ItemRewardNotify {
|
|
||||||
drop_id: reward_id,
|
|
||||||
reason: 15000,
|
|
||||||
magnification: 1,
|
|
||||||
reward_items: rewards,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// TODO: Should we remove entity?? get pcap
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn unlock_teleport_trigger(player: &mut Player, action: UnlockTeleportTrigger) {
|
|
||||||
player.unlock_teleport(action.teleport_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn change_self_entity_state(player: &mut Player,
|
|
||||||
entity_id: i64,
|
|
||||||
level_entity_data: &wicked_waifus_data::LevelEntityConfigData,
|
|
||||||
template_config: &wicked_waifus_data::TemplateConfigData,
|
|
||||||
action: ChangeSelfEntityState) {
|
|
||||||
let state = tag_utils::get_tag_id_by_name(action.entity_state.as_str());
|
|
||||||
|
|
||||||
// TODO: update Tag::CommonEntityTags too??
|
|
||||||
let old_state = {
|
|
||||||
let world_ref = player.world.borrow();
|
|
||||||
let world = world_ref.get_world_entity();
|
|
||||||
let mut state_tag = query_components!(world, entity_id, StateTag).0.unwrap();
|
|
||||||
let old_state = state_tag.state_tag_id;
|
|
||||||
tracing::debug!("ChangeSelfEntityState: old state {old_state} -> new state: {state}");
|
|
||||||
state_tag.state_tag_id = state;
|
|
||||||
old_state
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(entity_state_component) = level_entity_data.components_data.entity_state_component.as_ref()
|
|
||||||
.or(template_config.components_data.entity_state_component.as_ref()).cloned() {
|
|
||||||
let entity_state_component: EntityStateComponent = entity_state_component; // TODO: Remove this line, used for casting only
|
|
||||||
|
|
||||||
// TODO: implement rest of cases
|
|
||||||
if let Some(state_change_behaviors) = entity_state_component.state_change_behaviors {
|
|
||||||
for state_change_behavior in state_change_behaviors {
|
|
||||||
// TODO: implement rest of cases
|
|
||||||
let expected = tag_utils::get_tag_id_by_name(state_change_behavior.state.as_str());
|
|
||||||
|
|
||||||
if expected == state {
|
|
||||||
if let Some(actions) = state_change_behavior.action {
|
|
||||||
for sub in actions {
|
|
||||||
perform_action(player, entity_id, level_entity_data, template_config, sub);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
player.notify(EntityCommonTagNotify {
|
|
||||||
id: entity_id,
|
|
||||||
tags: vec![
|
|
||||||
CommonTagData { tag_id: old_state, remove_tag_ids: false }, // Remove
|
|
||||||
CommonTagData { tag_id: state, remove_tag_ids: true }, // Add
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
player.notify(EntityStateReadyNotify {
|
|
||||||
entity_id,
|
|
||||||
tag_id: state,
|
|
||||||
ready: true, // TODO: Always true? or shall we compare it to something??
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,9 +1,7 @@
|
||||||
pub mod action_utils;
|
|
||||||
pub mod condition_utils;
|
pub mod condition_utils;
|
||||||
pub mod entity_serializer;
|
pub mod entity_serializer;
|
||||||
pub mod growth_utils;
|
|
||||||
pub mod load_role_info;
|
pub mod load_role_info;
|
||||||
pub mod quadrant_util;
|
|
||||||
pub mod seq_utils;
|
|
||||||
pub mod tag_utils;
|
|
||||||
pub mod world_util;
|
pub mod world_util;
|
||||||
|
pub mod quadrant_util;
|
||||||
|
pub mod growth_utils;
|
||||||
|
pub mod tag_utils;
|
|
@ -3,7 +3,7 @@ use std::sync::OnceLock;
|
||||||
|
|
||||||
use wicked_waifus_data::LevelEntityConfigData;
|
use wicked_waifus_data::LevelEntityConfigData;
|
||||||
|
|
||||||
pub(crate) struct StaticConfig {
|
struct StaticConfig {
|
||||||
edge_size: f32,
|
edge_size: f32,
|
||||||
edge_check: f32,
|
edge_check: f32,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
use std::collections::{HashMap, VecDeque};
|
|
||||||
|
|
||||||
pub trait Sequencer<T> {
|
|
||||||
fn new() -> Self;
|
|
||||||
fn from_data<V>(data: &HashMap<T, V>) -> Self;
|
|
||||||
fn take_id(&mut self) -> T;
|
|
||||||
fn give_id(&mut self, id: T);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SequenceGenerator<T, A> {
|
|
||||||
recycled_ids: VecDeque<T>,
|
|
||||||
next_id: A,
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! sequence_trait_impl {
|
|
||||||
($t:ty, $a:ty) => (
|
|
||||||
impl Sequencer<$t> for SequenceGenerator<$t, $a> {
|
|
||||||
fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
recycled_ids: Default::default(),
|
|
||||||
next_id: <$a>::new(1),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_data<V>(data: &HashMap<$t, V>) -> Self {
|
|
||||||
let max_id = data.keys().max().copied().unwrap_or(1);
|
|
||||||
let next_id = <$a>::new(max_id);
|
|
||||||
|
|
||||||
let mut recycled_ids = VecDeque::new();
|
|
||||||
for i in 1..max_id {
|
|
||||||
if !data.contains_key(&i) {
|
|
||||||
recycled_ids.push_back(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Self {
|
|
||||||
recycled_ids,
|
|
||||||
next_id,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn take_id(&mut self) -> $t {
|
|
||||||
self.recycled_ids
|
|
||||||
.pop_front()
|
|
||||||
.unwrap_or_else(|| self.next_id.fetch_add(1, std::sync::atomic::Ordering::Relaxed))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn give_id(&mut self, id: $t) {
|
|
||||||
self.recycled_ids.push_back(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
sequence_trait_impl!(i32, std::sync::atomic::AtomicI32);
|
|
||||||
sequence_trait_impl!(i64, std::sync::atomic::AtomicI64);
|
|
|
@ -1,145 +1,172 @@
|
||||||
|
use wicked_waifus_protocol::summon::ESummonType;
|
||||||
use wicked_waifus_protocol::{
|
use wicked_waifus_protocol::{
|
||||||
EEntityType, ERemoveEntityType, EntityAddNotify, EntityConfigType, EntityPb, EntityRemoveInfo,
|
EEntityType, ERemoveEntityType, EntityAddNotify, EntityConfigType, EntityPb, EntityRemoveInfo, EntityRemoveNotify, EntityState, FightBuffInformation, FightRoleInfo, FightRoleInfos, LivingStatus, SceneInformation, SceneMode, ScenePlayerInformation, SceneTimeInfo
|
||||||
EntityRemoveNotify, EntityState, FightRoleInfo, FightRoleInfos, LivingStatus, SceneInformation,
|
|
||||||
SceneMode, ScenePlayerInformation, SceneTimeInfo,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use wicked_waifus_data::pb_components::ComponentsData;
|
use wicked_waifus_data::pb_components::ComponentsData;
|
||||||
use wicked_waifus_data::{
|
use wicked_waifus_data::{
|
||||||
blueprint_config_data, template_config_data, EntityLogic, EntityType, LevelEntityConfigData,
|
base_property_data, blueprint_config_data, summon_cfg_data, template_config_data, EntityLogic, EntityType, LevelEntityConfigData
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::logic::components::{Autonomous, Fsm, Interact, MonsterAi, ParaglidingSkin, SoarWingSkin, StateTag, Tag, WeaponSkin};
|
use crate::logic::components::{Autonomous, Fsm, Interact, MonsterAi, SoarWingSkin, StateTag, Tag};
|
||||||
use crate::logic::ecs::entity::EntityBuilder;
|
use crate::logic::ecs::entity::{Entity, EntityBuilder};
|
||||||
use crate::logic::ecs::world::World;
|
use crate::logic::ecs::world::{World, WorldEntity};
|
||||||
use crate::logic::math::Transform;
|
use crate::logic::math::Transform;
|
||||||
use crate::logic::player::Player;
|
use crate::logic::player::Player;
|
||||||
use crate::logic::utils::{entity_serializer, tag_utils};
|
use crate::logic::role::RoleFormation;
|
||||||
use crate::logic::utils::growth_utils::get_monster_props_by_level;
|
use crate::logic::utils::growth_utils::get_monster_props_by_level;
|
||||||
|
use crate::logic::utils::{entity_serializer, tag_utils};
|
||||||
use crate::logic::{
|
use crate::logic::{
|
||||||
components::{
|
components::{
|
||||||
Attribute, EntityConfig, Equip, FightBuff, Movement, OwnerPlayer, PlayerOwnedEntityMarker,
|
Attribute, Concomitant, EntityConfig, Equip, FightBuff, Movement, OwnerPlayer,
|
||||||
Position, RoleSkin, Visibility, VisionSkill,
|
PlayerOwnedEntityMarker, Position, RoleSkin, Summoner, Visibility, VisionSkill,
|
||||||
},
|
},
|
||||||
ecs::component::ComponentContainer,
|
ecs::component::ComponentContainer,
|
||||||
};
|
};
|
||||||
|
//use crate::resonator_data::{ResonatorData, Concomitant, SummonerComponent};
|
||||||
|
|
||||||
use crate::query_with;
|
use crate::query_with;
|
||||||
|
|
||||||
#[macro_export]
|
pub fn summon_concomitant(player: &Player, world: &mut WorldEntity, template_cfg: &wicked_waifus_data::TemplateConfigData, cur_summon_id: i32) -> (Entity, Vec<i64>) {
|
||||||
macro_rules! create_player_entity_pb {
|
let mut concomitant_buffs: Vec<FightBuffInformation> = Vec::new();
|
||||||
($role_list:expr, $cur_map_id:expr, $player:expr, $player_id:expr, $position:expr, $explore_tools:expr, $world:expr) => {{
|
|
||||||
let current_formation = $player.formation_list.get(&$player.cur_formation_id).unwrap();
|
|
||||||
let cur_role_id = current_formation.cur_role;
|
|
||||||
|
|
||||||
let mut pbs = Vec::new();
|
let summon_cfg = summon_cfg_data::get(&template_cfg.blueprint_type).unwrap();
|
||||||
|
let concomitant_config_id = template_cfg.id;
|
||||||
|
|
||||||
for role in $role_list {
|
let con_entity = world.create_entity(
|
||||||
let entity = $world.create_entity(
|
cur_summon_id,
|
||||||
role.role_id,
|
EEntityType::Monster.into(),
|
||||||
EEntityType::Player.into(),
|
player.basic_info.cur_map_id,
|
||||||
$cur_map_id,
|
|
||||||
);
|
);
|
||||||
// Once per character buffs are implemented, add a mut on role_buffs
|
|
||||||
let fight_buff_infos = $world.generate_role_permanent_buffs(entity.entity_id as i64);
|
|
||||||
let buf_manager = FightBuff {
|
|
||||||
fight_buff_infos,
|
|
||||||
list_buff_effect_cd: vec![],
|
|
||||||
};
|
|
||||||
|
|
||||||
let entity = $world.create_builder(entity)
|
for buff_id in &summon_cfg.born_buff_id {
|
||||||
|
concomitant_buffs.push(world.create_buff(cur_summon_id, *buff_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
tracing::info!("Adding Concomitant with id: {} and buffs {:#?}", concomitant_config_id, concomitant_buffs);
|
||||||
|
|
||||||
|
(world
|
||||||
|
.create_builder(con_entity)
|
||||||
.with(ComponentContainer::PlayerOwnedEntityMarker(PlayerOwnedEntityMarker {
|
.with(ComponentContainer::PlayerOwnedEntityMarker(PlayerOwnedEntityMarker {
|
||||||
entity_type: EEntityType::Player,
|
entity_type: EEntityType::Monster,
|
||||||
}))
|
}))
|
||||||
.with(ComponentContainer::EntityConfig(EntityConfig {
|
.with(ComponentContainer::EntityConfig(EntityConfig {
|
||||||
camp: 0,
|
camp: 0,
|
||||||
config_id: role.role_id,
|
config_id: concomitant_config_id,
|
||||||
config_type: EntityConfigType::Character,
|
config_type: EntityConfigType::Template,
|
||||||
entity_type: EEntityType::Player.into(),
|
entity_type: EEntityType::Monster,
|
||||||
entity_state: EntityState::Default,
|
entity_state: EntityState::Born,
|
||||||
}))
|
}))
|
||||||
.with(ComponentContainer::OwnerPlayer(OwnerPlayer($player_id)))
|
.with(ComponentContainer::OwnerPlayer(OwnerPlayer(
|
||||||
.with(ComponentContainer::Position(Position($position)))
|
player.basic_info.id,
|
||||||
.with(ComponentContainer::Visibility(Visibility{
|
)))
|
||||||
is_visible: role.role_id == cur_role_id,
|
.with(ComponentContainer::Position(Position(
|
||||||
|
player.location.position.clone(),
|
||||||
|
)))
|
||||||
|
.with(ComponentContainer::Visibility(Visibility {
|
||||||
|
is_visible: false,
|
||||||
is_actor_visible: true,
|
is_actor_visible: true,
|
||||||
}))
|
}))
|
||||||
// TODO: Check if role has hardness or rage_mode
|
.with(ComponentContainer::Attribute(Attribute::from_data(
|
||||||
// TODO: Support AddProp from Equipment(Echo, weapon, buffs??), weapon base state goes to base_prop too.
|
base_property_data::iter()
|
||||||
.with(ComponentContainer::Attribute(
|
.find(|d| d.id == template_cfg.components_data.attribute_component.clone().unwrap().property_id.unwrap())
|
||||||
Attribute::from_data(
|
.unwrap(),
|
||||||
&role.get_base_properties(),
|
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
)
|
)))
|
||||||
))
|
.with(ComponentContainer::FightBuff(FightBuff { fight_buff_infos: concomitant_buffs, ..Default::default() }))
|
||||||
.with(ComponentContainer::Movement(Movement::default()))
|
.with(ComponentContainer::Summoner(Summoner {
|
||||||
.with(ComponentContainer::Equip(Equip {
|
summon_cfg_id: summon_cfg.id,
|
||||||
weapon_id: role.equip_weapon,
|
summon_skill_id: 0,
|
||||||
weapon_breach_level: 90, // TODO: store this too
|
summon_type: ESummonType::ESummonTypeConcomitantCustom.into()
|
||||||
}))
|
}))
|
||||||
.with(ComponentContainer::VisionSkill(VisionSkill {
|
.with(ComponentContainer::Autonomous(Autonomous { autonomous_id: 3 }))
|
||||||
skill_id: $explore_tools.active_explore_skill,
|
.build(), summon_cfg.born_buff_id.clone())
|
||||||
}))
|
|
||||||
.with(ComponentContainer::RoleSkin(RoleSkin {
|
|
||||||
skin_id: role.skin_id,
|
|
||||||
}))
|
|
||||||
.with(ComponentContainer::SoarWingSkin(SoarWingSkin {
|
|
||||||
skin_id: role.fly_skin_id,
|
|
||||||
}))
|
|
||||||
.with(ComponentContainer::ParaglidingSkin(ParaglidingSkin {
|
|
||||||
skin_id: role.wing_skin_id,
|
|
||||||
}))
|
|
||||||
.with(ComponentContainer::WeaponSkin(WeaponSkin {
|
|
||||||
skin_id: role.weapon_skin_id,
|
|
||||||
}))
|
|
||||||
.with(ComponentContainer::FightBuff(buf_manager))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let mut pb = EntityPb {
|
|
||||||
id: entity.entity_id as i64,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
$world
|
|
||||||
.get_entity_components(entity.entity_id)
|
|
||||||
.into_iter()
|
|
||||||
.for_each(|comp| comp.set_pb_data(&mut pb));
|
|
||||||
pbs.push(pb);
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityAddNotify {
|
|
||||||
entity_pbs: pbs,
|
|
||||||
remove_tag_ids: true,
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_player_entities(player: &Player) {
|
fn add_player_entity(player: &Player, formation: &RoleFormation, world: &mut WorldEntity) {
|
||||||
let mut world_ref = player.world.borrow_mut();
|
let role_vec = formation
|
||||||
let world = world_ref.get_mut_world_entity();
|
|
||||||
|
|
||||||
let current_formation = player.formation_list.get(&player.cur_formation_id).unwrap();
|
|
||||||
|
|
||||||
let role_vec = current_formation
|
|
||||||
.role_ids
|
.role_ids
|
||||||
.iter()
|
.iter()
|
||||||
.map(|role_id| player.role_list.get(&role_id).unwrap())
|
.map(|role_id| player.role_list.get(role_id).unwrap())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let cur_role_id = current_formation.cur_role;
|
|
||||||
|
|
||||||
if world.active_entity_empty() {
|
tracing::info!("adding player entity for formation {:#?}", formation.role_ids);
|
||||||
|
let cur_role_id = formation.cur_role;
|
||||||
|
|
||||||
|
let mut pbs = Vec::new();
|
||||||
|
|
||||||
for role in role_vec {
|
for role in role_vec {
|
||||||
let entity = world.create_entity(
|
let entity = world.create_entity(
|
||||||
role.role_id,
|
role.role_id,
|
||||||
EEntityType::Player.into(),
|
EEntityType::Player.into(),
|
||||||
player.basic_info.cur_map_id,
|
player.basic_info.cur_map_id,
|
||||||
);
|
);
|
||||||
// Once per character buffs are implemented, add a mut on role_buffs
|
|
||||||
let fight_buff_infos = world.generate_role_permanent_buffs(entity.entity_id as i64);
|
let mut fight_buff_infos = world.generate_role_permanent_buffs(entity.entity_id, role.role_id);
|
||||||
|
|
||||||
|
// TODO: add actual weapon switching and remove this! - rabby
|
||||||
|
let equip_weapon = match role.role_id {
|
||||||
|
1409 => 21020056, // cartethyia
|
||||||
|
1207 => 21010036, // lupa
|
||||||
|
1301 => 21010036,
|
||||||
|
_ => role.equip_weapon,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut concomitants: Vec<i64> = vec![];
|
||||||
|
let mut concom_pbs = Vec::new();
|
||||||
|
|
||||||
|
let role_data = wicked_waifus_data::role_info_data::iter().find(|r| r.id == role.role_id).unwrap();
|
||||||
|
if let Some(skin_damage_first) = role_data.skin_damage.first() {
|
||||||
|
let role_name = skin_damage_first.as_str()
|
||||||
|
.split('/').next_back()
|
||||||
|
.and_then(|s| s.strip_prefix("DA_"))
|
||||||
|
.and_then(|s| s.split('_').next()).unwrap();
|
||||||
|
|
||||||
|
let mut summon_id = 1000;
|
||||||
|
for model_config in wicked_waifus_data::model_config_preload_data::iter().filter(|cfg| {
|
||||||
|
cfg.actor_class_path.starts_with("/Game/Aki/Character/Monster/Summon/") && cfg.actor_class_path.contains(role_name)
|
||||||
|
}) {
|
||||||
|
let template_cfg = wicked_waifus_data::template_config_data::iter().find(|cfg| {
|
||||||
|
let template_model_component = cfg.1.components_data.model_component.clone();
|
||||||
|
template_model_component.is_some()
|
||||||
|
&&
|
||||||
|
template_model_component.clone().unwrap().model_type.unwrap().model_id.is_some()
|
||||||
|
&&
|
||||||
|
template_model_component.unwrap().model_type.unwrap().model_id.unwrap() == model_config.id
|
||||||
|
}).unwrap().1;
|
||||||
|
|
||||||
|
let (concomitant, buffs) = summon_concomitant(player, world, template_cfg, summon_id);
|
||||||
|
let mut pb = EntityPb {
|
||||||
|
id: summon_id as i64,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
for buff_id in buffs {
|
||||||
|
fight_buff_infos.push(world.create_buff(entity.entity_id, buff_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
world
|
||||||
|
.get_entity_components(summon_id)
|
||||||
|
.into_iter()
|
||||||
|
.for_each(|comp| comp.set_pb_data(&mut pb));
|
||||||
|
concom_pbs.push(pb);
|
||||||
|
summon_id += 1;
|
||||||
|
concomitants.push(concomitant.entity_id.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
player.notify(EntityAddNotify {
|
||||||
|
entity_pbs: concom_pbs,
|
||||||
|
remove_tag_ids: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
fight_buff_infos.dedup_by(|x, z| x.buff_id == z.buff_id);
|
||||||
|
|
||||||
let buf_manager = FightBuff {
|
let buf_manager = FightBuff {
|
||||||
fight_buff_infos,
|
fight_buff_infos,
|
||||||
list_buff_effect_cd: vec![],
|
list_buff_effect_cd: vec![]
|
||||||
};
|
};
|
||||||
|
|
||||||
let entity = world
|
let entity = world
|
||||||
.create_builder(entity)
|
.create_builder(entity)
|
||||||
.with(ComponentContainer::PlayerOwnedEntityMarker(
|
.with(ComponentContainer::PlayerOwnedEntityMarker(
|
||||||
|
@ -151,7 +178,7 @@ pub fn add_player_entities(player: &Player) {
|
||||||
camp: 0,
|
camp: 0,
|
||||||
config_id: role.role_id,
|
config_id: role.role_id,
|
||||||
config_type: EntityConfigType::Character,
|
config_type: EntityConfigType::Character,
|
||||||
entity_type: EEntityType::Player.into(),
|
entity_type: EEntityType::Player,
|
||||||
entity_state: EntityState::Default,
|
entity_state: EntityState::Default,
|
||||||
}))
|
}))
|
||||||
.with(ComponentContainer::OwnerPlayer(OwnerPlayer(
|
.with(ComponentContainer::OwnerPlayer(OwnerPlayer(
|
||||||
|
@ -174,7 +201,7 @@ pub fn add_player_entities(player: &Player) {
|
||||||
)))
|
)))
|
||||||
.with(ComponentContainer::Movement(Movement::default()))
|
.with(ComponentContainer::Movement(Movement::default()))
|
||||||
.with(ComponentContainer::Equip(Equip {
|
.with(ComponentContainer::Equip(Equip {
|
||||||
weapon_id: role.equip_weapon,
|
weapon_id: equip_weapon,
|
||||||
weapon_breach_level: 0, // TODO: store this too
|
weapon_breach_level: 0, // TODO: store this too
|
||||||
}))
|
}))
|
||||||
.with(ComponentContainer::VisionSkill(VisionSkill {
|
.with(ComponentContainer::VisionSkill(VisionSkill {
|
||||||
|
@ -184,24 +211,48 @@ pub fn add_player_entities(player: &Player) {
|
||||||
skin_id: role.skin_id,
|
skin_id: role.skin_id,
|
||||||
}))
|
}))
|
||||||
.with(ComponentContainer::SoarWingSkin(SoarWingSkin {
|
.with(ComponentContainer::SoarWingSkin(SoarWingSkin {
|
||||||
skin_id: role.fly_skin_id,
|
skin_id: 84000001,
|
||||||
}))
|
|
||||||
.with(ComponentContainer::ParaglidingSkin(ParaglidingSkin {
|
|
||||||
skin_id: role.wing_skin_id,
|
|
||||||
}))
|
|
||||||
.with(ComponentContainer::WeaponSkin(WeaponSkin {
|
|
||||||
skin_id: role.weapon_skin_id, // TODO: Is this kept on weapon change
|
|
||||||
}))
|
}))
|
||||||
.with(ComponentContainer::FightBuff(buf_manager))
|
.with(ComponentContainer::FightBuff(buf_manager))
|
||||||
|
.with(ComponentContainer::Concomitant(Concomitant {
|
||||||
|
vision_entity_id: 0,
|
||||||
|
custom_entity_ids: concomitants,
|
||||||
|
phantom_role_id: 0
|
||||||
|
}))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
let mut pb = EntityPb {
|
||||||
|
id: entity.entity_id as i64,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
world
|
||||||
|
.get_entity_components(entity.entity_id)
|
||||||
|
.into_iter()
|
||||||
|
.for_each(|comp| comp.set_pb_data(&mut pb));
|
||||||
|
pbs.push(pb);
|
||||||
|
|
||||||
tracing::debug!(
|
tracing::debug!(
|
||||||
"created player entity, id: {}, role_id: {}",
|
"created player entity, id: {}, role_id: {}",
|
||||||
entity.entity_id,
|
entity.entity_id,
|
||||||
role.role_id
|
role.role_id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
player.notify(EntityAddNotify {
|
||||||
|
entity_pbs: pbs,
|
||||||
|
remove_tag_ids: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_player_entities(player: &Player, formation: &RoleFormation, possible_world: Option<&mut WorldEntity>) {
|
||||||
|
match possible_world {
|
||||||
|
Some(world) => add_player_entity(player, formation, world),
|
||||||
|
None => {
|
||||||
|
let mut world_ref = player.world.borrow_mut();
|
||||||
|
add_player_entity(player, formation, world_ref.get_mut_world_entity())
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_scene_information(player: &Player) -> SceneInformation {
|
pub fn build_scene_information(player: &Player) -> SceneInformation {
|
||||||
|
@ -252,10 +303,11 @@ fn build_player_info_list(world: &World) -> Vec<ScenePlayerInformation> {
|
||||||
world.get_world_entity(),
|
world.get_world_entity(),
|
||||||
PlayerOwnedEntityMarker,
|
PlayerOwnedEntityMarker,
|
||||||
OwnerPlayer,
|
OwnerPlayer,
|
||||||
EntityConfig
|
EntityConfig,
|
||||||
|
RoleSkin
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|(_, _, owner, _)| owner.0 == sp.player_id);
|
.filter(|(_, _, owner, _, _)| owner.0 == sp.player_id);
|
||||||
|
|
||||||
ScenePlayerInformation {
|
ScenePlayerInformation {
|
||||||
cur_role: cur_role_id,
|
cur_role: cur_role_id,
|
||||||
|
@ -272,7 +324,7 @@ fn build_player_info_list(world: &World) -> Vec<ScenePlayerInformation> {
|
||||||
cur_role: cur_role_id,
|
cur_role: cur_role_id,
|
||||||
// is_retain: true,
|
// is_retain: true,
|
||||||
fight_role_infos: active_characters
|
fight_role_infos: active_characters
|
||||||
.map(|(id, _, _, conf)| FightRoleInfo {
|
.map(|(id, _, _, conf, _role_skin)| FightRoleInfo {
|
||||||
entity_id: id.into(),
|
entity_id: id.into(),
|
||||||
role_id: conf.config_id,
|
role_id: conf.config_id,
|
||||||
on_stage_without_control: false,
|
on_stage_without_control: false,
|
||||||
|
@ -438,7 +490,13 @@ pub fn add_entities(player: &Player, entities: &[&LevelEntityConfigData], extern
|
||||||
|
|
||||||
build_autonomous_component(&mut builder, player.basic_info.id, entity_logic);
|
build_autonomous_component(&mut builder, player.basic_info.id, entity_logic);
|
||||||
build_interact_component(&mut builder, &components);
|
build_interact_component(&mut builder, &components);
|
||||||
build_tags_components(&mut builder, &components, player, blueprint_config.unwrap().entity_type, config_id as i64);
|
build_tags_components(
|
||||||
|
&mut builder,
|
||||||
|
&components,
|
||||||
|
player,
|
||||||
|
blueprint_config.unwrap().entity_type,
|
||||||
|
config_id as i64,
|
||||||
|
);
|
||||||
build_attribute_component(&mut builder, &components, player.location.instance_id);
|
build_attribute_component(&mut builder, &components, player.location.instance_id);
|
||||||
build_ai_components(&mut builder, &components);
|
build_ai_components(&mut builder, &components);
|
||||||
added_entities.push(builder.build());
|
added_entities.push(builder.build());
|
||||||
|
@ -504,7 +562,10 @@ fn build_tags_components(
|
||||||
if let Some(entity_state_component) = &components.entity_state_component {
|
if let Some(entity_state_component) = &components.entity_state_component {
|
||||||
let state = match entity_type {
|
let state = match entity_type {
|
||||||
EntityType::Teleporter | EntityType::TemporaryTeleporter => {
|
EntityType::Teleporter | EntityType::TemporaryTeleporter => {
|
||||||
let result = player.teleports.teleports_data.iter()
|
let result = player
|
||||||
|
.teleports
|
||||||
|
.teleports_data
|
||||||
|
.iter()
|
||||||
.find(|teleporter| teleporter.entity_config_id == config_id);
|
.find(|teleporter| teleporter.entity_config_id == config_id);
|
||||||
match result.is_some() {
|
match result.is_some() {
|
||||||
true => tag_utils::get_tag_id_by_name("关卡.Common.状态.激活"),
|
true => tag_utils::get_tag_id_by_name("关卡.Common.状态.激活"),
|
||||||
|
|
|
@ -51,12 +51,12 @@ async fn handler_loop(
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
tracing::debug!(
|
// tracing::debug!(
|
||||||
"received message from service: {}, rpc_id: {} message_id: {}",
|
// "received message from service: {}, rpc_id: {} message_id: {}",
|
||||||
message.src_service_id,
|
// message.src_service_id,
|
||||||
message.rpc_id,
|
// message.rpc_id,
|
||||||
message.message_id
|
// message.message_id
|
||||||
);
|
// );
|
||||||
|
|
||||||
match message.message_id {
|
match message.message_id {
|
||||||
CreatePlayerDataRequest::MESSAGE_ID => {
|
CreatePlayerDataRequest::MESSAGE_ID => {
|
||||||
|
@ -141,7 +141,7 @@ async fn on_start_player_session_request(
|
||||||
player_id: player_data.player_id,
|
player_id: player_data.player_id,
|
||||||
enter_rpc_id: message.rpc_id,
|
enter_rpc_id: message.rpc_id,
|
||||||
session: session.clone(),
|
session: session.clone(),
|
||||||
player_save_data,
|
player_save_data: Box::new(player_save_data),
|
||||||
});
|
});
|
||||||
|
|
||||||
session_mgr.add(session.clone());
|
session_mgr.add(session.clone());
|
||||||
|
|
|
@ -60,9 +60,6 @@ message RoleData {
|
||||||
RoleStats stats = 17;
|
RoleStats stats = 17;
|
||||||
int32 favor_level = 18;
|
int32 favor_level = 18;
|
||||||
int32 favor_exp = 19;
|
int32 favor_exp = 19;
|
||||||
int32 wing_skin_id = 20;
|
|
||||||
int32 fly_skin_id = 21;
|
|
||||||
int32 weapon_skin_id = 22;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message RoleFormationData {
|
message RoleFormationData {
|
||||||
|
@ -138,19 +135,8 @@ message PlayerAdventureStatusData {
|
||||||
repeated PlayerAdventureGlobalStatusData status = 1;
|
repeated PlayerAdventureGlobalStatusData status = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message PlayerInventoryWeaponData {
|
|
||||||
int32 id = 1;
|
|
||||||
int32 func_value = 2;
|
|
||||||
int32 level = 3;
|
|
||||||
int32 exp = 4;
|
|
||||||
int32 breach = 5;
|
|
||||||
int32 reson_level = 6;
|
|
||||||
int32 role_id = 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
message PlayerInventoryData {
|
message PlayerInventoryData {
|
||||||
map<int32, int32> items = 1;
|
map<int32, int32> items = 1;
|
||||||
map<int32, PlayerInventoryWeaponData> weapons = 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message PlayerTeleportData {
|
message PlayerTeleportData {
|
||||||
|
@ -196,13 +182,6 @@ message PlayerMcElementData {
|
||||||
PlayerMcElementType current_element = 2;
|
PlayerMcElementType current_element = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message PlayerUnlockedSkinsData {
|
|
||||||
repeated int32 role_skins = 1;
|
|
||||||
repeated int32 weapon_skins = 2;
|
|
||||||
repeated int32 fly_skins = 3;
|
|
||||||
repeated int32 wing_skins = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
message PlayerSaveData {
|
message PlayerSaveData {
|
||||||
PlayerBasicData basic_data = 1;
|
PlayerBasicData basic_data = 1;
|
||||||
PlayerRoleData role_data = 2;
|
PlayerRoleData role_data = 2;
|
||||||
|
@ -219,5 +198,4 @@ message PlayerSaveData {
|
||||||
PlayerMapTraceData map_trace = 13;
|
PlayerMapTraceData map_trace = 13;
|
||||||
PlayerMonthCardData month_card = 14;
|
PlayerMonthCardData month_card = 14;
|
||||||
PlayerMcElementData mc_element = 15;
|
PlayerMcElementData mc_element = 15;
|
||||||
PlayerUnlockedSkinsData unlocked_skins = 16;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue