diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c497e9c1c1..4967ab327b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -13,7 +13,7 @@ variables: # https://docs.gitlab.com/ee/ci/yaml/#shallow-cloning GIT_DEPTH: 3 GIT_CLEAN_FLAGS: -f - CACHE_IMAGE_TAG: 55629eab + CACHE_IMAGE_TAG: 8490f4b9 default: # https://docs.gitlab.com/ee/ci/pipelines/settings.html#auto-cancel-pending-pipelines diff --git a/CHANGELOG.md b/CHANGELOG.md index 2694d34f41..6ad28d3149 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,14 +9,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added a skill tree for mining, which gains xp from mining ores and gems. +- Added debug line info to release builds, enhancing the usefulness of panic backtraces +- NPCs and animals can now make sounds in response to certain events +- Players can press H to greet others ### Changed - Entity-entity pushback is no longer applied in forced movement states like rolling and leaping. +- Updated audio library (rodio 0.13 -> 0.14). ### Removed ### Fixed +- Cases where no audio output could be produced before. +- Significantly improved the performance of playing sound effects + ## [0.10.0] - 2021-06-12 ### Added diff --git a/Cargo.lock b/Cargo.lock index bc9c6669c8..7ae92f7488 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -619,15 +619,6 @@ dependencies = [ "objc_id", ] -[[package]] -name = "clipboard_wayland" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61bcb8cde0387fde807b9b7af66ce8bd1665ef736e46e6e47fda82ea003e6ade" -dependencies = [ - "smithay-clipboard", -] - [[package]] name = "clipboard_wayland" version = "0.2.0" @@ -637,16 +628,6 @@ dependencies = [ "smithay-clipboard", ] -[[package]] -name = "clipboard_x11" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40403aa5220e5cd303d32dc4248cac8aa92bf47e3ae31e0e2481081755a63ff1" -dependencies = [ - "thiserror", - "x11rb", -] - [[package]] name = "clipboard_x11" version = "0.3.1" @@ -937,8 +918,8 @@ dependencies = [ "lazy_static", "libc", "mach 0.3.2", - "ndk 0.3.0", - "ndk-glue 0.3.0", + "ndk", + "ndk-glue", "nix 0.20.0", "oboe", "parking_lot 0.11.1", @@ -1060,6 +1041,20 @@ dependencies = [ "itertools 0.9.0", ] +[[package]] +name = "crossbeam" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-channel", + "crossbeam-deque 0.8.0", + "crossbeam-epoch 0.9.5", + "crossbeam-queue", + "crossbeam-utils 0.8.5", +] + [[package]] name = "crossbeam-channel" version = "0.5.1" @@ -2449,13 +2444,13 @@ dependencies = [ [[package]] name = "iced_core" -version = "0.3.0" -source = "git+https://github.com/hecrj/iced?rev=8d882d787e6b7fd7c2435f42f82933e2ed904edf#8d882d787e6b7fd7c2435f42f82933e2ed904edf" +version = "0.4.0" +source = "git+https://github.com/Imberflur/iced?tag=winit-0.25#18a48a5eeefd2aa6e50f5dd0751ac2e94c88a9eb" [[package]] name = "iced_futures" -version = "0.2.0" -source = "git+https://github.com/hecrj/iced?rev=8d882d787e6b7fd7c2435f42f82933e2ed904edf#8d882d787e6b7fd7c2435f42f82933e2ed904edf" +version = "0.3.0" +source = "git+https://github.com/Imberflur/iced?tag=winit-0.25#18a48a5eeefd2aa6e50f5dd0751ac2e94c88a9eb" dependencies = [ "futures", "log", @@ -2464,8 +2459,8 @@ dependencies = [ [[package]] name = "iced_graphics" -version = "0.1.0" -source = "git+https://github.com/hecrj/iced?rev=8d882d787e6b7fd7c2435f42f82933e2ed904edf#8d882d787e6b7fd7c2435f42f82933e2ed904edf" +version = "0.2.0" +source = "git+https://github.com/Imberflur/iced?tag=winit-0.25#18a48a5eeefd2aa6e50f5dd0751ac2e94c88a9eb" dependencies = [ "bytemuck", "glam", @@ -2477,8 +2472,8 @@ dependencies = [ [[package]] name = "iced_native" -version = "0.3.0" -source = "git+https://github.com/hecrj/iced?rev=8d882d787e6b7fd7c2435f42f82933e2ed904edf#8d882d787e6b7fd7c2435f42f82933e2ed904edf" +version = "0.4.0" +source = "git+https://github.com/Imberflur/iced?tag=winit-0.25#18a48a5eeefd2aa6e50f5dd0751ac2e94c88a9eb" dependencies = [ "iced_core", "iced_futures", @@ -2489,16 +2484,16 @@ dependencies = [ [[package]] name = "iced_style" -version = "0.2.0" -source = "git+https://github.com/hecrj/iced?rev=8d882d787e6b7fd7c2435f42f82933e2ed904edf#8d882d787e6b7fd7c2435f42f82933e2ed904edf" +version = "0.3.0" +source = "git+https://github.com/Imberflur/iced?tag=winit-0.25#18a48a5eeefd2aa6e50f5dd0751ac2e94c88a9eb" dependencies = [ "iced_core", ] [[package]] name = "iced_winit" -version = "0.2.0" -source = "git+https://github.com/hecrj/iced?rev=8d882d787e6b7fd7c2435f42f82933e2ed904edf#8d882d787e6b7fd7c2435f42f82933e2ed904edf" +version = "0.3.0" +source = "git+https://github.com/Imberflur/iced?tag=winit-0.25#18a48a5eeefd2aa6e50f5dd0751ac2e94c88a9eb" dependencies = [ "iced_futures", "iced_graphics", @@ -2506,7 +2501,7 @@ dependencies = [ "log", "thiserror", "winapi 0.3.9", - "window_clipboard 0.1.4", + "window_clipboard", "winit", ] @@ -2700,7 +2695,7 @@ dependencies = [ [[package]] name = "keyboard-keynames" version = "0.1.0" -source = "git+https://gitlab.com/Frinksy/keyboard-keynames.git?rev=a97ae509cdb9dc70cf1bf0af762d2d1d3a0d6e0c#a97ae509cdb9dc70cf1bf0af762d2d1d3a0d6e0c" +source = "git+https://gitlab.com/Frinksy/keyboard-keynames.git?rev=9ae8f89014d0b0c5b61d0e821c5aeb6140c5c0dc#9ae8f89014d0b0c5b61d0e821c5aeb6140c5c0dc" dependencies = [ "libc", "memmap", @@ -3091,6 +3086,18 @@ dependencies = [ "slab", ] +[[package]] +name = "mio-misc" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ddf05411bb159cdb5801bb10002afb66cb4572be656044315e363460ce69dc2" +dependencies = [ + "crossbeam", + "crossbeam-queue", + "log", + "mio 0.7.11", +] + [[package]] name = "miow" version = "0.2.2" @@ -3160,18 +3167,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "ndk" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb167c1febed0a496639034d0c76b3b74263636045db5489eee52143c246e73" -dependencies = [ - "jni-sys", - "ndk-sys", - "num_enum 0.4.3", - "thiserror", -] - [[package]] name = "ndk" version = "0.3.0" @@ -3180,24 +3175,10 @@ checksum = "8794322172319b972f528bf90c6b467be0079f1fa82780ffb431088e741a73ab" dependencies = [ "jni-sys", "ndk-sys", - "num_enum 0.5.1", + "num_enum", "thiserror", ] -[[package]] -name = "ndk-glue" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf399b8b7a39c6fb153c4ec32c72fd5fe789df24a647f229c239aa7adb15241" -dependencies = [ - "lazy_static", - "libc", - "log", - "ndk 0.2.1", - "ndk-macro", - "ndk-sys", -] - [[package]] name = "ndk-glue" version = "0.3.0" @@ -3207,7 +3188,7 @@ dependencies = [ "lazy_static", "libc", "log", - "ndk 0.3.0", + "ndk", "ndk-macro", "ndk-sys", ] @@ -3528,16 +3509,6 @@ dependencies = [ "libc", ] -[[package]] -name = "num_enum" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca565a7df06f3d4b485494f25ba05da1435950f4dc263440eda7a6fa9b8e36e4" -dependencies = [ - "derivative", - "num_enum_derive 0.4.3", -] - [[package]] name = "num_enum" version = "0.5.1" @@ -3545,19 +3516,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "226b45a5c2ac4dd696ed30fa6b94b057ad909c7b7fc2e0d0808192bced894066" dependencies = [ "derivative", - "num_enum_derive 0.5.1", -] - -[[package]] -name = "num_enum_derive" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffa5a33ddddfee04c0283a7653987d634e880347e96b5b2ed64de07efb59db9d" -dependencies = [ - "proc-macro-crate", - "proc-macro2 1.0.27", - "quote 1.0.9", - "syn 1.0.72", + "num_enum_derive", ] [[package]] @@ -3637,8 +3596,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa187b38ae20374617b7ad418034ed3dc90ac980181d211518bd03537ae8f8d" dependencies = [ "jni", - "ndk 0.3.0", - "ndk-glue 0.3.0", + "ndk", + "ndk-glue", "num-derive", "num-traits", "oboe-sys", @@ -4440,9 +4399,9 @@ dependencies = [ [[package]] name = "rodio" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b65c2eda643191f6d1bb12ea323a9db8d9ba95374e9be3780b5a9fb5cfb8520f" +checksum = "4d98f5e557b61525057e2bc142c8cd7f0e70d75dc32852309bec440e6e046bf9" dependencies = [ "cpal", "lewton", @@ -6215,7 +6174,7 @@ dependencies = [ "veloren-world", "wgpu", "wgpu-profiler", - "window_clipboard 0.2.1", + "window_clipboard", "winit", "winres", ] @@ -6825,7 +6784,7 @@ dependencies = [ [[package]] name = "wgpu" version = "0.8.0" -source = "git+https://github.com/gfx-rs/wgpu-rs.git?rev=7486bdad64bb5d17b709ecccb41e063469efff88#7486bdad64bb5d17b709ecccb41e063469efff88" +source = "git+https://github.com/gfx-rs/wgpu.git?rev=a92b8549a8e2cb9dac781bafc5ed32828f3caf46#a92b8549a8e2cb9dac781bafc5ed32828f3caf46" dependencies = [ "arrayvec", "js-sys", @@ -6845,7 +6804,7 @@ dependencies = [ [[package]] name = "wgpu-core" version = "0.8.0" -source = "git+https://github.com/gfx-rs/wgpu?rev=53eab747a32414232be45d47cae8a43a369395d0#53eab747a32414232be45d47cae8a43a369395d0" +source = "git+https://github.com/gfx-rs/wgpu.git?rev=a92b8549a8e2cb9dac781bafc5ed32828f3caf46#a92b8549a8e2cb9dac781bafc5ed32828f3caf46" dependencies = [ "arrayvec", "bitflags", @@ -6885,7 +6844,7 @@ dependencies = [ [[package]] name = "wgpu-types" version = "0.8.0" -source = "git+https://github.com/gfx-rs/wgpu?rev=53eab747a32414232be45d47cae8a43a369395d0#53eab747a32414232be45d47cae8a43a369395d0" +source = "git+https://github.com/gfx-rs/wgpu.git?rev=a92b8549a8e2cb9dac781bafc5ed32828f3caf46#a92b8549a8e2cb9dac781bafc5ed32828f3caf46" dependencies = [ "bitflags", "serde", @@ -6953,19 +6912,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "window_clipboard" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37cf16659e398a96f4ab8deff2b9db2ca0c3c5d6c1b59b1d577b7f888f0f03c6" -dependencies = [ - "clipboard-win 4.2.1", - "clipboard_macos", - "clipboard_wayland 0.1.2", - "clipboard_x11 0.2.0", - "raw-window-handle", -] - [[package]] name = "window_clipboard" version = "0.2.1" @@ -6974,15 +6920,16 @@ checksum = "33a4518b538a45ad39d138a8c3bea8f6b4452174aeb38143d1dd643a3a838ccc" dependencies = [ "clipboard-win 4.2.1", "clipboard_macos", - "clipboard_wayland 0.2.0", - "clipboard_x11 0.3.1", + "clipboard_wayland", + "clipboard_x11", "raw-window-handle", ] [[package]] name = "winit" -version = "0.24.0" -source = "git+https://gitlab.com/veloren/winit.git?branch=macos-test-spiffed#488c511802dfd95ca54f6f76a38547c93c7b02c9" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79610794594d5e86be473ef7763f604f2159cbac8c94debd00df8fb41e86c2f8" dependencies = [ "bitflags", "cocoa", @@ -6994,15 +6941,16 @@ dependencies = [ "lazy_static", "libc", "log", - "mio 0.6.23", - "mio-extras", - "ndk 0.2.1", - "ndk-glue 0.2.1", + "mio 0.7.11", + "mio-misc", + "ndk", + "ndk-glue", "ndk-sys", "objc", "parking_lot 0.11.1", "percent-encoding", "raw-window-handle", + "scopeguard", "serde", "smithay-client-toolkit", "wayland-client 0.28.5", diff --git a/Cargo.toml b/Cargo.toml index 114aa4e683..d66acc620e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -89,7 +89,8 @@ opt-level = 3 overflow-checks = false debug-assertions = false lto = true -debug = false +debug = 1 # line tables so we can have useful backtraces +panic = "abort" # don't need unwinding so we can skip including the landing pads for that # used for cargo bench [profile.bench] @@ -113,11 +114,9 @@ buildInputs = ["openssl"] nativeBuildInputs = ["pkg-config"] [patch.crates-io] -# macos CI fix isn't released yet -winit = { git = "https://gitlab.com/veloren/winit.git", branch = "macos-test-spiffed" } vek = { git = "https://gitlab.com/veloren/vek.git", branch = "fix_intrinsics2" } # patch wgpu so we can use wgpu-profiler crate -wgpu = { git = "https://github.com/gfx-rs/wgpu-rs.git", rev = "7486bdad64bb5d17b709ecccb41e063469efff88" } +wgpu = { git = "https://github.com/gfx-rs/wgpu.git", rev = "a92b8549a8e2cb9dac781bafc5ed32828f3caf46" } # # use the latest fixes in naga (remove when updates trickle down to wgpu-rs) # naga = { git = "https://github.com/gfx-rs/naga.git", rev = "3a0f0144112ff621dd7f731bf455adf6cab19164" } diff --git a/assets/common/abilities/ability_set_manifest.ron b/assets/common/abilities/ability_set_manifest.ron index 6a3c4f4f57..12eb751aad 100644 --- a/assets/common/abilities/ability_set_manifest.ron +++ b/assets/common/abilities/ability_set_manifest.ron @@ -149,13 +149,20 @@ abilities: [], ), Custom("Basilisk"): ( - primary: "common.abilities.custom.basilisk.singlestrike", + primary: "common.abilities.custom.basilisk.petrify", secondary: "common.abilities.custom.basilisk.triplestrike", + abilities: [ + (None, "common.abilities.custom.basilisk.dash"), + ], + ), + Custom("Asp"): ( + primary: "common.abilities.custom.asp.singlestrike", + secondary: "common.abilities.custom.asp.firebomb", abilities: [], ), - Custom("Quad Low Ranged"): ( - primary: "common.abilities.custom.quadlowranged.singlestrike", - secondary: "common.abilities.custom.quadlowranged.firebomb", + Custom("Maneater"): ( + primary: "common.abilities.custom.maneater.singlestrike", + secondary: "common.abilities.custom.maneater.poisonball", abilities: [], ), Custom("Quad Low Breathe"): ( @@ -264,6 +271,18 @@ (None, "common.abilities.custom.birdlargefire.fireshockwave"), ], ), + Custom("Bird Large Basic"): ( + primary: "common.abilities.custom.birdlargebasic.triplestrike", + secondary: "common.abilities.custom.birdlargebasic.summontornadoes", + abilities: [ + (None, "common.abilities.custom.birdlargebasic.dash"), + ], + ), + Custom("Tornado"): ( + primary: "common.abilities.custom.tornado.spin", + secondary: "common.abilities.empty.basic", + abilities: [], + ), Tool(Debug): ( primary: "common.abilities.debug.forwardboost", secondary: "common.abilities.debug.upboost", diff --git a/assets/common/abilities/axe/doublestrike.ron b/assets/common/abilities/axe/doublestrike.ron index 545aab3ae9..80de5e37e0 100644 --- a/assets/common/abilities/axe/doublestrike.ron +++ b/assets/common/abilities/axe/doublestrike.ron @@ -6,11 +6,12 @@ ComboMelee( base_poise_damage: 12, damage_increase: 10, poise_damage_increase: 0, - knockback: 8.0, + knockback: 5.0, range: 3.5, angle: 50.0, base_buildup_duration: 0.15, base_swing_duration: 0.075, + hit_timing: 0.6, base_recover_duration: 0.35, forward_movement: 0.5, damage_kind: Slashing, @@ -21,11 +22,12 @@ ComboMelee( base_poise_damage: 20, damage_increase: 15, poise_damage_increase: 0, - knockback: 12.0, + knockback: 6.0, range: 3.5, angle: 30.0, base_buildup_duration: 0.2, base_swing_duration: 0.1, + hit_timing: 0.6, base_recover_duration: 0.35, forward_movement: 0.25, damage_kind: Slashing, diff --git a/assets/common/abilities/axesimple/doublestrike.ron b/assets/common/abilities/axesimple/doublestrike.ron index 2a87b78073..d97b3dbcce 100644 --- a/assets/common/abilities/axesimple/doublestrike.ron +++ b/assets/common/abilities/axesimple/doublestrike.ron @@ -11,6 +11,7 @@ ComboMelee( angle: 50.0, base_buildup_duration: 0.6, base_swing_duration: 0.12, + hit_timing: 0.5, base_recover_duration: 0.6, forward_movement: 3.5, damage_kind: Slashing, @@ -26,6 +27,7 @@ ComboMelee( angle: 15.0, base_buildup_duration: 0.5, base_swing_duration: 0.15, + hit_timing: 0.5, base_recover_duration: 1.2, forward_movement: 4.5, damage_kind: Slashing, diff --git a/assets/common/abilities/custom/asp/firebomb.ron b/assets/common/abilities/custom/asp/firebomb.ron new file mode 100644 index 0000000000..383f35ee39 --- /dev/null +++ b/assets/common/abilities/custom/asp/firebomb.ron @@ -0,0 +1,18 @@ +BasicRanged( + energy_cost: 0, + buildup_duration: 0.8, + recover_duration: 0.35, + projectile: Fireball( + damage: 130.0, + radius: 5.0, + energy_regen: 0, + ), + projectile_body: Object(BoltFire), + /*projectile_light: Some(LightEmitter { + col: (1.0, 0.75, 0.11).into(), + ..Default::default() + }),*/ + projectile_speed: 70.0, + num_projectiles: 1, + projectile_spread: 0.0, +) diff --git a/assets/common/abilities/custom/quadlowranged/singlestrike.ron b/assets/common/abilities/custom/asp/singlestrike.ron similarity index 75% rename from assets/common/abilities/custom/quadlowranged/singlestrike.ron rename to assets/common/abilities/custom/asp/singlestrike.ron index 7d36295027..ec3acbcd37 100644 --- a/assets/common/abilities/custom/quadlowranged/singlestrike.ron +++ b/assets/common/abilities/custom/asp/singlestrike.ron @@ -2,17 +2,18 @@ ComboMelee( stage_data: [ ( stage: 1, - base_damage: 80, + base_damage: 140, damage_increase: 0, base_poise_damage: 28, poise_damage_increase: 0, knockback: 3.0, range: 3.5, angle: 60.0, - base_buildup_duration: 0.4, + base_buildup_duration: 0.6, base_swing_duration: 0.1, - base_recover_duration: 0.4, - forward_movement: 3.0, + hit_timing: 0.5, + base_recover_duration: 0.2, + forward_movement: 2.0, damage_kind: Crushing, ), ], diff --git a/assets/common/abilities/custom/basilisk/dash.ron b/assets/common/abilities/custom/basilisk/dash.ron new file mode 100644 index 0000000000..8221e8092d --- /dev/null +++ b/assets/common/abilities/custom/basilisk/dash.ron @@ -0,0 +1,20 @@ +DashMelee( + energy_cost: 0, + base_damage: 120, + scaled_damage: 180, + base_poise_damage: 25, + scaled_poise_damage: 0, + base_knockback: 4.0, + scaled_knockback: 17.0, + range: 2.5, + angle: 45.0, + energy_drain: 0, + forward_speed: 4.0, + buildup_duration: 0.8, + charge_duration: 1.0, + swing_duration: 0.1, + recover_duration: 1.0, + charge_through: true, + is_interruptible: false, + damage_kind: Crushing, +) diff --git a/assets/common/abilities/custom/basilisk/petrify.ron b/assets/common/abilities/custom/basilisk/petrify.ron new file mode 100644 index 0000000000..c8fb5b3021 --- /dev/null +++ b/assets/common/abilities/custom/basilisk/petrify.ron @@ -0,0 +1,19 @@ +BasicBeam( + buildup_duration: 0.9, + recover_duration: 1.0, + beam_duration: 1.0, + damage: 420, + tick_rate: 0.5, + range: 22.0, + max_angle: 5.0, + damage_effect: Some(Buff(( + kind: Frozen, + dur_secs: 0.8, + strength: Value(5.0), + chance: 1.0, + ))), + energy_regen: 0, + energy_drain: 0, + orientation_behavior: Normal, + specifier: Cultist, +) \ No newline at end of file diff --git a/assets/common/abilities/custom/basilisk/triplestrike.ron b/assets/common/abilities/custom/basilisk/triplestrike.ron index fced56cfda..db05cf3e26 100644 --- a/assets/common/abilities/custom/basilisk/triplestrike.ron +++ b/assets/common/abilities/custom/basilisk/triplestrike.ron @@ -2,45 +2,48 @@ ComboMelee( stage_data: [ ( stage: 1, - base_damage: 100, + base_damage: 180, damage_increase: 0, base_poise_damage: 15, poise_damage_increase: 0, - knockback: 7.0, + knockback: 3.0, range: 2.8, angle: 30.0, - base_buildup_duration: 0.65, + base_buildup_duration: 0.7, base_swing_duration: 0.07, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 2.0, damage_kind: Crushing, ), ( stage: 2, - base_damage: 100, + base_damage: 180, damage_increase: 0, base_poise_damage: 18, poise_damage_increase: 0, - knockback: 7.0, + knockback: 3.0, range: 2.8, angle: 30.0, base_buildup_duration: 0.4, base_swing_duration: 0.07, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 1.5, damage_kind: Crushing, ), ( stage: 3, - base_damage: 100, + base_damage: 180, damage_increase: 0, base_poise_damage: 20, poise_damage_increase: 0, - knockback: 7.0, + knockback: 3.0, range: 2.8, angle: 30.0, base_buildup_duration: 0.4, base_swing_duration: 0.07, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 1.5, damage_kind: Crushing, diff --git a/assets/common/abilities/custom/birdlargebasic/dash.ron b/assets/common/abilities/custom/birdlargebasic/dash.ron new file mode 100644 index 0000000000..0760657973 --- /dev/null +++ b/assets/common/abilities/custom/birdlargebasic/dash.ron @@ -0,0 +1,20 @@ +DashMelee( + energy_cost: 0, + base_damage: 80, + scaled_damage: 150, + base_poise_damage: 50, + scaled_poise_damage: 100, + base_knockback: 6.0, + scaled_knockback: 12.0, + range: 2.0, + angle: 20.0, + energy_drain: 0, + forward_speed: 1.9, + buildup_duration: 0.5, + charge_duration: 3.0, + swing_duration: 0.1, + recover_duration: 0.7, + charge_through: false, + is_interruptible: false, + damage_kind: Crushing, +) diff --git a/assets/common/abilities/custom/birdlargebasic/summontornadoes.ron b/assets/common/abilities/custom/birdlargebasic/summontornadoes.ron new file mode 100644 index 0000000000..66240b64a6 --- /dev/null +++ b/assets/common/abilities/custom/birdlargebasic/summontornadoes.ron @@ -0,0 +1,18 @@ +BasicSummon( + buildup_duration: 0.5, + cast_duration: 0.2, + recover_duration: 0.2, + summon_amount: 12, + summon_distance: (4, 9), + summon_info: ( + body: Object(Tornado), + scale: None, + health_scaling: None, + loadout_config: None, + skillset_config: None, + ), + duration: Some(( + secs: 10, + nanos: 0, + )), +) \ No newline at end of file diff --git a/assets/common/abilities/custom/birdlargebasic/triplestrike.ron b/assets/common/abilities/custom/birdlargebasic/triplestrike.ron new file mode 100644 index 0000000000..ae24969a40 --- /dev/null +++ b/assets/common/abilities/custom/birdlargebasic/triplestrike.ron @@ -0,0 +1,60 @@ +ComboMelee( + stage_data: [ + ( + stage: 1, + base_damage: 110, + damage_increase: 0, + base_poise_damage: 0, + poise_damage_increase: 0, + knockback: 5.0, + range: 4.5, + angle: 30.0, + base_buildup_duration: 0.4, + base_swing_duration: 0.1, + hit_timing: 0.5, + base_recover_duration: 0.3, + forward_movement: 3.0, + damage_kind: Crushing, + ), + ( + stage: 2, + base_damage: 90, + damage_increase: 0, + base_poise_damage: 0, + poise_damage_increase: 0, + knockback: 5.0, + range: 3.5, + angle: 30.0, + base_buildup_duration: 0.4, + base_swing_duration: 0.1, + hit_timing: 0.5, + base_recover_duration: 0.3, + forward_movement: 3.0, + damage_kind: Crushing, + ), + ( + stage: 3, + base_damage: 140, + damage_increase: 0, + base_poise_damage: 0, + poise_damage_increase: 0, + knockback: 10.0, + range: 3.5, + angle: 30.0, + base_buildup_duration: 0.65, + base_swing_duration: 0.1, + hit_timing: 0.5, + base_recover_duration: 0.3, + forward_movement: 3.5, + damage_kind: Crushing, + ), + ], + initial_energy_gain: 0, + max_energy_gain: 0, + energy_increase: 0, + speed_increase: 0.0, + max_speed_increase: 0.0, + scales_from_combo: 0, + is_interruptible: false, + ori_modifier: 0.7, +) diff --git a/assets/common/abilities/custom/birdlargebreathe/triplestrike.ron b/assets/common/abilities/custom/birdlargebreathe/triplestrike.ron index eb332435a4..b0a727e645 100644 --- a/assets/common/abilities/custom/birdlargebreathe/triplestrike.ron +++ b/assets/common/abilities/custom/birdlargebreathe/triplestrike.ron @@ -11,6 +11,7 @@ ComboMelee( angle: 30.0, base_buildup_duration: 0.4, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 2.0, damage_kind: Slashing, @@ -26,6 +27,7 @@ ComboMelee( angle: 30.0, base_buildup_duration: 0.4, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 1.5, damage_kind: Slashing, @@ -41,6 +43,7 @@ ComboMelee( angle: 30.0, base_buildup_duration: 0.65, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 1.5, damage_kind: Slashing, diff --git a/assets/common/abilities/custom/birdlargefire/triplestrike.ron b/assets/common/abilities/custom/birdlargefire/triplestrike.ron index eb332435a4..b0a727e645 100644 --- a/assets/common/abilities/custom/birdlargefire/triplestrike.ron +++ b/assets/common/abilities/custom/birdlargefire/triplestrike.ron @@ -11,6 +11,7 @@ ComboMelee( angle: 30.0, base_buildup_duration: 0.4, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 2.0, damage_kind: Slashing, @@ -26,6 +27,7 @@ ComboMelee( angle: 30.0, base_buildup_duration: 0.4, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 1.5, damage_kind: Slashing, @@ -41,6 +43,7 @@ ComboMelee( angle: 30.0, base_buildup_duration: 0.65, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 1.5, damage_kind: Slashing, diff --git a/assets/common/abilities/custom/husk/singlestrike.ron b/assets/common/abilities/custom/husk/singlestrike.ron index 5d4aa94c8b..d64184bfa8 100644 --- a/assets/common/abilities/custom/husk/singlestrike.ron +++ b/assets/common/abilities/custom/husk/singlestrike.ron @@ -2,15 +2,16 @@ ComboMelee( stage_data: [ ( stage: 1, - base_damage: 90, + base_damage: 160, damage_increase: 0, base_poise_damage: 12, poise_damage_increase: 0, knockback: 5.0, - range: 3.5, + range: 2.5, angle: 60.0, base_buildup_duration: 0.25, base_swing_duration: 0.07, + hit_timing: 0.5, base_recover_duration: 0.25, forward_movement: 0.5, damage_kind: Crushing, diff --git a/assets/common/abilities/custom/husk/triplestrike.ron b/assets/common/abilities/custom/husk/triplestrike.ron index d14f182feb..d4b66e6a50 100644 --- a/assets/common/abilities/custom/husk/triplestrike.ron +++ b/assets/common/abilities/custom/husk/triplestrike.ron @@ -2,45 +2,48 @@ ComboMelee( stage_data: [ ( stage: 1, - base_damage: 120, + base_damage: 160, damage_increase: 0, - base_poise_damage: 8, + base_poise_damage: 6, poise_damage_increase: 0, - knockback: 5.0, - range: 3.5, + knockback: 3.0, + range: 2.5, angle: 30.0, base_buildup_duration: 0.2, base_swing_duration: 0.07, + hit_timing: 0.5, base_recover_duration: 0.2, forward_movement: 1.0, damage_kind: Crushing, ), ( stage: 2, - base_damage: 120, + base_damage: 160, damage_increase: 0, - base_poise_damage: 10, + base_poise_damage: 8, poise_damage_increase: 0, - knockback: 5.0, - range: 3.5, + knockback: 3.0, + range: 2.5, angle: 30.0, base_buildup_duration: 0.22, base_swing_duration: 0.07, + hit_timing: 0.5, base_recover_duration: 0.2, forward_movement: 0.0, damage_kind: Crushing, ), ( stage: 3, - base_damage: 120, + base_damage: 160, damage_increase: 0, - base_poise_damage: 12, + base_poise_damage: 10, poise_damage_increase: 0, - knockback: 5.0, - range: 3.5, + knockback: 3.0, + range: 2.5, angle: 30.0, base_buildup_duration: 0.2, base_swing_duration: 0.07, + hit_timing: 0.5, base_recover_duration: 0.2, forward_movement: 1.0, damage_kind: Crushing, diff --git a/assets/common/abilities/custom/maneater/poisonball.ron b/assets/common/abilities/custom/maneater/poisonball.ron new file mode 100644 index 0000000000..f8a2b14c9b --- /dev/null +++ b/assets/common/abilities/custom/maneater/poisonball.ron @@ -0,0 +1,18 @@ +BasicRanged( + energy_cost: 0, + buildup_duration: 0.8, + recover_duration: 0.35, + projectile: NecroticSphere( + damage: 260.0, + radius: 5.0, + energy_regen: 0, + ), + projectile_body: Object(FireworkPurple), + /*projectile_light: Some(LightEmitter { + col: (1.0, 0.75, 0.11).into(), + ..Default::default() + }),*/ + projectile_speed: 70.0, + num_projectiles: 3, + projectile_spread: 0.2, +) diff --git a/assets/common/abilities/custom/basilisk/singlestrike.ron b/assets/common/abilities/custom/maneater/singlestrike.ron similarity index 63% rename from assets/common/abilities/custom/basilisk/singlestrike.ron rename to assets/common/abilities/custom/maneater/singlestrike.ron index 3f21ccc88a..45ebb89522 100644 --- a/assets/common/abilities/custom/basilisk/singlestrike.ron +++ b/assets/common/abilities/custom/maneater/singlestrike.ron @@ -2,17 +2,18 @@ ComboMelee( stage_data: [ ( stage: 1, - base_damage: 130, + base_damage: 200, damage_increase: 0, base_poise_damage: 28, poise_damage_increase: 0, knockback: 3.0, - range: 3.0, + range: 3.5, angle: 60.0, - base_buildup_duration: 0.4, - base_swing_duration: 0.07, - base_recover_duration: 0.4, - forward_movement: 3.0, + base_buildup_duration: 0.5, + base_swing_duration: 0.075, + hit_timing: 0.5, + base_recover_duration: 0.2, + forward_movement: 2.0, damage_kind: Crushing, ), ], @@ -23,5 +24,5 @@ ComboMelee( max_speed_increase: 0.0, scales_from_combo: 0, is_interruptible: false, - ori_modifier: 0.6, + ori_modifier: 0.65, ) diff --git a/assets/common/abilities/custom/mindflayer/necroticsphere.ron b/assets/common/abilities/custom/mindflayer/necroticsphere.ron index e8ab890b78..08c2039552 100644 --- a/assets/common/abilities/custom/mindflayer/necroticsphere.ron +++ b/assets/common/abilities/custom/mindflayer/necroticsphere.ron @@ -3,7 +3,7 @@ BasicRanged( buildup_duration: 0.75, recover_duration: 0.4, projectile: NecroticSphere( - damage: 300.0, + damage: 450.0, radius: 5.0, ), projectile_body: Object(FireworkPurple), diff --git a/assets/common/abilities/custom/mindflayer/necroticvortex.ron b/assets/common/abilities/custom/mindflayer/necroticvortex.ron index 896b380b62..b4d750fea2 100644 --- a/assets/common/abilities/custom/mindflayer/necroticvortex.ron +++ b/assets/common/abilities/custom/mindflayer/necroticvortex.ron @@ -1,12 +1,12 @@ SpinMelee( - buildup_duration: 0.5, + buildup_duration: 0.8, swing_duration: 0.2, recover_duration: 0.6, base_damage: 80.0, base_poise_damage: 1.0, knockback: ( strength: 7.0, direction: Towards), range: 16.0, - damage_effect: Some(Lifesteal(1.0)), + damage_effect: Some(Lifesteal(2.0)), energy_cost: 0.0, is_infinite: true, movement_behavior: Stationary, diff --git a/assets/common/abilities/custom/mindflayer/summonminions.ron b/assets/common/abilities/custom/mindflayer/summonminions.ron index 99117ce2c0..7fdfb01ec1 100644 --- a/assets/common/abilities/custom/mindflayer/summonminions.ron +++ b/assets/common/abilities/custom/mindflayer/summonminions.ron @@ -3,14 +3,16 @@ BasicSummon( cast_duration: 1.0, recover_duration: 0.5, summon_amount: 6, + summon_distance: (3, 3), summon_info: ( body: BipedSmall(( species: Husk, body_type: Male, )), scale: None, - health_scaling: 80, + health_scaling: Some(80), loadout_config: Some(HuskSummon), skillset_config: None, ), + duration: None, ) diff --git a/assets/common/abilities/custom/quadlowbasic/singlestrike.ron b/assets/common/abilities/custom/quadlowbasic/singlestrike.ron index 8f60297e99..d0ce162fcd 100644 --- a/assets/common/abilities/custom/quadlowbasic/singlestrike.ron +++ b/assets/common/abilities/custom/quadlowbasic/singlestrike.ron @@ -2,15 +2,16 @@ ComboMelee( stage_data: [ ( stage: 1, - base_damage: 100, + base_damage: 200, damage_increase: 0, base_poise_damage: 28, poise_damage_increase: 0, knockback: 3.0, range: 2.0, angle: 60.0, - base_buildup_duration: 0.4, + base_buildup_duration: 0.6, base_swing_duration: 0.07, + hit_timing: 0.5, base_recover_duration: 0.4, forward_movement: 3.0, damage_kind: Crushing, diff --git a/assets/common/abilities/custom/quadlowbasic/triplestrike.ron b/assets/common/abilities/custom/quadlowbasic/triplestrike.ron index 3fae8726f5..db548b316b 100644 --- a/assets/common/abilities/custom/quadlowbasic/triplestrike.ron +++ b/assets/common/abilities/custom/quadlowbasic/triplestrike.ron @@ -2,45 +2,48 @@ ComboMelee( stage_data: [ ( stage: 1, - base_damage: 80, + base_damage: 140, damage_increase: 0, base_poise_damage: 15, poise_damage_increase: 0, - knockback: 7.0, + knockback: 3.0, range: 2.2, angle: 30.0, base_buildup_duration: 0.65, base_swing_duration: 0.07, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 2.0, damage_kind: Crushing, ), ( stage: 2, - base_damage: 80, + base_damage: 140, damage_increase: 0, base_poise_damage: 18, poise_damage_increase: 0, - knockback: 7.0, + knockback: 3.0, range: 2.2, angle: 30.0, base_buildup_duration: 0.4, base_swing_duration: 0.07, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 1.5, damage_kind: Crushing, ), ( stage: 3, - base_damage: 80, + base_damage: 140, damage_increase: 0, base_poise_damage: 20, poise_damage_increase: 0, - knockback: 7.0, + knockback: 3.0, range: 2.2, angle: 30.0, base_buildup_duration: 0.4, base_swing_duration: 0.07, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 1.5, damage_kind: Crushing, diff --git a/assets/common/abilities/custom/quadlowbreathe/dash.ron b/assets/common/abilities/custom/quadlowbreathe/dash.ron index 645e4b8516..32ae96a698 100644 --- a/assets/common/abilities/custom/quadlowbreathe/dash.ron +++ b/assets/common/abilities/custom/quadlowbreathe/dash.ron @@ -1,7 +1,7 @@ DashMelee( energy_cost: 0, - base_damage: 50, - scaled_damage: 100, + base_damage: 80, + scaled_damage: 150, base_poise_damage: 25, scaled_poise_damage: 0, base_knockback: 4.0, diff --git a/assets/common/abilities/custom/quadlowbreathe/flamethrower.ron b/assets/common/abilities/custom/quadlowbreathe/flamethrower.ron index 6a24929f17..ddc09e0ef6 100644 --- a/assets/common/abilities/custom/quadlowbreathe/flamethrower.ron +++ b/assets/common/abilities/custom/quadlowbreathe/flamethrower.ron @@ -2,7 +2,7 @@ BasicBeam( buildup_duration: 0.4, recover_duration: 0.25, beam_duration: 0.5, - damage: 40, + damage: 70, tick_rate: 3.0, range: 15.0, max_angle: 22.5, diff --git a/assets/common/abilities/custom/quadlowbreathe/triplestrike.ron b/assets/common/abilities/custom/quadlowbreathe/triplestrike.ron index 19320571bb..6c68f6f61a 100644 --- a/assets/common/abilities/custom/quadlowbreathe/triplestrike.ron +++ b/assets/common/abilities/custom/quadlowbreathe/triplestrike.ron @@ -2,45 +2,48 @@ ComboMelee( stage_data: [ ( stage: 1, - base_damage: 75, + base_damage: 220, damage_increase: 0, - base_poise_damage: 0, + base_poise_damage: 20, poise_damage_increase: 0, - knockback: 10.0, + knockback: 3.0, range: 2.5, angle: 30.0, base_buildup_duration: 0.65, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 2.0, damage_kind: Crushing, ), ( stage: 2, - base_damage: 75, + base_damage: 220, damage_increase: 0, - base_poise_damage: 0, + base_poise_damage: 20, poise_damage_increase: 0, - knockback: 10.0, + knockback: 3.0, range: 2.5, angle: 30.0, base_buildup_duration: 0.4, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 1.5, damage_kind: Crushing, ), ( stage: 3, - base_damage: 75, + base_damage: 220, damage_increase: 0, - base_poise_damage: 0, + base_poise_damage: 20, poise_damage_increase: 0, - knockback: 10.0, + knockback: 3.0, range: 2.5, angle: 30.0, base_buildup_duration: 0.4, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 1.5, damage_kind: Crushing, diff --git a/assets/common/abilities/custom/quadlowquick/quadstrike.ron b/assets/common/abilities/custom/quadlowquick/quadstrike.ron index 2bd6e570f3..fdf237aebf 100644 --- a/assets/common/abilities/custom/quadlowquick/quadstrike.ron +++ b/assets/common/abilities/custom/quadlowquick/quadstrike.ron @@ -6,11 +6,12 @@ ComboMelee( damage_increase: 0, base_poise_damage: 15, poise_damage_increase: 0, - knockback: 2.0, + knockback: 1.0, range: 2.5, angle: 30.0, base_buildup_duration: 0.6, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.1, forward_movement: 1.5, damage_kind: Crushing, @@ -21,11 +22,12 @@ ComboMelee( damage_increase: 0, base_poise_damage: 15, poise_damage_increase: 0, - knockback: 2.0, + knockback: 1.0, range: 2.5, angle: 30.0, base_buildup_duration: 0.15, base_swing_duration: 0.07, + hit_timing: 0.5, base_recover_duration: 0.1, forward_movement: 0.8, damage_kind: Crushing, @@ -36,11 +38,12 @@ ComboMelee( damage_increase: 0, base_poise_damage: 15, poise_damage_increase: 0, - knockback: 2.0, + knockback: 1.0, range: 2.5, angle: 30.0, base_buildup_duration: 0.2, base_swing_duration: 0.07, + hit_timing: 0.5, base_recover_duration: 0.1, forward_movement: 0.8, damage_kind: Crushing, @@ -56,6 +59,7 @@ ComboMelee( angle: 30.0, base_buildup_duration: 0.2, base_swing_duration: 0.07, + hit_timing: 0.5, base_recover_duration: 0.1, forward_movement: 0.8, damage_kind: Crushing, diff --git a/assets/common/abilities/custom/quadlowranged/firebomb.ron b/assets/common/abilities/custom/quadlowranged/firebomb.ron index beb3c27f1c..4c758438cf 100644 --- a/assets/common/abilities/custom/quadlowranged/firebomb.ron +++ b/assets/common/abilities/custom/quadlowranged/firebomb.ron @@ -2,12 +2,12 @@ BasicRanged( energy_cost: 0, buildup_duration: 0.8, recover_duration: 0.35, - projectile: Fireball( - damage: 80.0, + projectile: NecroticSphere( + damage: 130.0, radius: 5.0, energy_regen: 0, ), - projectile_body: Object(BoltFire), + projectile_body: Object(FireworkPurple), /*projectile_light: Some(LightEmitter { col: (1.0, 0.75, 0.11).into(), ..Default::default() diff --git a/assets/common/abilities/custom/quadlowtail/charged.ron b/assets/common/abilities/custom/quadlowtail/charged.ron index fb03117f1c..d2c563f69c 100644 --- a/assets/common/abilities/custom/quadlowtail/charged.ron +++ b/assets/common/abilities/custom/quadlowtail/charged.ron @@ -13,6 +13,6 @@ ChargedMelee( charge_duration: 0.8, swing_duration: 0.7, hit_timing: 0.9, - recover_duration: 1.2, + recover_duration: 0.7, damage_kind: Crushing, ) diff --git a/assets/common/abilities/custom/quadlowtail/triplestrike.ron b/assets/common/abilities/custom/quadlowtail/triplestrike.ron index a35efe048e..457328d1c0 100644 --- a/assets/common/abilities/custom/quadlowtail/triplestrike.ron +++ b/assets/common/abilities/custom/quadlowtail/triplestrike.ron @@ -11,6 +11,7 @@ ComboMelee( angle: 30.0, base_buildup_duration: 0.65, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.2, forward_movement: 2.0, damage_kind: Crushing, @@ -26,6 +27,7 @@ ComboMelee( angle: 30.0, base_buildup_duration: 0.2, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.2, forward_movement: 1.0, damage_kind: Crushing, @@ -41,6 +43,7 @@ ComboMelee( angle: 30.0, base_buildup_duration: 0.2, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.2, forward_movement: 1.0, damage_kind: Crushing, diff --git a/assets/common/abilities/custom/quadmedbasic/singlestrike.ron b/assets/common/abilities/custom/quadmedbasic/singlestrike.ron index fef9810b42..d5659cd650 100644 --- a/assets/common/abilities/custom/quadmedbasic/singlestrike.ron +++ b/assets/common/abilities/custom/quadmedbasic/singlestrike.ron @@ -6,11 +6,12 @@ ComboMelee( damage_increase: 0, base_poise_damage: 28, poise_damage_increase: 0, - knockback: 5.0, + knockback: 3.0, range: 2.7, angle: 60.0, base_buildup_duration: 0.4, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.4, forward_movement: 1.0, damage_kind: Crushing, diff --git a/assets/common/abilities/custom/quadmedbasic/triplestrike.ron b/assets/common/abilities/custom/quadmedbasic/triplestrike.ron index 4b8544b345..1a5577da1d 100644 --- a/assets/common/abilities/custom/quadmedbasic/triplestrike.ron +++ b/assets/common/abilities/custom/quadmedbasic/triplestrike.ron @@ -11,6 +11,7 @@ ComboMelee( angle: 30.0, base_buildup_duration: 0.45, base_swing_duration: 0.07, + hit_timing: 0.5, base_recover_duration: 0.2, forward_movement: 1.0, damage_kind: Crushing, @@ -26,6 +27,7 @@ ComboMelee( angle: 30.0, base_buildup_duration: 0.4, base_swing_duration: 0.07, + hit_timing: 0.5, base_recover_duration: 0.2, forward_movement: 0.0, damage_kind: Crushing, @@ -41,6 +43,7 @@ ComboMelee( angle: 30.0, base_buildup_duration: 0.4, base_swing_duration: 0.07, + hit_timing: 0.5, base_recover_duration: 0.2, forward_movement: 1.0, damage_kind: Crushing, diff --git a/assets/common/abilities/custom/quadmedcharge/doublestrike.ron b/assets/common/abilities/custom/quadmedcharge/doublestrike.ron index 9ec940c20f..d535ccb97a 100644 --- a/assets/common/abilities/custom/quadmedcharge/doublestrike.ron +++ b/assets/common/abilities/custom/quadmedcharge/doublestrike.ron @@ -6,11 +6,12 @@ ComboMelee( damage_increase: 0, base_poise_damage: 22, poise_damage_increase: 0, - knockback: 10.0, + knockback: 4.0, range: 2.5, angle: 30.0, base_buildup_duration: 0.65, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 1.0, damage_kind: Crushing, @@ -21,11 +22,12 @@ ComboMelee( damage_increase: 0, base_poise_damage: 0, poise_damage_increase: 22, - knockback: 10.0, + knockback: 4.0, range: 2.5, angle: 30.0, base_buildup_duration: 0.4, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 0.5, damage_kind: Crushing, diff --git a/assets/common/abilities/custom/quadmedhoof/basic.ron b/assets/common/abilities/custom/quadmedhoof/basic.ron index a7608d6b22..b1d70e5f7f 100644 --- a/assets/common/abilities/custom/quadmedhoof/basic.ron +++ b/assets/common/abilities/custom/quadmedhoof/basic.ron @@ -1,12 +1,12 @@ BasicMelee( energy_cost: 0, - buildup_duration: 0.45, - swing_duration: 0.5, + buildup_duration: 0.65, + swing_duration: 0.3, recover_duration: 0.35, base_damage: 100, base_poise_damage: 28, knockback: ( strength: 25.0, direction: Away), - range: 1.2, + range: 0.8, max_angle: 50.0, damage_effect: None, damage_kind: Crushing, diff --git a/assets/common/abilities/custom/quadmedjump/doublestrike.ron b/assets/common/abilities/custom/quadmedjump/doublestrike.ron index 635eb2bfac..d57e0c63df 100644 --- a/assets/common/abilities/custom/quadmedjump/doublestrike.ron +++ b/assets/common/abilities/custom/quadmedjump/doublestrike.ron @@ -11,6 +11,7 @@ ComboMelee( angle: 30.0, base_buildup_duration: 0.65, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 1.0, damage_kind: Crushing, @@ -26,6 +27,7 @@ ComboMelee( angle: 30.0, base_buildup_duration: 0.4, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 1.5, damage_kind: Crushing, diff --git a/assets/common/abilities/custom/quadmedquick/triplestrike.ron b/assets/common/abilities/custom/quadmedquick/triplestrike.ron index cdf07c952d..596df64343 100644 --- a/assets/common/abilities/custom/quadmedquick/triplestrike.ron +++ b/assets/common/abilities/custom/quadmedquick/triplestrike.ron @@ -11,6 +11,7 @@ ComboMelee( angle: 40.0, base_buildup_duration: 0.6, base_swing_duration: 0.15, + hit_timing: 0.5, base_recover_duration: 0.4, forward_movement: 0.3, damage_kind: Crushing, @@ -26,6 +27,7 @@ ComboMelee( angle: 40.0, base_buildup_duration: 0.4, base_swing_duration: 0.15, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 0.5, damage_kind: Crushing, @@ -41,6 +43,7 @@ ComboMelee( angle: 40.0, base_buildup_duration: 0.4, base_swing_duration: 0.15, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 0.5, damage_kind: Crushing, diff --git a/assets/common/abilities/custom/quadsmallbasic/singlestrike.ron b/assets/common/abilities/custom/quadsmallbasic/singlestrike.ron index 4ce36a7a0f..d494ab6974 100644 --- a/assets/common/abilities/custom/quadsmallbasic/singlestrike.ron +++ b/assets/common/abilities/custom/quadsmallbasic/singlestrike.ron @@ -6,11 +6,12 @@ ComboMelee( damage_increase: 0, base_poise_damage: 10, poise_damage_increase: 0, - knockback: 3.0, + knockback: 1.0, range: 1.5, angle: 50.0, base_buildup_duration: 0.3, base_swing_duration: 0.15, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 1.0, damage_kind: Crushing, diff --git a/assets/common/abilities/custom/stonegolemfist/singlestrike.ron b/assets/common/abilities/custom/stonegolemfist/singlestrike.ron index 74d2853a78..0c22b0bdb7 100644 --- a/assets/common/abilities/custom/stonegolemfist/singlestrike.ron +++ b/assets/common/abilities/custom/stonegolemfist/singlestrike.ron @@ -11,6 +11,7 @@ ComboMelee( angle: 60.0, base_buildup_duration: 0.9, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.9, forward_movement: 3.0, damage_kind: Crushing, diff --git a/assets/common/abilities/custom/theropodbasic/singlestrike.ron b/assets/common/abilities/custom/theropodbasic/singlestrike.ron index 17c2f98b28..9c607d0058 100644 --- a/assets/common/abilities/custom/theropodbasic/singlestrike.ron +++ b/assets/common/abilities/custom/theropodbasic/singlestrike.ron @@ -2,15 +2,16 @@ ComboMelee( stage_data: [ ( stage: 1, - base_damage: 130, + base_damage: 270, damage_increase: 0, base_poise_damage: 40, poise_damage_increase: 0, knockback: 4.0, range: 7.5, angle: 60.0, - base_buildup_duration: 0.5, + base_buildup_duration: 0.4, base_swing_duration: 0.15, + hit_timing: 0.5, base_recover_duration: 0.4, forward_movement: 3.0, damage_kind: Crushing, diff --git a/assets/common/abilities/custom/theropodbasic/triplestrike.ron b/assets/common/abilities/custom/theropodbasic/triplestrike.ron index 5c19bf5d62..7157a77620 100644 --- a/assets/common/abilities/custom/theropodbasic/triplestrike.ron +++ b/assets/common/abilities/custom/theropodbasic/triplestrike.ron @@ -2,45 +2,48 @@ ComboMelee( stage_data: [ ( stage: 1, - base_damage: 140, + base_damage: 300, damage_increase: 0, base_poise_damage: 35, poise_damage_increase: 0, - knockback: 5.0, + knockback: 3.0, range: 7.5, angle: 30.0, - base_buildup_duration: 0.9, + base_buildup_duration: 0.7, base_swing_duration: 0.15, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 1.0, damage_kind: Crushing, ), ( stage: 2, - base_damage: 160, + base_damage: 340, damage_increase: 0, base_poise_damage: 35, poise_damage_increase: 0, - knockback: 5.0, + knockback: 3.0, range: 5.5, angle: 30.0, - base_buildup_duration: 0.5, + base_buildup_duration: 0.4, base_swing_duration: 0.15, + hit_timing: 0.5, base_recover_duration: 0.15, forward_movement: 1.0, damage_kind: Crushing, ), ( stage: 3, - base_damage: 200, + base_damage: 400, damage_increase: 0, base_poise_damage: 35, poise_damage_increase: 0, - knockback: 5.0, + knockback: 25.0, range: 5.5, angle: 30.0, - base_buildup_duration: 0.35, + base_buildup_duration: 0.3, base_swing_duration: 0.125, + hit_timing: 0.5, base_recover_duration: 0.9, forward_movement: 1.0, damage_kind: Crushing, diff --git a/assets/common/abilities/custom/theropodbird/singlestrike.ron b/assets/common/abilities/custom/theropodbird/singlestrike.ron index db41b51c21..1401500a4b 100644 --- a/assets/common/abilities/custom/theropodbird/singlestrike.ron +++ b/assets/common/abilities/custom/theropodbird/singlestrike.ron @@ -11,6 +11,7 @@ ComboMelee( angle: 15.0, base_buildup_duration: 0.4, base_swing_duration: 0.15, + hit_timing: 0.5, base_recover_duration: 0.4, forward_movement: 3.0, damage_kind: Crushing, diff --git a/assets/common/abilities/custom/theropodbird/triplestrike.ron b/assets/common/abilities/custom/theropodbird/triplestrike.ron index 0ae2472f83..9693aa46d0 100644 --- a/assets/common/abilities/custom/theropodbird/triplestrike.ron +++ b/assets/common/abilities/custom/theropodbird/triplestrike.ron @@ -11,6 +11,7 @@ ComboMelee( angle: 15.0, base_buildup_duration: 0.65, base_swing_duration: 0.15, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 1.0, damage_kind: Crushing, @@ -26,6 +27,7 @@ ComboMelee( angle: 15.0, base_buildup_duration: 0.4, base_swing_duration: 0.15, + hit_timing: 0.5, base_recover_duration: 0.15, forward_movement: 1.0, damage_kind: Crushing, @@ -41,6 +43,7 @@ ComboMelee( angle: 15.0, base_buildup_duration: 0.35, base_swing_duration: 0.125, + hit_timing: 0.5, base_recover_duration: 0.9, forward_movement: 1.0, damage_kind: Crushing, diff --git a/assets/common/abilities/custom/tidalwarrior/totem.ron b/assets/common/abilities/custom/tidalwarrior/totem.ron index 31df64a7cd..c997b8954c 100644 --- a/assets/common/abilities/custom/tidalwarrior/totem.ron +++ b/assets/common/abilities/custom/tidalwarrior/totem.ron @@ -3,11 +3,13 @@ BasicSummon( cast_duration: 1.0, recover_duration: 0.5, summon_amount: 1, + summon_distance: (1, 1), summon_info: ( body: Object(SeaLantern), scale: None, - health_scaling: 0, + health_scaling: Some(0), loadout_config: None, skillset_config: None, ), + duration: None, ) diff --git a/assets/common/abilities/custom/tornado/spin.ron b/assets/common/abilities/custom/tornado/spin.ron new file mode 100644 index 0000000000..f5108fad61 --- /dev/null +++ b/assets/common/abilities/custom/tornado/spin.ron @@ -0,0 +1,19 @@ +SpinMelee( + buildup_duration: 0.0, + swing_duration: 0.5, + recover_duration: 0.0, + base_damage: 400, + base_poise_damage: 0, + knockback: ( strength: 50.0, direction: Away), + range: 3.5, + damage_effect: None, + energy_cost: 0, + is_infinite: true, + movement_behavior: ForwardGround, + is_interruptible: false, + forward_speed: 0.0, + num_spins: 1, + specifier: None, + target: Some(OutOfGroup), + damage_kind: Slashing, +) diff --git a/assets/common/abilities/custom/wendigomagic/frostbomb.ron b/assets/common/abilities/custom/wendigomagic/frostbomb.ron index 5cf95514b2..d49f94fcc1 100644 --- a/assets/common/abilities/custom/wendigomagic/frostbomb.ron +++ b/assets/common/abilities/custom/wendigomagic/frostbomb.ron @@ -3,7 +3,7 @@ BasicRanged( buildup_duration: 0.5, recover_duration: 0.35, projectile: Frostball( - damage: 80.0, + damage: 120.0, radius: 5.0, ), projectile_body: Object(BoltFire), // TODO: Get ice projectile model diff --git a/assets/common/abilities/custom/wendigomagic/singlestrike.ron b/assets/common/abilities/custom/wendigomagic/singlestrike.ron index c6fe60fade..efdf2b7bc9 100644 --- a/assets/common/abilities/custom/wendigomagic/singlestrike.ron +++ b/assets/common/abilities/custom/wendigomagic/singlestrike.ron @@ -2,15 +2,16 @@ ComboMelee( stage_data: [ ( stage: 1, - base_damage: 120, + base_damage: 180, damage_increase: 0, base_poise_damage: 40, poise_damage_increase: 0, knockback: 3.0, - range: 3.5, + range: 2.5, angle: 30.0, base_buildup_duration: 0.6, base_swing_duration: 0.2, + hit_timing: 0.5, base_recover_duration: 0.4, forward_movement: 5.0, damage_kind: Crushing, diff --git a/assets/common/abilities/hammer/singlestrike.ron b/assets/common/abilities/hammer/singlestrike.ron index 5a7657c7ea..d4aef1f59c 100644 --- a/assets/common/abilities/hammer/singlestrike.ron +++ b/assets/common/abilities/hammer/singlestrike.ron @@ -3,13 +3,14 @@ ComboMelee( stage: 1, base_damage: 150, damage_increase: 10, - base_poise_damage: 25, + base_poise_damage: 20, poise_damage_increase: 0, - knockback: 5.0, + knockback: 3.5, range: 4.5, angle: 50.0, base_buildup_duration: 0.2, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.45, forward_movement: 0.0, damage_kind: Crushing, diff --git a/assets/common/abilities/hammersimple/doublestrike.ron b/assets/common/abilities/hammersimple/doublestrike.ron index 4bc8e7f3b2..fa333528e3 100644 --- a/assets/common/abilities/hammersimple/doublestrike.ron +++ b/assets/common/abilities/hammersimple/doublestrike.ron @@ -2,30 +2,32 @@ ComboMelee( stage_data: [ ( stage: 1, - base_damage: 90, + base_damage: 240, damage_increase: 10, - base_poise_damage: 30, + base_poise_damage: 40, poise_damage_increase: 0, knockback: 4.0, - range: 3.5, + range: 4.5, angle: 50.0, base_buildup_duration: 0.6, base_swing_duration: 0.08, + hit_timing: 0.5, base_recover_duration: 0.6, forward_movement: 3.5, damage_kind: Crushing, ), ( stage: 2, - base_damage: 130, + base_damage: 320, damage_increase: 15, - base_poise_damage: 30, + base_poise_damage: 40, poise_damage_increase: 0, knockback: 16.0, - range: 1.5, + range: 2.5, angle: 30.0, - base_buildup_duration: 0.5, + base_buildup_duration: 0.6, base_swing_duration: 0.25, + hit_timing: 0.5, base_recover_duration: 1.2, forward_movement: 2.0, damage_kind: Crushing, @@ -38,5 +40,5 @@ ComboMelee( max_speed_increase: 0.0, scales_from_combo: 0, is_interruptible: false, - ori_modifier: 0.6, + ori_modifier: 0.65, ) diff --git a/assets/common/abilities/spear/doublestrike.ron b/assets/common/abilities/spear/doublestrike.ron index e7e1c92980..075850a90c 100644 --- a/assets/common/abilities/spear/doublestrike.ron +++ b/assets/common/abilities/spear/doublestrike.ron @@ -11,6 +11,7 @@ ComboMelee( angle: 15.0, base_buildup_duration: 0.35, base_swing_duration: 0.075, + hit_timing: 0.5, base_recover_duration: 0.4, forward_movement: 0.7, damage_kind: Piercing, @@ -26,6 +27,7 @@ ComboMelee( angle: 15.0, base_buildup_duration: 0.5, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.5, forward_movement: 0.7, damage_kind: Piercing, diff --git a/assets/common/abilities/sword/spin.ron b/assets/common/abilities/sword/spin.ron index ac5cdee91f..faf3361b1c 100644 --- a/assets/common/abilities/sword/spin.ron +++ b/assets/common/abilities/sword/spin.ron @@ -3,7 +3,7 @@ SpinMelee( swing_duration: 0.4, recover_duration: 0.5, base_damage: 160, - base_poise_damage: 25, + base_poise_damage: 13, knockback: ( strength: 10.0, direction: Away), range: 3.5, damage_effect: None, diff --git a/assets/common/abilities/sword/triplestrike.ron b/assets/common/abilities/sword/triplestrike.ron index ea05f387d8..93ae1ffd07 100644 --- a/assets/common/abilities/sword/triplestrike.ron +++ b/assets/common/abilities/sword/triplestrike.ron @@ -6,11 +6,12 @@ ComboMelee( damage_increase: 10, base_poise_damage: 10, poise_damage_increase: 0, - knockback: 1.0, + knockback: 0.0, range: 4.0, angle: 30.0, - base_buildup_duration: 0.15, + base_buildup_duration: 0.1, base_swing_duration: 0.075, + hit_timing: 0.5, base_recover_duration: 0.15, forward_movement: 0.5, damage_kind: Slashing, @@ -26,6 +27,7 @@ ComboMelee( angle: 40.0, base_buildup_duration: 0.1, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.3, forward_movement: 0.0, damage_kind: Slashing, @@ -36,11 +38,12 @@ ComboMelee( damage_increase: 20, base_poise_damage: 15, poise_damage_increase: 0, - knockback: 4.0, + knockback: 2.0, range: 6.0, angle: 10.0, base_buildup_duration: 0.15, base_swing_duration: 0.1, + hit_timing: 0.2, base_recover_duration: 0.35, forward_movement: 1.2, damage_kind: Piercing, diff --git a/assets/common/abilities/swordsimple/doublestrike.ron b/assets/common/abilities/swordsimple/doublestrike.ron index 5aefeb50a6..f8a9b3860e 100644 --- a/assets/common/abilities/swordsimple/doublestrike.ron +++ b/assets/common/abilities/swordsimple/doublestrike.ron @@ -11,6 +11,7 @@ ComboMelee( angle: 50.0, base_buildup_duration: 0.4, base_swing_duration: 0.08, + hit_timing: 0.5, base_recover_duration: 0.5, forward_movement: 2.5, damage_kind: Slashing, @@ -26,6 +27,7 @@ ComboMelee( angle: 30.0, base_buildup_duration: 0.7, base_swing_duration: 0.1, + hit_timing: 0.5, base_recover_duration: 0.7, forward_movement: 2.0, damage_kind: Slashing, diff --git a/assets/common/cave_scatter/dark_floor.ron b/assets/common/cave_scatter/dark_floor.ron index 1b3f456bff..bd89d3a6dd 100644 --- a/assets/common/cave_scatter/dark_floor.ron +++ b/assets/common/cave_scatter/dark_floor.ron @@ -1,10 +1,11 @@ [ - (20, Velorite), - (30, VeloriteFrag), - (5, CaveMushroom), + (50, Velorite), + (60, VeloriteFrag), + (40, CaveMushroom), (16, SapphireSmall), (12, EmeraldSmall), (15, Cobalt), + (30, Bloodstone), (40, Coal), (10, RubySmall), ] diff --git a/assets/common/cave_scatter/deep_floor.ron b/assets/common/cave_scatter/deep_floor.ron index 66c2e3ce59..0594c8679a 100644 --- a/assets/common/cave_scatter/deep_floor.ron +++ b/assets/common/cave_scatter/deep_floor.ron @@ -1,14 +1,14 @@ [ - (30, Velorite), + (40, Velorite), (40, VeloriteFrag), - (10, CaveMushroom), + (30, CaveMushroom), (30, Mushroom), - (10, AmethystSmall), - (10, TopazSmall), + (30, AmethystSmall), + (30, TopazSmall), (16, SapphireSmall), - (60, CrystalLow), + (100, CrystalLow), (12, EmeraldSmall), - (5, Cobalt), + (15, Cobalt), (40, Coal), (70, Iron), (10, RubySmall), diff --git a/assets/common/cave_scatter/shallow_floor.ron b/assets/common/cave_scatter/shallow_floor.ron index 290a476ac3..f80601194a 100644 --- a/assets/common/cave_scatter/shallow_floor.ron +++ b/assets/common/cave_scatter/shallow_floor.ron @@ -1,6 +1,6 @@ [ (110, Stones), - (150, ShortGrass), + (250, ShortGrass), (50, CaveMushroom), (50, Mushroom), (30, AmethystSmall), diff --git a/assets/common/items/npc_armor/biped_large/generic.ron b/assets/common/items/npc_armor/biped_large/generic.ron new file mode 100644 index 0000000000..edf92287cb --- /dev/null +++ b/assets/common/items/npc_armor/biped_large/generic.ron @@ -0,0 +1,17 @@ +ItemDef( + name: "Generic Biped Large", + description: "Worn by bipeds.", + kind: Armor(( + kind: Chest("GenericBipedLarge"), + stats: ( + protection: Normal(45.0), + poise_resilience: Normal(1.0), + energy_max: 0, + energy_reward: 0.0, + crit_power: 0.0, + stealth: 0.0, + ), + )), + quality: Moderate, + tags: [], +) \ No newline at end of file diff --git a/assets/common/items/npc_armor/biped_large/mindflayer.ron b/assets/common/items/npc_armor/biped_large/mindflayer.ron index cfddaadbfa..2d1696b29f 100644 --- a/assets/common/items/npc_armor/biped_large/mindflayer.ron +++ b/assets/common/items/npc_armor/biped_large/mindflayer.ron @@ -4,7 +4,7 @@ ItemDef( kind: Armor(( kind: Chest("Mindflayer"), stats: ( - protection: Normal(60.0), + protection: Normal(110.0), poise_resilience: Normal(1.0), energy_max: 0, energy_reward: 0.0, diff --git a/assets/common/items/npc_armor/quadruped_low/generic.ron b/assets/common/items/npc_armor/quadruped_low/generic.ron new file mode 100644 index 0000000000..a5e634b032 --- /dev/null +++ b/assets/common/items/npc_armor/quadruped_low/generic.ron @@ -0,0 +1,17 @@ +ItemDef( + name: "Quad Low Generic", + description: "Scaly.", + kind: Armor(( + kind: Chest("QuadrupedLowGeneric"), + stats: ( + protection: Normal(40.0), + poise_resilience: Normal(0.0), + energy_max: 0, + energy_reward: 0.0, + crit_power: 0.0, + stealth: 0.0, + ), + )), + quality: Moderate, + tags: [], +) diff --git a/assets/common/items/npc_armor/quadruped_low/shell.ron b/assets/common/items/npc_armor/quadruped_low/shell.ron new file mode 100644 index 0000000000..0fcf7e270e --- /dev/null +++ b/assets/common/items/npc_armor/quadruped_low/shell.ron @@ -0,0 +1,17 @@ +ItemDef( + name: "Quad Low Shell", + description: "Shell.", + kind: Armor(( + kind: Chest("QuadrupedLowShell"), + stats: ( + protection: Normal(750.0), + poise_resilience: Normal(0.0), + energy_max: 0, + energy_reward: 0.0, + crit_power: 0.0, + stealth: 0.0, + ), + )), + quality: Moderate, + tags: [], +) diff --git a/assets/common/items/npc_armor/theropod/rugged.ron b/assets/common/items/npc_armor/theropod/rugged.ron new file mode 100644 index 0000000000..01c260de60 --- /dev/null +++ b/assets/common/items/npc_armor/theropod/rugged.ron @@ -0,0 +1,17 @@ +ItemDef( + name: "Theropod Rugged", + description: "stronk.", + kind: Armor(( + kind: Chest("TheropodRugged"), + stats: ( + protection: Normal(80.0), + poise_resilience: Normal(0.0), + energy_max: 0, + energy_reward: 0.0, + crit_power: 0.0, + stealth: 0.0, + ), + )), + quality: Moderate, + tags: [], +) diff --git a/assets/common/items/npc_weapons/unique/quadlowranged.ron b/assets/common/items/npc_weapons/unique/asp.ron similarity index 80% rename from assets/common/items/npc_weapons/unique/quadlowranged.ron rename to assets/common/items/npc_weapons/unique/asp.ron index 2f4bcf2464..4312766e53 100644 --- a/assets/common/items/npc_weapons/unique/quadlowranged.ron +++ b/assets/common/items/npc_weapons/unique/asp.ron @@ -1,5 +1,5 @@ ItemDef( - name: "Quad Low Ranged", + name: "Asp", description: "testing123", kind: Tool(( kind: Natural, @@ -14,5 +14,5 @@ ItemDef( )), quality: Low, tags: [], - ability_spec: Some(Custom("Quad Low Ranged")), + ability_spec: Some(Custom("Asp")), ) \ No newline at end of file diff --git a/assets/common/items/npc_weapons/unique/birdlargebasic.ron b/assets/common/items/npc_weapons/unique/birdlargebasic.ron new file mode 100644 index 0000000000..a97d610359 --- /dev/null +++ b/assets/common/items/npc_weapons/unique/birdlargebasic.ron @@ -0,0 +1,19 @@ +ItemDef( + name: "Bird Large Basic", + description: "testing123", + kind: Tool(( + kind: Natural, + hands: Two, + stats: Direct(( + equip_time_secs: 0.01, + power: 1.0, + poise_strength: 1.0, + speed: 1.0, + crit_chance: 0.0625, + crit_mult: 1.9142857, + )), + )), + quality: Low, + tags: [], + ability_spec: Some(Custom("Bird Large Basic")), +) \ No newline at end of file diff --git a/assets/common/items/npc_weapons/unique/maneater.ron b/assets/common/items/npc_weapons/unique/maneater.ron new file mode 100644 index 0000000000..93fc149b6c --- /dev/null +++ b/assets/common/items/npc_weapons/unique/maneater.ron @@ -0,0 +1,18 @@ +ItemDef( + name: "Maneater", + description: "testing123", + kind: Tool(( + kind: Natural, + hands: Two, + stats: Direct(( + equip_time_secs: 0.01, + power: 1.0, + poise_strength: 1.0, + speed: 1.0, + crit_chance: 0.0625, + )), + )), + quality: Low, + tags: [], + ability_spec: Some(Custom("Maneater")), +) \ No newline at end of file diff --git a/assets/common/items/npc_weapons/unique/tornado.ron b/assets/common/items/npc_weapons/unique/tornado.ron new file mode 100644 index 0000000000..ee38a3be6b --- /dev/null +++ b/assets/common/items/npc_weapons/unique/tornado.ron @@ -0,0 +1,19 @@ +ItemDef( + name: "Tornado", + description: "Tornado weapon", + kind: Tool(( + kind: Natural, + hands: Two, + stats: Direct(( + equip_time_secs: 0.01, + power: 1.0, + poise_strength: 0.0, + speed: 1.0, + crit_chance: 0.0, + crit_mult: 0.0, + )), + )), + quality: Low, + tags: [], + ability_spec: Some(Custom("Tornado")), +) \ No newline at end of file diff --git a/assets/common/loot_tables/creature/bird_large/roc.ron b/assets/common/loot_tables/creature/bird_large/roc.ron new file mode 100644 index 0000000000..a5ec41abcf --- /dev/null +++ b/assets/common/loot_tables/creature/bird_large/roc.ron @@ -0,0 +1,4 @@ +[ + (0.5, Item("common.items.food.meat.beast_large_raw")), + (1.0, Item("common.items.crafting_ing.animal_misc.raptor_feather")), +] \ No newline at end of file diff --git a/assets/common/loot_tables/creature/quad_small/generic.ron b/assets/common/loot_tables/creature/quad_small/generic.ron index 431e082771..d7aeb6531a 100644 --- a/assets/common/loot_tables/creature/quad_small/generic.ron +++ b/assets/common/loot_tables/creature/quad_small/generic.ron @@ -1,4 +1,4 @@ [ - (1.0, Item("common.items.crafting_ing.hide.animal_hide")), + (1.0, ItemQuantity("common.items.crafting_ing.hide.animal_hide", 1, 2)), (0.25, Item("common.items.food.meat.beast_small_raw")), ] \ No newline at end of file diff --git a/assets/common/loot_tables/trading.ron b/assets/common/loot_tables/trading.ron index c109d6db31..9db4df6cdb 100644 --- a/assets/common/loot_tables/trading.ron +++ b/assets/common/loot_tables/trading.ron @@ -8,12 +8,17 @@ (1.0, Item("common.items.crafting_ing.hide.animal_hide")), (0.5, Item("common.items.crafting_ing.hide.tough_hide")), (0.2, Item("common.items.crafting_ing.hide.scales")), - (0.08, Item("common.items.crafting_ing.animal_misc.fur")), - (0.08, Item("common.items.crafting_ing.animal_misc.grim_eyeball")), - (0.08, Item("common.items.crafting_ing.animal_misc.icy_fang")), + (0.8, Item("common.items.crafting_ing.animal_misc.fur")), + (0.15, Item("common.items.crafting_ing.animal_misc.grim_eyeball")), + (0.1, Item("common.items.crafting_ing.animal_misc.icy_fang")), (0.08, Item("common.items.crafting_ing.animal_misc.large_horn")), - (0.08, Item("common.items.crafting_ing.animal_misc.lively_vine")), + (0.15, Item("common.items.crafting_ing.animal_misc.lively_vine")), (0.08, Item("common.items.crafting_ing.animal_misc.phoenix_feather")), + (1.0, Item("common.items.food.meat.beast_small_raw")), + (0.6, Item("common.items.food.meat.beast_large_raw")), + (1.3, Item("common.items.food.meat.bird_raw")), + (1.2, Item("common.items.food.meat.fish_raw")), + (0.8, Item("common.items.food.meat.tough_raw")), (0.2, Item("common.items.mineral.ore.bloodstone")), (1.0, Item("common.items.mineral.ore.coal")), (0.4, Item("common.items.mineral.ore.cobalt")), diff --git a/assets/common/npc_names.ron b/assets/common/npc_names.ron index 2729cacb40..ca8be884c0 100644 --- a/assets/common/npc_names.ron +++ b/assets/common/npc_names.ron @@ -826,9 +826,17 @@ keyword: "wendigo", generic: "Wendigo" ), - troll: ( - keyword: "troll", - generic: "Troll" + troll_cave: ( + keyword: "troll_cave", + generic: "Cave Troll" + ), + troll_mountain: ( + keyword: "troll_mountain", + generic: "Mountain Troll" + ), + troll_swamp: ( + keyword: "troll_swamp", + generic: "Swamp Troll" ), dullahan: ( keyword: "dullahan", @@ -1080,6 +1088,10 @@ keyword: "cockatrice", generic: "Cockatrice" ), + roc: ( + keyword: "roc", + generic: "Roc" + ), ) ), quadruped_low: ( diff --git a/assets/common/recipe_book.ron b/assets/common/recipe_book.ron index 85f6d48076..9f8f48e7dd 100644 --- a/assets/common/recipe_book.ron +++ b/assets/common/recipe_book.ron @@ -418,10 +418,9 @@ (Item("common.items.crafting_ing.animal_misc.raptor_feather"), 6), (Item("common.items.crafting_ing.twigs"), 5), (Item("common.items.crafting_ing.leather.thick_leather"), 4), - (Item("common.items.crafting_ing.cloth.linen"), 5), - (Item("common.items.mineral.gem.ruby"), 1), + (Item("common.items.crafting_ing.cloth.wool"), 5), + (Item("common.items.mineral.gem.sapphire"), 1), (Item("common.items.tool.craftsman_hammer"), 0), - (Item("common.items.crafting_tools.sewing_set"), 0), ], craft_sprite: Some(CraftingBench), ), @@ -431,11 +430,10 @@ (Item("common.items.crafting_ing.animal_misc.raptor_feather"), 6), (Item("common.items.crafting_ing.twigs"), 5), (Item("common.items.crafting_ing.leather.thick_leather"), 4), - (Item("common.items.crafting_ing.cloth.linen"), 5), + (Item("common.items.crafting_ing.cloth.silk"), 5), (Item("common.items.crafting_ing.animal_misc.icy_fang"), 1), (Item("common.items.mineral.gem.ruby"), 1), (Item("common.items.tool.craftsman_hammer"), 0), - (Item("common.items.crafting_tools.sewing_set"), 0), ], craft_sprite: Some(CraftingBench), ), @@ -443,12 +441,11 @@ output: ("common.items.glider.glider_woodraptor", 1), inputs: [ (Item("common.items.crafting_ing.animal_misc.raptor_feather"), 6), - (Item("common.items.crafting_ing.twigs"), 15), - (Item("common.items.crafting_ing.leather.leather_strips"), 5), - (Item("common.items.crafting_ing.cloth.linen"), 5), - (Item("common.items.mineral.gem.ruby"), 1), + (Item("common.items.crafting_ing.twigs"), 5), + (Item("common.items.crafting_ing.leather.thick_leather"), 4), + (Item("common.items.crafting_ing.cloth.lifecloth"), 5), + (Item("common.items.mineral.gem.emerald"), 1), (Item("common.items.tool.craftsman_hammer"), 0), - (Item("common.items.crafting_tools.sewing_set"), 0), ], craft_sprite: Some(CraftingBench), ), @@ -466,7 +463,6 @@ inputs: [ (Item("common.items.crafting_ing.leather.leather_strips"), 8), (Item("common.items.crafting_ing.twigs"), 6), - (Item("common.items.crafting_ing.stones"), 0), ], craft_sprite: Some(CraftingBench), ), @@ -476,7 +472,6 @@ (Item("common.items.crafting_ing.leather.leather_strips"), 4), (Item("common.items.crafting_ing.twigs"), 10), (Item("common.items.mineral.ore.veloritefrag"), 1), - (Item("common.items.crafting_ing.stones"), 0), ], craft_sprite: Some(Anvil), ), @@ -662,8 +657,8 @@ "carapace back": ( output: ("common.items.armor.hide.carapace.back", 1), inputs: [ - (Item("common.items.mineral.ingot.steel"), 1), (Item("common.items.crafting_ing.hide.carapace"), 3), + (Item("common.items.mineral.ingot.steel"), 1), (Item("common.items.crafting_ing.leather.leather_strips"), 2), ], craft_sprite: Some(CraftingBench), @@ -671,8 +666,8 @@ "carapace belt": ( output: ("common.items.armor.hide.carapace.belt", 1), inputs: [ - (Item("common.items.mineral.ingot.steel"), 1), (Item("common.items.crafting_ing.hide.carapace"), 2), + (Item("common.items.mineral.ingot.steel"), 1), (Item("common.items.crafting_ing.leather.leather_strips"), 2), ], craft_sprite: Some(CraftingBench), @@ -680,8 +675,8 @@ "carapace chest": ( output: ("common.items.armor.hide.carapace.chest", 1), inputs: [ - (Item("common.items.mineral.ingot.steel"), 2), (Item("common.items.crafting_ing.hide.carapace"), 10), + (Item("common.items.mineral.ingot.steel"), 2), (Item("common.items.crafting_ing.leather.leather_strips"), 4), ], craft_sprite: Some(CraftingBench), @@ -689,8 +684,8 @@ "carapace feet": ( output: ("common.items.armor.hide.carapace.foot", 1), inputs: [ - (Item("common.items.mineral.ingot.steel"), 1), (Item("common.items.crafting_ing.hide.carapace"), 3), + (Item("common.items.mineral.ingot.steel"), 1), (Item("common.items.crafting_ing.leather.leather_strips"), 2), ], craft_sprite: Some(CraftingBench), @@ -698,8 +693,8 @@ "carapace hands": ( output: ("common.items.armor.hide.carapace.hand", 1), inputs: [ - (Item("common.items.mineral.ingot.steel"), 1), (Item("common.items.crafting_ing.hide.carapace"), 3), + (Item("common.items.mineral.ingot.steel"), 1), (Item("common.items.crafting_ing.leather.leather_strips"), 2), ], craft_sprite: Some(CraftingBench), @@ -707,8 +702,8 @@ "carapace pants": ( output: ("common.items.armor.hide.carapace.pants", 1), inputs: [ - (Item("common.items.mineral.ingot.steel"), 1), (Item("common.items.crafting_ing.hide.carapace"), 8), + (Item("common.items.mineral.ingot.steel"), 1), (Item("common.items.crafting_ing.leather.leather_strips"), 4), ], craft_sprite: Some(CraftingBench), @@ -716,8 +711,8 @@ "carapace shoulder": ( output: ("common.items.armor.hide.carapace.shoulder", 1), inputs: [ - (Item("common.items.mineral.ingot.steel"), 1), (Item("common.items.crafting_ing.hide.carapace"), 8), + (Item("common.items.mineral.ingot.steel"), 1), (Item("common.items.crafting_ing.leather.leather_strips"), 6), ], craft_sprite: Some(CraftingBench), @@ -726,9 +721,9 @@ "primal back": ( output: ("common.items.armor.hide.primal.back", 1), inputs: [ + (Item("common.items.crafting_ing.hide.plate"), 3), (Item("common.items.crafting_ing.animal_misc.large_horn"), 1), (Item("common.items.crafting_ing.cloth.lifecloth"), 1), - (Item("common.items.crafting_ing.hide.plate"), 3), (Item("common.items.crafting_ing.leather.rigid_leather"), 2), ], craft_sprite: Some(CraftingBench), @@ -736,8 +731,8 @@ "primal belt": ( output: ("common.items.armor.hide.primal.belt", 1), inputs: [ - (Item("common.items.crafting_ing.cloth.lifecloth"), 1), (Item("common.items.crafting_ing.hide.plate"), 2), + (Item("common.items.crafting_ing.cloth.lifecloth"), 1), (Item("common.items.crafting_ing.leather.rigid_leather"), 2), ], craft_sprite: Some(CraftingBench), @@ -745,9 +740,9 @@ "primal chest": ( output: ("common.items.armor.hide.primal.chest", 1), inputs: [ + (Item("common.items.crafting_ing.hide.plate"), 10), (Item("common.items.crafting_ing.animal_misc.large_horn"), 1), (Item("common.items.crafting_ing.cloth.lifecloth"), 2), - (Item("common.items.crafting_ing.hide.plate"), 10), (Item("common.items.crafting_ing.leather.rigid_leather"), 4), ], craft_sprite: Some(CraftingBench), @@ -755,8 +750,8 @@ "primal feet": ( output: ("common.items.armor.hide.primal.foot", 1), inputs: [ - (Item("common.items.crafting_ing.cloth.lifecloth"), 1), (Item("common.items.crafting_ing.hide.plate"), 3), + (Item("common.items.crafting_ing.cloth.lifecloth"), 1), (Item("common.items.crafting_ing.leather.rigid_leather"), 2), ], craft_sprite: Some(CraftingBench), @@ -764,8 +759,8 @@ "primal hands": ( output: ("common.items.armor.hide.primal.hand", 1), inputs: [ - (Item("common.items.crafting_ing.cloth.lifecloth"), 1), (Item("common.items.crafting_ing.hide.plate"), 3), + (Item("common.items.crafting_ing.cloth.lifecloth"), 1), (Item("common.items.crafting_ing.leather.rigid_leather"), 2), ], craft_sprite: Some(CraftingBench), @@ -773,9 +768,9 @@ "primal pants": ( output: ("common.items.armor.hide.primal.pants", 1), inputs: [ + (Item("common.items.crafting_ing.hide.plate"), 8), (Item("common.items.crafting_ing.animal_misc.large_horn"), 1), (Item("common.items.crafting_ing.cloth.lifecloth"), 2), - (Item("common.items.crafting_ing.hide.plate"), 8), (Item("common.items.crafting_ing.leather.rigid_leather"), 4), ], craft_sprite: Some(CraftingBench), @@ -783,9 +778,9 @@ "primal shoulder": ( output: ("common.items.armor.hide.primal.shoulder", 1), inputs: [ + (Item("common.items.crafting_ing.hide.plate"), 8), (Item("common.items.crafting_ing.animal_misc.large_horn"), 2), (Item("common.items.crafting_ing.cloth.lifecloth"), 2), - (Item("common.items.crafting_ing.hide.plate"), 8), (Item("common.items.crafting_ing.leather.rigid_leather"), 6), ], craft_sprite: Some(CraftingBench), @@ -794,8 +789,8 @@ "dragonscale back": ( output: ("common.items.armor.hide.dragonscale.back", 1), inputs: [ - (Item("common.items.mineral.ingot.bloodsteel"), 2), (Item("common.items.crafting_ing.hide.dragon_scale"), 3), + (Item("common.items.mineral.ingot.bloodsteel"), 2), (Item("common.items.crafting_ing.leather.rigid_leather"), 1), (Item("common.items.crafting_ing.hide.scales"), 2), ], @@ -804,8 +799,8 @@ "dragonscale belt": ( output: ("common.items.armor.hide.dragonscale.belt", 1), inputs: [ - (Item("common.items.mineral.ingot.bloodsteel"), 2), (Item("common.items.crafting_ing.hide.dragon_scale"), 2), + (Item("common.items.mineral.ingot.bloodsteel"), 2), (Item("common.items.crafting_ing.hide.scales"), 2), ], craft_sprite: Some(CraftingBench), @@ -813,8 +808,8 @@ "dragonscale chest": ( output: ("common.items.armor.hide.dragonscale.chest", 1), inputs: [ - (Item("common.items.mineral.ingot.bloodsteel"), 3), (Item("common.items.crafting_ing.hide.dragon_scale"), 10), + (Item("common.items.mineral.ingot.bloodsteel"), 3), (Item("common.items.crafting_ing.leather.rigid_leather"), 2), (Item("common.items.crafting_ing.hide.scales"), 4), ], @@ -823,8 +818,8 @@ "dragonscale feet": ( output: ("common.items.armor.hide.dragonscale.foot", 1), inputs: [ - (Item("common.items.mineral.ingot.bloodsteel"), 2), (Item("common.items.crafting_ing.hide.dragon_scale"), 3), + (Item("common.items.mineral.ingot.bloodsteel"), 2), (Item("common.items.crafting_ing.hide.scales"), 2), ], craft_sprite: Some(CraftingBench), @@ -832,8 +827,8 @@ "dragonscale hands": ( output: ("common.items.armor.hide.dragonscale.hand", 1), inputs: [ - (Item("common.items.mineral.ingot.bloodsteel"), 2), (Item("common.items.crafting_ing.hide.dragon_scale"), 3), + (Item("common.items.mineral.ingot.bloodsteel"), 2), (Item("common.items.crafting_ing.hide.scales"), 2), ], craft_sprite: Some(CraftingBench), @@ -841,8 +836,8 @@ "dragonscale pants": ( output: ("common.items.armor.hide.dragonscale.pants", 1), inputs: [ - (Item("common.items.mineral.ingot.bloodsteel"), 3), (Item("common.items.crafting_ing.hide.dragon_scale"), 8), + (Item("common.items.mineral.ingot.bloodsteel"), 3), (Item("common.items.crafting_ing.leather.rigid_leather"), 1), (Item("common.items.crafting_ing.hide.scales"), 4), ], @@ -851,8 +846,8 @@ "dragonscale shoulder": ( output: ("common.items.armor.hide.dragonscale.shoulder", 1), inputs: [ - (Item("common.items.mineral.ingot.bloodsteel"), 3), (Item("common.items.crafting_ing.hide.dragon_scale"), 8), + (Item("common.items.mineral.ingot.bloodsteel"), 3), (Item("common.items.crafting_ing.leather.rigid_leather"), 2), (Item("common.items.crafting_ing.hide.scales"), 6), ], @@ -1109,6 +1104,7 @@ inputs: [ (Item("common.items.crafting_ing.cloth.moonweave"), 3), (Item("common.items.crafting_ing.hide.leather_troll"), 3), + (Item("common.items.mineral.ingot.silver"), 1), (Item("common.items.mineral.ingot.cobalt"), 2), (Item("common.items.crafting_tools.sewing_set"), 0), ], @@ -1129,6 +1125,7 @@ inputs: [ (Item("common.items.crafting_ing.cloth.moonweave"), 10), (Item("common.items.crafting_ing.hide.leather_troll"), 5), + (Item("common.items.mineral.ingot.silver"), 1), (Item("common.items.mineral.ingot.cobalt"), 3), (Item("common.items.crafting_tools.sewing_set"), 0), ], @@ -1180,7 +1177,7 @@ inputs: [ (Item("common.items.crafting_ing.cloth.sunsilk"), 3), (Item("common.items.crafting_ing.animal_misc.phoenix_feather"), 1), - (Item("common.items.mineral.ore.silver"), 1), + (Item("common.items.mineral.ingot.gold"), 1), (Item("common.items.crafting_tools.sewing_set"), 0), ], craft_sprite: Some(Loom), @@ -1189,7 +1186,7 @@ output: ("common.items.armor.cloth.sunsilk.belt", 1), inputs: [ (Item("common.items.crafting_ing.cloth.sunsilk"), 2), - (Item("common.items.mineral.ore.silver"), 1), + (Item("common.items.mineral.ingot.gold"), 1), (Item("common.items.crafting_tools.sewing_set"), 0), ], craft_sprite: Some(Loom), @@ -1199,7 +1196,7 @@ inputs: [ (Item("common.items.crafting_ing.cloth.sunsilk"), 10), (Item("common.items.crafting_ing.animal_misc.phoenix_feather"), 2), - (Item("common.items.mineral.ore.silver"), 2), + (Item("common.items.mineral.ingot.gold"), 2), (Item("common.items.crafting_tools.sewing_set"), 0), ], craft_sprite: Some(Loom), @@ -1208,7 +1205,7 @@ output: ("common.items.armor.cloth.sunsilk.foot", 1), inputs: [ (Item("common.items.crafting_ing.cloth.sunsilk"), 3), - (Item("common.items.mineral.ore.silver"), 2), + (Item("common.items.mineral.ingot.gold"), 2), (Item("common.items.crafting_tools.sewing_set"), 0), ], craft_sprite: Some(Loom), @@ -1217,7 +1214,7 @@ output: ("common.items.armor.cloth.sunsilk.hand", 1), inputs: [ (Item("common.items.crafting_ing.cloth.sunsilk"), 3), - (Item("common.items.mineral.ore.silver"), 2), + (Item("common.items.mineral.ingot.gold"), 2), (Item("common.items.crafting_tools.sewing_set"), 0), ], craft_sprite: Some(Loom), @@ -1226,7 +1223,7 @@ output: ("common.items.armor.cloth.sunsilk.pants", 1), inputs: [ (Item("common.items.crafting_ing.cloth.sunsilk"), 8), - (Item("common.items.mineral.ore.silver"), 3), + (Item("common.items.mineral.ingot.gold"), 3), (Item("common.items.crafting_tools.sewing_set"), 0), ], craft_sprite: Some(Loom), @@ -1235,7 +1232,7 @@ output: ("common.items.armor.cloth.sunsilk.shoulder", 1), inputs: [ (Item("common.items.crafting_ing.cloth.sunsilk"), 8), - (Item("common.items.mineral.ore.silver"), 3), + (Item("common.items.mineral.ingot.gold"), 3), (Item("common.items.crafting_tools.sewing_set"), 0), ], craft_sprite: Some(Loom), @@ -1635,13 +1632,13 @@ "tiny leather pouch": ( output: ("common.items.armor.misc.bag.tiny_leather_pouch", 1), inputs: [ - (Item("common.items.crafting_ing.leather.leather_strips"), 6), + (Item("common.items.crafting_ing.leather.leather_strips"), 12), ], ), "knitted red pouch": ( output: ("common.items.armor.misc.bag.knitted_red_pouch", 1), inputs: [ - (Item("common.items.crafting_ing.cloth.linen_red"), 3), + (Item("common.items.crafting_ing.cloth.wool"), 6), (Item("common.items.armor.misc.bag.tiny_red_pouch"), 2), (Item("common.items.crafting_tools.sewing_set"), 0), ], @@ -1649,7 +1646,7 @@ "woven red bag": ( output: ("common.items.armor.misc.bag.woven_red_bag", 1), inputs: [ - (Item("common.items.crafting_ing.cloth.linen_red"), 6), + (Item("common.items.crafting_ing.cloth.silk"), 6), (Item("common.items.armor.misc.bag.knitted_red_pouch"), 1), (Item("common.items.crafting_tools.sewing_set"), 0), ], @@ -1659,7 +1656,7 @@ inputs: [ (Item("common.items.mineral.gem.diamond"), 2), (Item("common.items.crafting_ing.twigs"), 2), - (Item("common.items.crafting_ing.cloth.linen"), 3), + (Item("common.items.crafting_ing.cloth.silk"), 4), (Item("common.items.crafting_ing.leather.leather_strips"), 3), (Item("common.items.armor.misc.bag.tiny_leather_pouch"), 2), (Item("common.items.crafting_tools.sewing_set"), 0), @@ -1669,9 +1666,9 @@ "sturdy red backpack": ( output: ("common.items.armor.misc.bag.sturdy_red_backpack", 1), inputs: [ - (Item("common.items.mineral.gem.diamond"), 2), + (Item("common.items.mineral.gem.amethyst"), 2), (Item("common.items.crafting_ing.cloth.linen_red"), 3), - (Item("common.items.crafting_ing.leather.thick_leather"), 3), + (Item("common.items.crafting_ing.leather.thick_leather"), 6), (Item("common.items.armor.misc.bag.woven_red_bag"), 1), (Item("common.items.crafting_tools.sewing_set"), 0), ], @@ -1689,7 +1686,7 @@ output: ("common.items.armor.misc.bag.mindflayer_spellbag", 1), inputs: [ (Item("common.items.crafting_ing.mindflayer_bag_damaged"), 1), - (Item("common.items.crafting_ing.leather.thick_leather"), 8), + (Item("common.items.crafting_ing.leather.rigid_leather"), 8), (Item("common.items.mineral.gem.diamond"), 4), (Item("common.items.mineral.ore.veloritefrag"), 10), (Item("common.items.crafting_tools.sewing_set"), 0), diff --git a/assets/voxygen/audio/sfx.ron b/assets/voxygen/audio/sfx.ron index bd9434f765..cb25f11d92 100644 --- a/assets/voxygen/audio/sfx.ron +++ b/assets/voxygen/audio/sfx.ron @@ -5,7 +5,7 @@ // Campfire: ( files: [ - "voxygen.audio.sfx.ambient.fire", + "voxygen.audio.sfx.ambient.fire", ], threshold: 21.835, ), @@ -831,5 +831,126 @@ ], threshold: 0.2, ), + Utterance(Angry, BipedLarge): ( + files: [ + "voxygen.audio.sfx.utterance.ogre_angry1", + "voxygen.audio.sfx.utterance.ogre_angry2", + ], + threshold: 1.0, + ), + Utterance(Angry, Bird): ( + files: [ + "voxygen.audio.sfx.utterance.bird_angry1", + ], + threshold: 1.0, + ), + Utterance(Calm, Pig): ( + files: [ + "voxygen.audio.sfx.utterance.pig_calm1", + ], + threshold: 1.0, + ), + Utterance(Angry, Adlet): ( + files: [ + "voxygen.audio.sfx.utterance.adlet_angry1", + "voxygen.audio.sfx.utterance.adlet_angry2", + ], + threshold: 1.0, + ), + Utterance(Angry, Alligator): ( + files: [ + "voxygen.audio.sfx.utterance.alligator_angry1", + "voxygen.audio.sfx.utterance.alligator_angry2", + ], + threshold: 1.0, + ), + Utterance(Angry, Antelope): ( + files: [ + "voxygen.audio.sfx.utterance.antelope_angry1", + ], + threshold: 1.0, + ), + Utterance(Angry, Reptile): ( + files: [ + "voxygen.audio.sfx.utterance.alligator_angry1", + "voxygen.audio.sfx.utterance.alligator_angry2", + ], + threshold: 1.0, + ), + Utterance(Angry, Saurok): ( + files: [ + "voxygen.audio.sfx.utterance.saurok_angry1", + ], + threshold: 1.0, + ), + Utterance(Angry, Wendigo): ( + files: [ + "voxygen.audio.sfx.utterance.wendigo_angry1", + ], + threshold: 1.0, + ), + Utterance(Calm, Cow): ( + files: [ + "voxygen.audio.sfx.utterance.cow_calm1", + "voxygen.audio.sfx.utterance.cow_calm2", + "voxygen.audio.sfx.utterance.cow_calm3", + ], + threshold: 1.0, + ), + Utterance(Calm, Sheep): ( + files: [ + "voxygen.audio.sfx.utterance.sheep_calm1", + ], + threshold: 1.0, + ), + Utterance(Greeting, HumanMale): ( + files: [ + "voxygen.audio.sfx.utterance.humanmale_greeting1", + ], + threshold: 1.0, + ), + Utterance(Hurt, Adlet): ( + files: [ + "voxygen.audio.sfx.utterance.adlet_hurt1", + "voxygen.audio.sfx.utterance.adlet_hurt2", + ], + threshold: 1.0, + ), + Utterance(Hurt, Antelope): ( + files: [ + "voxygen.audio.sfx.utterance.antelope", + ], + threshold: 1.0, + ), + Utterance(Hurt, HumanMale): ( + files: [ + "voxygen.audio.sfx.utterance.humanmale_hurt1", + ], + threshold: 1.0, + ), + Utterance(Hurt, Lion): ( + files: [ + "voxygen.audio.sfx.utterance.lion_hurt1", + ], + threshold: 1.0, + ), + Utterance(Hurt, Marlin): ( + files: [ + "voxygen.audio.sfx.utterance.marlin_hurt1", + ], + threshold: 1.0, + ), + Utterance(Hurt, Maneater): ( + files: [ + "voxygen.audio.sfx.utterance.maneater_hurt1", + ], + threshold: 1.0, + ), + Utterance(Hurt, Mindflayer): ( + files: [ + "voxygen.audio.sfx.utterance.mindflayer_hurt1", + ], + threshold: 1.0, + ), } ) diff --git a/assets/voxygen/audio/sfx/utterance/adlet_angry1.ogg b/assets/voxygen/audio/sfx/utterance/adlet_angry1.ogg new file mode 100644 index 0000000000..2989a25e5e --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/adlet_angry1.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79edc121cf180d76d07d879de2f7886938c562be46d6fe52e7e04cb31384d78a +size 14109 diff --git a/assets/voxygen/audio/sfx/utterance/adlet_angry2.ogg b/assets/voxygen/audio/sfx/utterance/adlet_angry2.ogg new file mode 100644 index 0000000000..4550863e5b --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/adlet_angry2.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0a280ff8c3556bb4492358a7de1801e138b727c1f9da4878e7737e1bbeafad2 +size 17091 diff --git a/assets/voxygen/audio/sfx/utterance/adlet_hurt1.ogg b/assets/voxygen/audio/sfx/utterance/adlet_hurt1.ogg new file mode 100644 index 0000000000..1d3eb6fa3d --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/adlet_hurt1.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2fe322b89f4370904f56ee67e60b4e5019692fd1a7cb4a1743931d169aed0d1c +size 9159 diff --git a/assets/voxygen/audio/sfx/utterance/adlet_hurt2.ogg b/assets/voxygen/audio/sfx/utterance/adlet_hurt2.ogg new file mode 100644 index 0000000000..1c7fe8305a --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/adlet_hurt2.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:64173b57b5cfa18f86d83d3fb850cdee3a7a1ec58f0714a314381643f4544d28 +size 12955 diff --git a/assets/voxygen/audio/sfx/utterance/alligator_angry1.ogg b/assets/voxygen/audio/sfx/utterance/alligator_angry1.ogg new file mode 100644 index 0000000000..7980df43f9 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/alligator_angry1.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be7e1a79c23e049c46f6ace589907bcb47a4373476dd1c1ff6831f23f90c2b28 +size 20861 diff --git a/assets/voxygen/audio/sfx/utterance/alligator_angry2.ogg b/assets/voxygen/audio/sfx/utterance/alligator_angry2.ogg new file mode 100644 index 0000000000..7f0b1ca572 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/alligator_angry2.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d0e767a3979318558bc583ed97c729025924411b9ac4cf1b40f6fb76997d1215 +size 15381 diff --git a/assets/voxygen/audio/sfx/utterance/antelope_angry1.ogg b/assets/voxygen/audio/sfx/utterance/antelope_angry1.ogg new file mode 100644 index 0000000000..bcc9688a46 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/antelope_angry1.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:24def83183120c92f0e4722a83afdebf990758e5cc54f1d31c2688ed12da720c +size 16845 diff --git a/assets/voxygen/audio/sfx/utterance/antelope_hurt1.ogg b/assets/voxygen/audio/sfx/utterance/antelope_hurt1.ogg new file mode 100644 index 0000000000..8816597048 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/antelope_hurt1.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3afdd23faea117d7c6f51604a823f349230b37a05714ce14b6c4c47f11eba67f +size 15679 diff --git a/assets/voxygen/audio/sfx/utterance/bird_angry1.ogg b/assets/voxygen/audio/sfx/utterance/bird_angry1.ogg new file mode 100644 index 0000000000..bd0c9a7e77 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/bird_angry1.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e028570750b872652dc16dff1dd4cafe34ad568bc079bd8ba379a5ceac66942 +size 11508 diff --git a/assets/voxygen/audio/sfx/utterance/cow_calm1.ogg b/assets/voxygen/audio/sfx/utterance/cow_calm1.ogg new file mode 100644 index 0000000000..fcb6058d93 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/cow_calm1.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb54f07923524c80c8cb35d908165fa55582f0b085790473802fbb578766f347 +size 22691 diff --git a/assets/voxygen/audio/sfx/utterance/cow_calm2.ogg b/assets/voxygen/audio/sfx/utterance/cow_calm2.ogg new file mode 100644 index 0000000000..f060217fe4 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/cow_calm2.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:581a6c86eb6f06ed2694d0cdfa08691fa8bf38fd7fffb57680b41ed5dc1060ed +size 23328 diff --git a/assets/voxygen/audio/sfx/utterance/cow_calm3.ogg b/assets/voxygen/audio/sfx/utterance/cow_calm3.ogg new file mode 100644 index 0000000000..59ae620508 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/cow_calm3.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb77a69af59eb015c20de58bad181f7e02bc82649d33c274302018c8baf4b85a +size 14690 diff --git a/assets/voxygen/audio/sfx/utterance/humanmale_greeting1.ogg b/assets/voxygen/audio/sfx/utterance/humanmale_greeting1.ogg new file mode 100644 index 0000000000..69dbe5a088 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/humanmale_greeting1.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac12e8915ff261097d5aa24debf5685c4da3bc439ba64e6fd0bc12070f2ebff7 +size 12604 diff --git a/assets/voxygen/audio/sfx/utterance/humanmale_hurt1.ogg b/assets/voxygen/audio/sfx/utterance/humanmale_hurt1.ogg new file mode 100644 index 0000000000..f9db0309e9 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/humanmale_hurt1.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bca43c8a18501f7345b2e5314af80c33bca3e464a16a8d9caef5b6e1adb57d5e +size 10669 diff --git a/assets/voxygen/audio/sfx/utterance/mandragora_hurt1.ogg b/assets/voxygen/audio/sfx/utterance/mandragora_hurt1.ogg new file mode 100644 index 0000000000..737590936a --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/mandragora_hurt1.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85a420c21ce7150d4841ad895f065a0bc0d2204b1799c6ec3acb09e2ed65c8ee +size 9531 diff --git a/assets/voxygen/audio/sfx/utterance/maneater_hurt1.ogg b/assets/voxygen/audio/sfx/utterance/maneater_hurt1.ogg new file mode 100644 index 0000000000..cba5563006 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/maneater_hurt1.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ee1d5b9976d7db6c4978d865653658eeb2d98b14e7bbb0a5e5fd2d92fc6d0922 +size 22347 diff --git a/assets/voxygen/audio/sfx/utterance/marlin_hurt1.ogg b/assets/voxygen/audio/sfx/utterance/marlin_hurt1.ogg new file mode 100644 index 0000000000..bd24a8d35e --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/marlin_hurt1.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b539cb75f734be4cf5353fe99342899c6d4e612ab25de6347d372eca83986b5f +size 20057 diff --git a/assets/voxygen/audio/sfx/utterance/mindflayer_hurt1.ogg b/assets/voxygen/audio/sfx/utterance/mindflayer_hurt1.ogg new file mode 100644 index 0000000000..adc0c22a35 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/mindflayer_hurt1.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:78902402673d74be5e3abf8980a95963e08fd52b3ec5ad2de7440ee95297a383 +size 15376 diff --git a/assets/voxygen/audio/sfx/utterance/ogre_angry1.ogg b/assets/voxygen/audio/sfx/utterance/ogre_angry1.ogg new file mode 100644 index 0000000000..819348a228 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/ogre_angry1.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:78f705397c01f73fd2bfad14f0aa3949a5409556cd5f004c185dea358fbd9701 +size 34809 diff --git a/assets/voxygen/audio/sfx/utterance/ogre_angry2.ogg b/assets/voxygen/audio/sfx/utterance/ogre_angry2.ogg new file mode 100644 index 0000000000..da49817cca --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/ogre_angry2.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5c97dcb8f2ff2543a041d07147c04a74b59e43421dd7452eccb095a947bd7466 +size 52973 diff --git a/assets/voxygen/audio/sfx/utterance/pig_calm1.ogg b/assets/voxygen/audio/sfx/utterance/pig_calm1.ogg new file mode 100644 index 0000000000..b5660f8b39 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/pig_calm1.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:397fca64b10178b05d5007b86e166e2ff335380dae69491f95df0e5724b7c2a5 +size 10729 diff --git a/assets/voxygen/audio/sfx/utterance/saurok_angry1.ogg b/assets/voxygen/audio/sfx/utterance/saurok_angry1.ogg new file mode 100644 index 0000000000..a550c1bbe2 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/saurok_angry1.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f859d590ac38bac163f0821eec8e2157f4f021d34d59575ccca2aeedde919ce +size 56816 diff --git a/assets/voxygen/audio/sfx/utterance/sheep_calm1.ogg b/assets/voxygen/audio/sfx/utterance/sheep_calm1.ogg new file mode 100644 index 0000000000..23e9151f17 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/sheep_calm1.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32fd1868f9f58774e1cd93b5e577795e20a6c3f93683ba4adc7666f2157d0eb3 +size 12028 diff --git a/assets/voxygen/audio/sfx/utterance/wendigo_angry1.ogg b/assets/voxygen/audio/sfx/utterance/wendigo_angry1.ogg new file mode 100644 index 0000000000..4c02e0bd36 --- /dev/null +++ b/assets/voxygen/audio/sfx/utterance/wendigo_angry1.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cfbac68b83de452e7be824075ee9104559ca96a9a710be303c89ede0ab4a6a03 +size 42373 diff --git a/assets/voxygen/i18n/en/hud/misc.ron b/assets/voxygen/i18n/en/hud/misc.ron index 04b74ef477..d447525a9f 100644 --- a/assets/voxygen/i18n/en/hud/misc.ron +++ b/assets/voxygen/i18n/en/hud/misc.ron @@ -32,9 +32,9 @@ You are welcome to take whatever you need on your journey! Look at the bottom right of the screen to find various things like your bag, the crafting menu and the map. -The crafting menu allows you to create armor, weapons, food and much more! +The crafting stations allow you to create armor, weapons, food and much more! -The wild animals all around town are a great source of Leather Scraps to create some protection against the dangers of the world. +The wild animals all around town are a great source of Animal Hide to create some protection against the dangers of the world. Whenever you feel ready, try to get even better equipment from the many challenges marked on your map! "#, diff --git a/assets/voxygen/i18n/ru_RU/_manifest.ron b/assets/voxygen/i18n/ru_RU/_manifest.ron index b3844898b4..25d1d25c93 100644 --- a/assets/voxygen/i18n/ru_RU/_manifest.ron +++ b/assets/voxygen/i18n/ru_RU/_manifest.ron @@ -1,18 +1,6 @@ -/// Translation document instructions -/// -/// In order to keep localization documents readible please follow the following -/// rules: -/// - separate the string map sections using a commentary describing the purpose -/// of the next section -/// - prepend multi-line strings with a commentary -/// - append one blank lines after a multi-line strings and two after sections -/// -/// To add a new language in Veloren, just write an additional `.ron` file in -/// `assets/voxygen/i18n` and that's it! -/// /// WARNING: Localization files shall be saved in UTF-8 format without BOM -/// Localization for "global" Russian +/// Localization for RUS ( metadata: ( language_name: "Русский", @@ -41,516 +29,9 @@ scale_ratio: 1.0, ), }, - sub_directories: [], + sub_directories: [], + string_map: { - /// Start Common section - // Texts used in multiple locations with the same formatting - "common.username": "Имя пользователя", - "common.singleplayer": "Одиночная игра", - "common.multiplayer": "Мультиплеер", - "common.servers": "Сервера", - "common.quit": "Выход", - "common.settings": "Настройки", - "common.languages": "Язык", - "common.interface": "Интерфейс", - "common.gameplay": "Геймплей", - "common.controls": "Управление", - "common.video": "Видео", - "common.sound": "Звук", - "common.languages": "Языки", - "common.resume": "Продолжить", - "common.characters": "Персонажи", - "common.close": "Закрыть", - "common.yes": "Да", - "common.no": "Нет", - "common.back": "Назад", - "common.create": "Создать", - "common.okay": "Окей", - "common.accept": "Принять", - "common.decline": "Отклонить", - "common.disclaimer": "Дисклеймер", - "common.cancel": "Отмена", - "common.none": "Нет", - "common.error": "Ошибка", - "common.fatal_error": "Критическая ошибка", - "common.you": "Вы", - "common.automatic": "Авто", - "common.random": "Случайно", - // Settings Window title - "common.interface_settings": "Настройки интерфейса", - "common.gameplay_settings": "Настройки геймплея", - "common.controls_settings": "Настройки управления", - "common.video_settings": "Графические настройки", - "common.sound_settings": "Звуковые настройки", - "common.language_settings": "Языковые настройки", - - // Message when connection to the server is lost - "common.connection_lost": r#"Соединение потеряно! -Сервер перезагрузился? -Клиент обновлен до последней версии?"#, - - - "common.species.orc": "Орк", - "common.species.human": "Человек", - "common.species.dwarf": "Дварф", - "common.species.elf": "Эльф", - "common.species.undead": "Нежить", - "common.species.danari": "Данари", - - "common.weapons.axe": "Топор", - "common.weapons.sword": "Меч", - "common.weapons.staff": "Посох", - "common.weapons.bow": "Лук", - "common.weapons.hammer": "Молот", - "common.weapons.sceptre": "Лечащий посох", - "common.rand_appearance": "Случайная внешность и имя", - /// End Common section - - - /// Start Main screen section - "main.username": "Имя пользователя", - "main.server": "Сервер", - "main.password": "Пароль", - "main.connecting": "Подключение", - "main.creating_world": "Создание мира", - "main.tip": "Совет:", - - // Welcome notice that appears the first time Veloren is started - "main.notice": r#"Добро пожаловать в Veloren-Alpha! - -Прежде чем начать веселье, прими во внимание следующие вещи: - -- Это очень ранняя альфа. Тут есть баги, крайне незавершенный геймплей, неотполированные механики и отсутсвующие фичи. - -- Если у вас есть конструктивный фидбек или сообщение об ошибке, вы можете связаться с нами через Reddit, GitLab или наш Discord-сервер. - -- Veloren лицензирован GPL 3 open-source licence. Это означает, игра бесплатна, ее можно модифицировать и переделывать на свой вкус (при условии, что готовая работа тоже лицензирована GPL 3). - -- Veloren - некоммерческий проект, каждый работает над ним добровольно. -Если тебе нравится, что ты видишь, милости просим присоединиться к команде разработчиков или художественной команде! - -Спасибо за прочтение, мы надеемся, вам понравится игра! - -~ Команда разработчиков Veloren"#, - - // Login process description - "main.login_process": r#"Информация по входу: - -Обратите внимание, что теперь вам нужен аккаунт -играть на серверах с включенной аутентификацией. - -Вы можете создать аккаунт тут: - -https://veloren.net/account/."#, - "main.login.server_not_found": "Сервер не найден", - "main.login.authentication_error": "Ошибка аутентификации на сервер", - "main.login.server_full": "Сервер полон", - "main.login.untrusted_auth_server": "Аутентификация не пройдена", - "main.login.outdated_client_or_server": "ServerWentMad: Возможно, версии несовместимы. Проверьте наличие обновлений.", - "main.login.timeout": "Timeout: Сервер не ответил вовремя. (Перегрузка или проблемы с сетью).", - "main.login.server_shut_down": "Сервер выключен", - "main.login.network_error": "Ошибка сети", - "main.login.failed_sending_request": "Запрос аутентификации провален", - "main.login.invalid_character": "Выбранный персонаж недоступен", - "main.login.client_crashed": "Клиент вылетел", - "main.login.not_on_whitelist": "Чтобы войти, необходимо быть внесенным в Вайтлист", - "main.login.banned": "Вы были забанены по следующей причине", - "main.login.kicked": "Вы были кикнуты по следующей причине", - "main.login.select_language": "Выбрать язык", - - "main.servers.select_server": "Выбрать сервер", - - /// End Main screen section - - - /// Start HUD Section - "hud.do_not_show_on_startup": "Не показывать это при запуске", - "hud.show_tips": "Показать советы", - "hud.quests": "Квесты", - "hud.you_died": "Вы мертвы", - "hud.waypoint_saved": "Точка спауна сохранена", - - "hud.press_key_to_show_keybindings_fmt": "[{key}] Раскладка", - "hud.press_key_to_toggle_lantern_fmt": "[{key}] Фонарь", - "hud.press_key_to_show_debug_info_fmt": "Нажмите {key}, чтобы показать панель отладки", - "hud.press_key_to_toggle_keybindings_fmt": "Нажмите {key}, чтобы показать раскладку", - "hud.press_key_to_toggle_debug_info_fmt": "Нажмите {key}, чтобы включить панель отладки", - - // Chat outputs - "hud.chat.online_msg": "[{name}] сейчас онлайн.", - "hud.chat.offline_msg": "[{name}] сейчас оффлайн.", - - "hud.chat.default_death_msg": "[{name}] умер", - "hud.chat.environmental_kill_msg": "[{name}] умер от {environment}", - "hud.chat.fall_kill_msg": "[{name}] разбился", - "hud.chat.suicide_msg": "[{name}] сам стал виной своей смерти", - - "hud.chat.pvp_melee_kill_msg": "[{attacker}] одолел [{victim}]", - "hud.chat.pvp_ranged_kill_msg": "[{attacker}] подстрелил [{victim}]", - "hud.chat.pvp_explosion_kill_msg": "[{attacker}] взорвал [{victim}]", - "hud.chat.pvp_energy_kill_msg": "[{attacker}] убил [{victim}] с помощью магии", - "hud.chat.pvp_buff_kill_msg": "[{attacker}] убил [{victim}]", - - - "hud.chat.npc_melee_kill_msg": "{attacker} убил [{victim}]", - "hud.chat.npc_ranged_kill_msg": "{attacker} подстрелил [{victim}]", - "hud.chat.npc_explosion_kill_msg": "{attacker} взорвал [{victim}]", - "hud.chat.npc_energy_kill_msg": "{attacker} убил [{victim}] с помощью магии", - "hud.chat.npc_other_kill_msg": "{attacker} убил [{victim}]", - - "hud.chat.loot_msg": "Вы подобрали [{item}]", - "hud.chat.loot_fail": "Ваш инвентарь полон!", - "hud.chat.goodbye": "До встречи!", - "hud.chat.connection_lost": "Соединение потеряно. Кик через {time} секунд.", - - // SCT outputs - "hud.sct.experience": "{amount} Опыт", - "hud.sct.block": "ЗАБЛОКИРОВАНО", - - // Respawn message - "hud.press_key_to_respawn": r#"Нажмите {key}, чтобы возродиться на последнем костре, который вы посетили."#, - - // Welcome message - "hud.welcome": r#"Добро пожаловать в Veloren-Alpha!, - - -Немного советов перед тем началом игры: - - -Нажмите F1, чтобы увидеть доступые команды. - -Напишите /help, чтобы увидеть команды чата. - - -В мире есть сундуки и другие рандомно генерируемые объекты! - -Нажмите ПКМ, чтобы собрать их. - -Чтобы использовать то, что вы нашли в сундуках, откройте свой инвентарь 'B'. - -Двойной клик на предмет в инвентаре использует или экипирует его. - -Чтобы выкинуть его, кликните на предмет, а потом кликните вне инвентаря. - - -Ночи в Veloren могут быть довольно темными. - -Зажгите свой фонарь, нажав на 'G'. - - -Хотите увидеть курсор, чтобы закрыть это окно? Нажмите TAB! - - -Наслаждайтесь миром Veloren."#, - -"hud.temp_quest_headline": r#"Пожалуйста, путешественник, помоги нам!"#, -"hud.temp_quest_text": r#"Подземелья наполнены злыми культистами, -которые появились вокруг наших мирных городов! - - -Собери компанию, запасись едой -и победи мерзкого лидера и его приспешников. - - -Может быть ты даже сможешь получить один из их -магических предметов?"#, - - - - // Inventory - "hud.bag.inventory": "Инвентарь", - "hud.bag.stats_title": "Характеристики", - "hud.bag.exp": "Опыт", - "hud.bag.armor": "Броня", - "hud.bag.stats": "Статы", - "hud.bag.head": "Голова", - "hud.bag.neck": "Шея", - "hud.bag.tabard": "Накидка", - "hud.bag.shoulders": "Плечи", - "hud.bag.chest": "Нагрудник", - "hud.bag.hands": "Руки", - "hud.bag.lantern": "Фонарь", - "hud.bag.glider": "Глайдер", - "hud.bag.belt": "Пояс", - "hud.bag.ring": "Кольцо", - "hud.bag.back": "Спина", - "hud.bag.legs": "Ноги", - "hud.bag.feet": "Ботинки", - "hud.bag.mainhand": "Главная рука", - "hud.bag.offhand": "Второстепенная рука", - - - // Map and Questlog - "hud.map.map_title": "Карта", - "hud.map.qlog_title": "Квесты", - - // Settings - "hud.settings.general": "Общие", - "hud.settings.none": "Нет", - "hud.settings.press_behavior.toggle": "Переключить", - "hud.settings.press_behavior.hold": "Держать", - "hud.settings.help_window": "Окно помощи", - "hud.settings.debug_info": "Панель отладки", - "hud.settings.tips_on_startup": "Советы на старте", - "hud.settings.ui_scale": "Размер интерфейса", - "hud.settings.relative_scaling": "Относительное масштабирование", - "hud.settings.custom_scaling": "Пользовательское масштабирование", - "hud.settings.crosshair": "Перекрестие", - "hud.settings.transparency": "Прозрачность", - "hud.settings.hotbar": "Хотбар", - "hud.settings.toggle_shortcuts": "Отображать ярлыки", - "hud.settings.buffs_skillbar": "Баффы на панели навыков", - "hud.settings.buffs_mmap": "Баффы на миникарте", - "hud.settings.toggle_bar_experience": "Отображать полоску опыта", - "hud.settings.scrolling_combat_text": "Боевой журнал", - "hud.settings.single_damage_number": "Отдельные числа урона", - "hud.settings.cumulated_damage": "Суммарный урон", - "hud.settings.incoming_damage": "Входящий урон", - "hud.settings.cumulated_incoming_damage": "Суммарный входящий урон", - "hud.settings.speech_bubble": "Текстовые облачка", - "hud.settings.speech_bubble_dark_mode": "Темный режим текстовых облачков", - "hud.settings.speech_bubble_icon": "Значок текстовых облачков", - "hud.settings.energybar_numbers": "Отображение полоски энергии", - "hud.settings.values": "Значение", - "hud.settings.percentages": "Проценты", - "hud.settings.chat": "Чат", - "hud.settings.background_transparency": "Прозрачность заднего фона", - "hud.settings.chat_character_name": "Имя персонажа в чате", - "hud.settings.loading_tips": "Советы при загрузке", - - "hud.settings.pan_sensitivity": "Чувствительность камеры", - "hud.settings.zoom_sensitivity": "Чувствительность зума", - "hud.settings.invert_scroll_zoom": "Инвертировать прокрутку зума", - "hud.settings.invert_mouse_y_axis": "Инвертировать ось Y", - "hud.settings.enable_mouse_smoothing": "Размытие камеры", - "hud.settings.free_look_behavior": "Настройка свободной камеры", - "hud.settings.auto_walk_behavior": "Автодвижение", - "hud.settings.stop_auto_walk_on_input": "Остановить автодвижение на кнопку движения", - - "hud.settings.view_distance": "Дальность прорисовки", - "hud.settings.sprites_view_distance": "Дальность прорисовки спрайтов", - "hud.settings.figures_view_distance": "Дальность прорисовки объектов", - "hud.settings.maximum_fps": "Максимум FPS", - "hud.settings.fov": "Поле зрения (градусы)", - "hud.settings.gamma": "Гамма", - "hud.settings.exposure": "Экспозиция", - "hud.settings.ambiance": "Яркость окружения", - "hud.settings.antialiasing_mode": "Сглаживание", - "hud.settings.cloud_rendering_mode": "Рендер облаков", - "hud.settings.fluid_rendering_mode": "Рендер жидкостей", - "hud.settings.fluid_rendering_mode.cheap": "Низко", - "hud.settings.fluid_rendering_mode.shiny": "Высоко", - "hud.settings.cloud_rendering_mode.minimal": "Минимально", - "hud.settings.cloud_rendering_mode.low": "Низко", - "hud.settings.cloud_rendering_mode.medium": "Средне", - "hud.settings.cloud_rendering_mode.high": "Высоко", - "hud.settings.cloud_rendering_mode.ultra": "Ультра", - "hud.settings.fullscreen": "Полный экран", - "hud.settings.fullscreen_mode": "Режим полного экрана", - "hud.settings.fullscreen_mode.exclusive": "Особый", - "hud.settings.fullscreen_mode.borderless": "Без рамок", - "hud.settings.particles": "Частицы", - "hud.settings.resolution": "Разрешение", - "hud.settings.bit_depth": "Разрядность", - "hud.settings.refresh_rate": "Частота обновления", - "hud.settings.save_window_size": "Сохранить размер окна", - "hud.settings.lighting_rendering_mode": "Режим рендера освещения", - "hud.settings.lighting_rendering_mode.ashikhmin": "Тип A - Высоко ", - "hud.settings.lighting_rendering_mode.blinnphong": "Тип B - Средне", - "hud.settings.lighting_rendering_mode.lambertian": "Тип L - Низко", - "hud.settings.shadow_rendering_mode": "Режим рендера теней", - "hud.settings.shadow_rendering_mode.none": "Нет", - "hud.settings.shadow_rendering_mode.cheap": "Низко", - "hud.settings.shadow_rendering_mode.map": "Карта", - "hud.settings.shadow_rendering_mode.map.resolution": "Разрешение", - "hud.settings.lod_detail": "LoD-детали", - "hud.settings.save_window_size": "Сохранить размер окна", - - - "hud.settings.music_volume": "Громкость музыки", - "hud.settings.sound_effect_volume": "Громкость звуковых эффектов", - "hud.settings.audio_device": "Аудио устройство", - - "hud.settings.awaitingkey": "Нажми клавишу...", - "hud.settings.unbound": "Ничего", - "hud.settings.reset_keybinds": "По-умолчанию", - - "hud.social": "Другие игроки", - "hud.social.online": "Онлайн", - "hud.social.friends": "Друзья", - "hud.social.not_yet_available": "Пока недоступно", - "hud.social.faction": "Фракция", - "hud.social.play_online_fmt": "{nb_player} игрок(ов) онлайн", - "hud.social.name": "Имя", - "hud.social.level": "Ур.", - "hud.social.zone": "Зона", - "hud.social.account": "Аккаунт", - - - "hud.crafting": "Крафт", - "hud.crafting.recipes": "Рецепты", - "hud.crafting.ingredients": "Ингредиенты:", - "hud.crafting.craft": "Создать", - "hud.crafting.tool_cata": "Требуется:", - - "hud.group": "Группа", - "hud.group.invite_to_join": "[{name}] пригласил вас в свою группу!", - "hud.group.invite": "Пригласить", - "hud.group.kick": "Кикнуть", - "hud.group.assign_leader": "Назначить лидером", - "hud.group.leave": "Покинуть группу", - "hud.group.dead" : "Мертв", - "hud.group.out_of_range": "Слишком далеко", - "hud.group.add_friend": "Добавить в друзья", - "hud.group.link_group": "Объединить группы", - "hud.group.in_menu": "В меню", - "hud.group.members": "Участники группы", - - "hud.spell": "Заклинания", - - "hud.free_look_indicator": "Свободная камера активна. Нажмите {key}, чтобы выключить", - "hud.auto_walk_indicator": "Автодвижение активно", - - "hud.map.difficulty": "Сложность", - "hud.map.towns": "Города", - "hud.map.castles": "Замки", - "hud.map.dungeons": "Данжи", - "hud.map.caves": "Пещеры", - "hud.map.cave": "Пещера", - "hud.map.town": "Город", - "hud.map.castle": "Замок", - "hud.map.dungeon": "Данж", - "hud.map.difficulty_dungeon": "Сложность данжа: {difficulty}", - "hud.map.drag": "Перетащить", - "hud.map.zoom": "Зум", - "hud.map.recenter": "Рецентрировать", - - /// End HUD section - - - /// Start GameInput section - - "gameinput.primary": "Основная атака", - "gameinput.secondary": "Второстепенная атака/Блок/Прицел", - "gameinput.slot1": "Быстрый слот 1", - "gameinput.slot2": "Быстрый слот 2", - "gameinput.slot3": "Быстрый слот 3", - "gameinput.slot4": "Быстрый слот 4", - "gameinput.slot5": "Быстрый слот 5", - "gameinput.slot6": "Быстрый слот 6", - "gameinput.slot7": "Быстрый слот 7", - "gameinput.slot8": "Быстрый слот 8", - "gameinput.slot9": "Быстрый слот 9", - "gameinput.slot10": "Быстрый слот 10", - "gameinput.swaploadout": "Сменить снаряжение", - "gameinput.togglecursor": "Отображать курсор", - "gameinput.help": "Отображать окно помощи", - "gameinput.toggleinterface": "Отображать интерфейс", - "gameinput.toggledebug": "Отображать FPS и экран отладки", - "gameinput.screenshot": "Сделать скриншот", - "gameinput.toggleingameui": "Отображать неймтеги", - "gameinput.fullscreen": "Включить полный экран", - "gameinput.moveforward": "Двигаться вперед", - "gameinput.moveleft": "Двигаться влево", - "gameinput.moveright": "Двигаться вправо", - "gameinput.moveback": "Двигаться назад", - "gameinput.jump": "Прыжок", - "gameinput.glide": "Глайдер", - "gameinput.roll": "Кувырок", - "gameinput.climb": "Карабкаться", - "gameinput.climbdown": "Карабкаться вниз", - "gameinput.wallleap": "Прыжок от стены", - "gameinput.togglelantern": "Включить фонарь", - "gameinput.mount": "Оседлать", - "gameinput.enter": "Войти", - "gameinput.chat": "Чат", - "gameinput.command": "Командовать", - "gameinput.escape": "Выйти", - "gameinput.map": "Карта", - "gameinput.bag": "Рюкзак", - "gameinput.social": "Социальное", - "gameinput.sit": "Сесть", - "gameinput.spellbook": "Заклинания", - "gameinput.settings": "Настройки", - "gameinput.respawn": "Возродиться", - "gameinput.charge": "Зарядить", - "gameinput.togglewield": "Достать/убрать оружие", - "gameinput.interact": "Взаимодействовать", - "gameinput.freelook": "Свободная камера", - "gameinput.autowalk": "Автодвижение", - "gameinput.dance": "Танцевать", - "gameinput.select": "Выбрать объект", - "gameinput.acceptgroupinvite": "Принять приглашение в группу", - "gameinput.declinegroupinvite": "Отклонить приглашение в группу", - "gameinput.crafting": "Крафт", - "gameinput.fly": "Полет", - "gameinput.sneak": "Скрытность", - "gameinput.swimdown": "Плыть вниз", - "gameinput.swimup": "Плыть вверх", - - /// End GameInput section - - - /// Start chracter selection section - "char_selection.loading_characters": "Загрузка персонажей...", - "char_selection.delete_permanently": "Навсегда удалить этого персонажа?", - "char_selection.deleting_character": "Удаление персонажа...", - "char_selection.change_server": "Сменить сервер", - "char_selection.enter_world": "Войти в мир", - "char_selection.logout": "Выйти в меню", - "char_selection.create_new_character": "Создать нового персонажа", - "char_selection.creating_character": "Создание персонажа...", - "char_selection.character_creation": "Создание персонажа", - - "char_selection.human_default": "Стандартный человек", - "char_selection.level_fmt": "Уровень {level_nb}", - "char_selection.uncanny_valley": "Wilderness", - "char_selection.plains_of_uncertainty": "Plains of Uncertainty", - "char_selection.beard": "Борода", - "char_selection.hair_style": "Прическа", - "char_selection.hair_color": "Цвет волос", - "char_selection.eye_color": "Цвет глаз", - "char_selection.skin": "Кожа", - "char_selection.eyeshape": "Детали глаз", - "char_selection.accessories": "Аксессуары", - "char_selection.create_info_name": "Вашему персонажу необходимо имя!", - - /// End chracter selection section - - - /// Start character window section - "character_window.character_name": "Имя персонажа", - // Charater stats - "character_window.character_stats": r#"Стойкость - -Выносливость - -Сила воли - -Защита -"#, - /// End character window section - - - /// Start Escape Menu Section - "esc_menu.logout": "Выйти в меню", - "esc_menu.quit_game": "Выйти из игры", - /// End Escape Menu Section - - /// Buffs and Debuffs - "buff.remove": "Кликните, чтобы убрать", - "buff.title.missing": "Отсутствует название", - "buff.desc.missing": "Отсутствует описание", - // Buffs - "buff.title.heal": "Лечение", - "buff.desc.heal": "Лечит в течении времени.", - "buff.title.potion": "Зелье", - "buff.desc.potion": "Пьем...", - "buff.title.saturation": "Сыт", - "buff.desc.saturation": "Получайте здоровье от расходников в течении времени.", - // Debuffs - "buff.title.bleed": "Кровотечение", - "buff.desc.bleed": "Наносит переодический урон.", }, @@ -558,105 +39,196 @@ https://veloren.net/account/."#, vector_map: { "loading.tips": [ "Нажмите 'G', чтобы зажечь фонарь.", - "Нажмите 'F1', чтобы увидеть управление по-умолчанию.", - "Вы можете написать /say или /s, чтобы обратиться только к игрокам вблизи вас.", - "Вы можете написать /region или /r, чтобы обратиться к игрокам в нескольких сотнях блоков вокруг вас.", - "Вы можете написать /group или /g, чтобы обратиться к игрокам в вашей группе.", - "Чтобы отправить приватное сообщение, напишите /tell, а затем имя персонажа и сообщение.", - "NPC одного уровня могут быть разной сложности.", - "Осматривайтесь, чтобы найти еду, сундуки и другой лут!", - "Инвентарь забит едой? Попробуйте скрафтить из нее еду получше!", - "Думаете, чем заняться? Подземелья отмечены коричневыми метками на карте!", - "Не забудьте настроить графику под свою систему. Нажмите 'N', чтобы открыть настройки.", - "Играть с остальными веселее! Нажмите 'O', чтобы посмотреть кто онлайн.", - "NPC с черепом около полоски здоровья намного сильнее, по сравнению с вами.", - "Нажмите 'J', чтобы танцевать. Тусовка!", - "Нажмите 'L-Shift', чтобы открыть Глайдер и покорить небеса.", - "Veloren все еще пре-альфа. Мы стараемся улучшать его каждый день!", - "Если вы хотите присоединиться к команде разработчиков или просто пообщаться с нами, заходите на наш Дискорд-сервер.", - "Вы можете включить отображение чисел на полосе здоровья в настройках.", - "Чтобы увидеть свои характеристики нажмите на 'Статы' в инвентаре.", + "Нажмите 'F1', чтобы просмотреть все клавиши по умолчанию.", + "Вы можете ввести /tell или /s, чтобы общаться только с игроками непосредственно вокруг вас.", + "Вы можете ввести /region или /r, чтобы общаться только с игроками в паре сотен блоков вокруг вас.", + "Администраторы могут использовать команду /build для входа в режим постройки.", + "Вы можете ввести /group или /g, чтобы общаться только с игроками в вашей текущей группе.", + "Чтобы отправить личные сообщения, введите /tell, а затем имя игрока и ваше сообщение.", + "Смотрите внимательно чтобы найти еду, сундуки и другие предметы, разбросанные по всему миру!", + "Инвентарь, заполненный едой? Попробуйте приготовить из нее еду получше!", + "Интересно, чем можно заняться? Попробуйте пройти одно из подземелий, отмеченных на карте!", + "Не забудьте настроить графику для вашей системы. Нажмите 'N', чтобы открыть настройки.", + "Играть с другими-это весело! Нажмите 'О', чтобы узнать, кто находится в сети.", + "Нажмите 'J', чтобы танцевать. Вечеринка!", + "Нажмите 'L-Shift', чтобы открыть свой дельтаплан и покорить небо.", + "Veloren все еще находится в Пре-Альфе. Мы делаем все возможное, чтобы улучшать его каждый день!", + "Если вы хотите присоединиться к команде разработчиков или просто пообщаться с нами, присоединяйтесь к нашему серверу Discord.", + "Вы можете переключить отображение количества здоровья на панели здоровья в настройках.", + "Сядьте у костра (с помощью клавиши 'К'), чтобы залечить свои раны.", + "Вам нужно больше сумок или лучшая броня, чтобы продолжить свое путешествие? Нажмите 'C', чтобы открыть меню крафта!", + ], + "npc.speech.villager": [ + "Хорошая погода?", + "Как дела?", + "Доброе утро!", + "Интересно, что думает Catoblepas когда ест траву.", /// in original Catoblepas (киса) но яб сменил на овцу в оригинале + "Хорошая погода, не правда ли?", + "Мысли об этих подземельях пугают меня. Надеюсь их кто-нибудь уничтожит", + "Когда я вырасту, я буду исследовать пещеры.", + "Вы не видели моего кота?", + "Вы когда-нибудь слышали о свирепых сухопутных акулах? Я слышал, они живут в пустынях", + "Говорят, в пещерах можно найти блестящие драгоценные камни всех видов.", + "Я просто помешан на сыре!", + "Ты не зайдешь? Мы как раз собирались съесть немного сыра", + "Говорят, мухоморы полезны для здоровья. Сам я их не ем.", + "Не забудь про печенья!", + "Я просто обожаю сыр дварфов. Я бы хотел научиться его готовить.", + "Интересно, что по ту сторону гор.", + "Я надеюсь сделать свой собственный дельтаплан когда-нибудь.", + "Хочешь, покажу тебе свой сад? Ладно, может в следующий раз.", + "Прекрасный день для прогулки по лесу!", + "Быть или не быть? Я подумываю о том чтобы стать фермером.", + "Тебе не кажется, что наша деревня самая лучшая?", + "Как ты думаешь, что заставляет Glowing Remains светься?", + "Время второго завтрака!", + "Ты когда - нибудь ловил светлячка?", + "I just can't understand where those Sauroks keep coming from.", + "Я бы хотел, чтобы кто-нибудь держал волков подальше от деревнию.", + "Прошлой ночью мне приснился чудесный сон о сыре. Что это значит?", + "Я оставила немного сыра у брата. Теперь я не знаю, съеден сыр или нет. Я называю его сыром Шредингера.", + "Я оставил немного сыра у сестры. Теперь я не знаю, съеден сыр или нет. Я называю его сыром Шредингера.", + "Кто-то должен что-то сделать с этими культистами. Желательно не я.", + "Надеюсь, скоро пойдет дождь. Это было бы хорошо для урожая.", + "Я люблю мед! И я ненавижу пчел.", + "Я хочу однажды увидеть мир. В жизни должно быть что-то большее, чем эта деревня.", + ], + "npc.speech.villager_decline_trade": [ + "Извините, мне нечем торговать.", + "Торговля? Как будто у меня есть что-то, что может вас заинтересовать.", + "Мой дом принадлежит мне, я не променяю его ни на что.", + ], + "npc.speech.merchant_advertisement": [ + "Могу ли я заинтересовать вас сделкой?", + "Ты хочешь со мной поторговать?", + "У меня много товаров, не хочешь взглянуть?" + ], + "npc.speech.merchant_busy": [ + "Эй, подожди своей очереди.", + "Пожалуйста, подождите, я здесь один на всех.", + "Видите другого человека перед собой?", + "Минутку, дай мне закончить.", + "Не лезь вне очереди!", + "Я занят, зайди попозже." + ], + "npc.speech.merchant_trade_successful": [ + "Спасибо, что торгуете со мной!", + "Спасибо вам!", + ], + "npc.speech.merchant_trade_declined": [ + "Может быть, в другой раз, хорошего дня!", + "Жаль, тогда, может быть, в следующий раз!" + ], + "npc.speech.villager_cultist_alarm": [ + "Берегись! На свободе разгуливает культист!", + "К оружию! Культисты атакуют!", + "Как посмели культисты напасть на нашу деревню!", + "Смерть культистам!", + "Культистов здесь не потерпят!", + "Кровожадный культист!", + "Попробуй на вкус острие моего меча, грязный культист!", + "Ничего не сможет смыть кровь с твоих рук, культист!", + "Миллиарды пузырящихся синих ракушек! Культист среди нас!", + "Зло этого культиста вот-вот закончится!", + "Этот культист мой!", + "Приготовься встретить своего создателя, грязный культист!", + "Я вижу культиста! Схватите его!", + "Я вижу культиста! В атаку!", + "Я вижу культиста! Не дайте им сбежать!", + "Будет ли самый почтенный культист заботиться о какой-то СМЕРТИ?!", + "Никогда не прощу! Никогда не забуду! Культист, сожалею!", + "Умри, культист!", + "Ваше царство террора захвачено!", + "Вот тебе за все, что ты сделал!", + "Мы не очень хорошо относимся к вашим людям здесь.", + "Тебе следовало оставаться под землей!", ], "npc.speech.villager_under_attack": [ - "Помогите, меня атакуют!", - "Помогите, меня атакуют!", - "Ай! Меня атакуют!", - "Ай! Меня атакуют! На помощь!", - "Помогите мне! Меня атакуют!", + "Помогите, Меня атакуют!", + "Помогите, Меня атакуют!", + "Оуч, Меня атакуют!", + "Оуч, Меня атакуют!", + "Помоги мне! Меня атакуют!", "Меня атакуют! Помогите!", - "Меня атакуют!! На помощь!", + "Меня атакуют! Помогите мне!", "Помогите!", - "На помощь! На помощь!", + "Помогите! Помогите!", "Помогите! Помогите! Помогите!", "Меня атакуют!", - "ААА! Меня атакуют!", - "AAA! Меня атакуют! На помощь!", - "Помогите! Нас атакуют!", - "На помощь! Убийца!", - "Помогите! Здесь убийца!", - "На помощь! Меня пытаются убить!", - "Стража, меня атакуют!", - "Стража, на помощь!", + "АААААА! Меня атакуют!", + "АААААА! Меня атакуют! Помогите!", + "Помогите! Мы атакованны!", + "Помогите! Убийца!", + "Помогите! Убийца на свободе!", + "Помогите! Они пытаются меня убить!", + "Стража, Меня атакуют!", + "Стража! Меня атакуют!", "Меня атакуют! Стража!", "Помогите! Стража! Меня атакуют!", - "Стража! Cкорее!", + "Стража! Скорее!", "Стража! Стража!", - "Стража! На меня напали!", - "Стража, убейте этого мерзкого злодея", - "Стража! Тут убийца!", - "Стража! Помогите мне!", - "Тебе это не сойдет с рук! Охрана!", - "Ты враг!", - "Помогите!", - "На помощь! Пожалуйста!", - "Ай! Стража, помогите!", - "Они пришли за мной!", - "На помощь, на помощь, на меня напали!", + "Стража! Этот злодей бьёт меня!", + "Стража, Схватите этого негодяя!", + "Стража! Здесь убийца!", + "Стража! Помогите me!", + "Тебе это не сойдет с рук! Стража!", + "Ты изверг!", + "Помогите мне!", + "Помогите! Пожалуйста!", + "Ой! Стража! Помогите!", + "Они идут за мной!", + "Помогите! Помогите! Меня постигла расплата!", "Ах, теперь мы видим насилие, присущее системе.", "Это всего лишь царапина!", - "Прекрати!", - "Что я вообще тебе сделал?!", - "Пожалуйста, прекрати меня бить!", - "Эй, поаккуратнее с этой штукой!", - "Мерзкий негодняй, отстань!", - "Остановись! Уходи!", - "Ты злишь меня!", - "Ай! Кем ты себя возомнил?!", - "Я лишу тебя головы за это!", - "Остановись! У меня нет ничего ценного!", - "Я натравлю на тебя братьев! Они больше меня!", - "Нееет, я расскажу маме!", + "Остановитесь!", + "Что я тебе сделал?!", + "Пожалуйста, не бей!", + "Эй! Смотри, куда направляешь эту штуку", + "Гнусный негодяй, проваливай отсюда!", + "Прекрати! Уходи!", + "Ты уже достал!", + "Эй! Что ты возомнил о себе?!", + "Я тебе башку оторву!", + "Остановись пожалуйста. У меня ничего нет!", + "Я позову брата, он больше меня", + "Нет! Я расскажу маме!", "Будь ты проклят!", - "Пожалуйста, не надо!", - "Это было недружелюбно!", - "Хорошо, ты сильный, а теперь убери оружие!", - "Пощади меня!", + "Пожалуйста, не делай этого.", + "Это не приятно!", + "Ваше оружие работает, вы можете убрать его прямо сейчас!", + "Пощади!", "Пожалуйста, у меня семья!", - "Я слишком молод, чтобы умирать!", - "Мы можем решить все словами?", + "Я слишком молод чтобы умереть!", + "Может договоримся?", "Насилие не выход!", - "Так и знал, что день будет плохим...", - "Эй, больно же!", - "Эй!", - "Как некультурно!", - "Остановись, я прошу!", - "Проклятие!", + "Сегодня выдался плохой день...", + "Эй, это больно!", + "Ик!", + "Как грубо!", + "Остановись, прошу тебя!", + "Чтоб ты сдох!", "Это не смешно.", "Как ты смеешь?!", "Ты заплатишь за это!", - "Не продолжай, а то пожалеешь!", - "Не заставляй делать тебе больно!", - "Ты все неправильно понял!", - "Зачем ты так?!", - "Проваливай, вражина!", - "Это было больно!", - "Почему ты это делаешь?", - "Ради духов, уймись!", - "Ты меня с кем-то спутал!", - "Я не заслужил этого!", - "Пожалуйста, не делай так больше.", - "Стража, киньте этого монстра в озеро!", - "Я натравлю на тебя своего тараска!", + "Ты об этом пожалеешь!", + "Не заставляй меня делать тебе больно!", + "Произошла какая то ошибка!", + "Не делай этого!", + "Изыди, дьявол", + "Это очень больно!", + "Зачем ты это сделал?", + "Ради всего святого, прекрати!", + "Ты меня перепутал с кем то", + "Я не заслуживаю этого!", + "Пожалуйста, больше так не делай.", + "Стража, утопите этого монстра в озере!", + "Я натравлю своего tarasque на тебя!", + "Почему я?", ], + "npc.speech.villager_enemy_killed": [ + "Я уничтожил врага!", + "Наконец-то мир!", + "... что же я наделал?", + ] } ) diff --git a/assets/voxygen/i18n/ru_RU/char_selection.ron b/assets/voxygen/i18n/ru_RU/char_selection.ron new file mode 100644 index 0000000000..a990ea7775 --- /dev/null +++ b/assets/voxygen/i18n/ru_RU/char_selection.ron @@ -0,0 +1,32 @@ +/// WARNING: Localization files shall be saved in UTF-8 format without BOM + +/// Localization for "global" English +( + string_map: { + "char_selection.loading_characters": "Загрузка персонажей...", + "char_selection.delete_permanently": "Навсегда удалить этого персонажа?", + "char_selection.deleting_character": "Удаление Персонажа...", + "char_selection.change_server": "Сменить сервер", + "char_selection.enter_world": "Войти в мир", + "char_selection.logout": "Разлогиниться", + "char_selection.create_new_character": "Создать нового персонажа", + "char_selection.creating_character": "Создание персонажа...", + "char_selection.character_creation": "Персонаж создан", + "char_selection.human_default": "Стандартный человек", + "char_selection.level_fmt": "Уровень {level_nb}", + "char_selection.uncanny_valley": "Wilderness", + "char_selection.plains_of_uncertainty": "Plains of Uncertainty", + "char_selection.beard": "Борода", + "char_selection.hair_style": "Прическа", + "char_selection.hair_color": "Цвет волос", + "char_selection.eye_color": "Цвет глаз", + "char_selection.skin": "Кожа", + "char_selection.eyeshape": "Детали глаз", + "char_selection.accessories": "Аксессуары", + "char_selection.create_info_name": "Вашему персонажу нужно имя!", + "char_selection.version_mismatch": "ПРЕДУПРЕЖДЕНИЕ! На этом сервере работает другая, возможно, несовместимая версия игры. Пожалуйста, обновите свою игру.", + }, + + vector_map: { + } +) diff --git a/assets/voxygen/i18n/ru_RU/common.ron b/assets/voxygen/i18n/ru_RU/common.ron new file mode 100644 index 0000000000..b72812e10c --- /dev/null +++ b/assets/voxygen/i18n/ru_RU/common.ron @@ -0,0 +1,117 @@ +/// WARNING: Localization files shall be saved in UTF-8 format without BOM + +/// Localization for RUS +( + string_map: { + // Texts used in multiple locations with the same formatting + "common.username": "Юзернейм", + "common.singleplayer": "Одиночная игра", + "common.multiplayer": "Онлайн игра", + "common.servers": "Сервера", + "common.quit": "Выход", + "common.settings": "Настройки", + "common.languages": "Языки", + "common.interface": "Интерфейс", + "common.gameplay": "Гемплей", + "common.controls": "Управление", + "common.video": "Графика", + "common.sound": "Звук", + "common.chat": "Чат", + "common.resume": "Продолжить", + "common.characters": "Персонажи", + "common.close": "Закрыть", + "common.yes": "Да", + "common.no": "Нет", + "common.back": "Назад", + "common.create": "Создание", + "common.okay": "Окей", + "common.add": "Добавить", + "common.accept": "Принять", + "common.decline": "Отказаться", + "common.disclaimer": "Предупреждение", + "common.cancel": "Отменить", + "common.none": "Отключены", + "common.error": "Ошибка", + "common.fatal_error": "Фатальная ошибка", + "common.you": "Вы", + "common.automatic": "Авто", + "common.random": "Случайно", + "common.empty": "Пустой", + + // Settings Window title + "common.interface_settings": "Настройки интерфейса", + "common.gameplay_settings": "Настройки гемплея", + "common.controls_settings": "Настройки управления", + "common.video_settings": "Графические настройки", + "common.sound_settings": "Настройки звука", + "common.language_settings": "Настройки языка", + "common.chat_settings": "Настройки чата", + + // Message when connection to the server is lost + "common.connection_lost": r#"Связь потеряна! +Клиент обновлен до версии сервера?"#, + + + "common.species.orc": "Орк", + "common.species.human": "Человек", + "common.species.dwarf": "Дварфы", + "common.species.elf": "Эльфы", + "common.species.undead": "Нежить", + "common.species.danari": "Данари", + + "common.weapons.axe": "Топор", + "common.weapons.sword": "Меч", + "common.weapons.staff": "Посох", + "common.weapons.bow": "Лук", + "common.weapons.hammer": "Молот", + "common.weapons.general": "Общий бой", + "common.weapons.sceptre": "Скипетр", + "common.weapons.shield": "Защита", + "common.weapons.spear": "Копье", + "common.weapons.hammer_simple": "Простой молот", + "common.weapons.sword_simple": "Простой меч", + "common.weapons.staff_simple": "Простой посох", + "common.weapons.axe_simple": "Простой топор", + "common.weapons.bow_simple": "Простой лук", + "common.weapons.unique": "Уникальный", + "common.tool.debug": "Дебаг", + "common.tool.faming": "Сельскохозяйственный инструмент", + "common.tool.pick": "Кирка", + "common.kind.modular_component": "Компонент", + "common.kind.glider": "Дельтаплан", + "common.kind.consumable": "Расходуемый", + "common.kind.throwable": "Можно бросить", + "common.kind.utility": "Полезность", + "common.kind.ingredient": "Ингредиент", + "common.kind.lantern": "Фонарь", + "common.hands.one": "Одноручное", + "common.hands.two": "Двуручное", + + "common.rand_appearance": "Случайная внешность", + "common.rand_name": "Случайное имя", + + "common.stats.combat_rating": "CR", + "common.stats.power": "Сила", + "common.stats.speed": "Скорость", + "common.stats.poise": "Равновесие", + "common.stats.crit_chance": "Крит шанс", + "common.stats.crit_mult": "Множитель крита", + "common.stats.armor": "Броня", + "common.stats.poise_res":"Оглушение", + "common.stats.energy_max": "Максимальная выносливость", + "common.stats.energy_reward": "Востановление выносливости", + "common.stats.crit_power": "Сила крита", + "common.stats.stealth": "Скрытность", + "common.stats.slots": "Слоты", + + "common.material.metal": "Метал", + "common.material.wood": "Дерево", + "common.material.stone": "Камень", + "common.material.cloth": "Ткань", + "common.material.hide": "Кожа", + }, + + + vector_map: { + } +) diff --git a/assets/voxygen/i18n/ru_RU/gameinput.ron b/assets/voxygen/i18n/ru_RU/gameinput.ron new file mode 100644 index 0000000000..db8d764eac --- /dev/null +++ b/assets/voxygen/i18n/ru_RU/gameinput.ron @@ -0,0 +1,73 @@ +/// WARNING: Localization files shall be saved in UTF-8 format without BOM + +/// Localization for RUS +( + string_map: { + "gameinput.primary": "Основная атака", + "gameinput.secondary": "Вторичная атака", + "gameinput.block": "Блок", + "gameinput.slot1": "Быстрое меню 1", + "gameinput.slot2": "Быстрое меню 2", + "gameinput.slot3": "Быстрое меню 3", + "gameinput.slot4": "Быстрое меню 4", + "gameinput.slot5": "Быстрое меню 5", + "gameinput.slot6": "Быстрое меню 6", + "gameinput.slot7": "Быстрое меню 7", + "gameinput.slot8": "Быстрое меню 8", + "gameinput.slot9": "Быстрое меню 9", + "gameinput.slot10": "Быстрое меню 10", + "gameinput.swaploadout": "Сменить снаряжение", + "gameinput.togglecursor": "ВКЛ/ВЫКЛ курсор", + "gameinput.help": "ВКЛ/ВЫКЛ окно помощи", + "gameinput.toggleinterface": "ВКЛ/ВЫКЛ интерфейс", + "gameinput.toggledebug": "ВКЛ/ВЫКЛ FPS и отладочную информацию", + "gameinput.screenshot": "Сделать скриншот", + "gameinput.toggleingameui": "ВЫКЛ/ВЫКЛ никнеймы и имена", + "gameinput.fullscreen": "ВКЛ/ВЫКЛ полноэкранный режим", + "gameinput.moveforward": "Двигаться вперед", + "gameinput.moveleft": "Двигаться влево", + "gameinput.moveright": "Двигаться вправо", + "gameinput.moveback": "Двигаться назад", + "gameinput.jump": "Прыжок", + "gameinput.glide": "Дельтаплан", + "gameinput.roll": "Перекат", + "gameinput.climb": "Взбираться", + "gameinput.climbdown": "Спускаться", + "gameinput.wallleap": "Прыжок от стены", + "gameinput.togglelantern": "ВКЛ/ВЫКЛ фонарь", + "gameinput.mount": "Оседлать", + "gameinput.chat": "Чат", + "gameinput.command": "Команда", + "gameinput.escape": "Назад", + "gameinput.map": "Карта", + "gameinput.bag": "Рюкзак", + "gameinput.trade": "Обмен", + "gameinput.social": "Список игроков", + "gameinput.sit": "Сидеть", + "gameinput.spellbook": "Навыки", + "gameinput.settings": "Настройки", + "gameinput.respawn": "Возродиться", + "gameinput.charge": "Зарядить", + "gameinput.togglewield": "Переключить Управление", + "gameinput.interact": "Взаимодействовать", + "gameinput.freelook": "Свободная камера", + "gameinput.autowalk": "Автодвижение", + "gameinput.cameraclamp": "Фиксирование камеры", + "gameinput.dance": "Танцевать", + "gameinput.select": "Выбор объекта", + "gameinput.acceptgroupinvite": "Принять приглашение в группу", + "gameinput.declinegroupinvite": "Отвергнуть приглашение в группу", + "gameinput.cyclecamera": "Переключение камеры", + "gameinput.crafting": "Крафтинг", + "gameinput.fly": "Полет", + "gameinput.sneak": "Красться", + "gameinput.swimdown": "Погружение (в воду)", + "gameinput.swimup": "Всплыть", + "gameinput.mapzoomin": "Увеличение масштаба карты", + "gameinput.mapzoomout": "Уменьшение масштаба карты", + }, + + + vector_map: { + } +) diff --git a/assets/voxygen/i18n/ru_RU/main.ron b/assets/voxygen/i18n/ru_RU/main.ron index 26a42b40d1..752188d27f 100644 --- a/assets/voxygen/i18n/ru_RU/main.ron +++ b/assets/voxygen/i18n/ru_RU/main.ron @@ -1,6 +1,6 @@ /// WARNING: Localization files shall be saved in UTF-8 format without BOM -/// Localization for RU +/// Localization for RUS ( string_map: { /// Start Main screen section @@ -52,14 +52,14 @@ https://veloren.net/account/."#, "main.login.network_wrong_version": "Несоответствие версии сервера и клиента, пожалуйста, обновите свой игровой клиент.", "main.login.failed_sending_request": "Не удалось выполнить запрос на сервер аутентификации", "main.login.invalid_character": "Выбранный символ недопустим", - "main.login.client_crashed": "Клиент разбился", + "main.login.client_crashed": "Клиент крашнулся", "main.login.not_on_whitelist": "Вам нужна запись в Белом списке от администратора, чтобы присоединиться", "main.login.banned": "Вы были забанены по следующей причине", "main.login.kicked": "Вас выгнали по следующей причине", "main.login.select_language": "Выберите язык", "main.login.client_version": "Версия клиента", - "main.login.server_version": "Server Version", - "main.servers.select_server": "Версия сервера", + "main.login.server_version": "Версия сервера", + "main.servers.select_server": "Выбор сервера", /// End Main screen section }, diff --git a/assets/voxygen/i18n/ru_RU/skills.ron b/assets/voxygen/i18n/ru_RU/skills.ron index 5b898545cf..8b347dcd22 100644 --- a/assets/voxygen/i18n/ru_RU/skills.ron +++ b/assets/voxygen/i18n/ru_RU/skills.ron @@ -1,6 +1,6 @@ /// WARNING: Localization files shall be saved in UTF-8 format without BOM -/// Localization for "global" English +/// Localization for RUS ( string_map: { "hud.rank_up": "Новый скиллпоинт", @@ -169,11 +169,11 @@ "hud.skill.hmr_single_strike_knockback" : "Увеличьте потенциал отбрасывания на 50%{SP}", "hud.skill." : "", // Sword - "hud.skill.sw_trip_str_title": "Тройное вращение", - "hud.skill.sw_trip_str": "Вращение на 3 оборота", + "hud.skill.sw_trip_str_title": "Тройной удар", + "hud.skill.sw_trip_str": "Атака из 3х ударов в комбо", "hud.skill.sw_trip_str_combo_title": "Тройной удар Комбо", - "hud.skill.sw_trip_str_combo": "Разблокирует комбо при тройном вращении{SP}", - "hud.skill.sw_trip_str_dmg_title": "Урон тройного вращения", + "hud.skill.sw_trip_str_combo": "Разблокирует комбо для тройного удара{SP}", + "hud.skill.sw_trip_str_dmg_title": "Урон тройного удара", "hud.skill.sw_trip_str_dmg": "Увеличивает урон, наносимый каждым последующим ударом{SP}", "hud.skill.sw_trip_str_sp_title": "Скорость атаки", "hud.skill.sw_trip_str_sp": "Увеличивает скорость атаки, получаемую при каждом последующем ударе{SP}", diff --git a/assets/voxygen/shaders/particle-vert.glsl b/assets/voxygen/shaders/particle-vert.glsl index a97e1bdffe..3cd9721a47 100644 --- a/assets/voxygen/shaders/particle-vert.glsl +++ b/assets/voxygen/shaders/particle-vert.glsl @@ -71,6 +71,7 @@ const int BUBBLES = 29; const int WATER = 30; const int ICE_SPIKES = 31; const int DRIP = 32; +const int TORNADO = 33; // meters per second squared (acceleration) const float earth_gravity = 9.807; @@ -543,6 +544,15 @@ void main() { spin_in_axis(vec3(1,0,0),0) ); break; + case TORNADO: + f_reflect = 0.0; + attr = Attr( + spiral_motion(vec3(0, 0, 5), abs(rand0) + abs(rand1) * percent() * 3.0, percent(), 15.0 * abs(rand2), rand3), + vec3((2.5 * (1 - slow_start(0.05)))), + vec4(vec3(1.2 + 0.5 * percent()), 1), + spin_in_axis(vec3(rand6, rand7, rand8), percent() * 10 + 3 * rand9) + ); + break; default: attr = Attr( linear_motion( diff --git a/assets/voxygen/voxel/biped_large_central_manifest.ron b/assets/voxygen/voxel/biped_large_central_manifest.ron index e002711ae2..4d2830c1b2 100644 --- a/assets/voxygen/voxel/biped_large_central_manifest.ron +++ b/assets/voxygen/voxel/biped_large_central_manifest.ron @@ -156,22 +156,22 @@ central: ("armor.empty"), ) ), - (Troll, Male): ( + (Cavetroll, Male): ( head: ( - offset: (-8.0, -8.5, -9.0), - central: ("npc.troll.male.head"), + offset: (-8.0, -8.0, -8.5), + central: ("npc.troll_cave.male.head"), ), torso_upper: ( - offset: (-8.0, -7.5, -11.0), - central: ("npc.troll.male.torso_upper"), + offset: (-8.0, -9.5, -11.0), + central: ("npc.troll_cave.male.torso_upper"), ), torso_lower: ( - offset: (-6.0, -3.5, -5.0), - central: ("npc.troll.male.torso_lower"), + offset: (-7.0, -5.5, -7.0), + central: ("npc.troll_cave.male.torso_lower"), ), jaw: ( - offset: (-4.0, 0.0, -4.5), - central: ("npc.troll.male.jaw"), + offset: (-5.0, 0.0, -4.5), + central: ("npc.troll_cave.male.jaw"), ), tail: ( offset: (0.0, 0.0, 0.0), @@ -182,22 +182,126 @@ central: ("armor.empty"), ) ), - (Troll, Female): ( + (Cavetroll, Female): ( head: ( - offset: (-8.0, -8.5, -9.0), - central: ("npc.troll.male.head"), + offset: (-8.0, -8.0, -8.5), + central: ("npc.troll_cave.male.head"), ), torso_upper: ( - offset: (-8.0, -7.5, -11.0), - central: ("npc.troll.male.torso_upper"), + offset: (-8.0, -9.5, -11.0), + central: ("npc.troll_cave.male.torso_upper"), ), torso_lower: ( - offset: (-6.0, -3.5, -5.0), - central: ("npc.troll.male.torso_lower"), + offset: (-7.0, -5.5, -7.0), + central: ("npc.troll_cave.male.torso_lower"), + ), + jaw: ( + offset: (-5.0, 0.0, -4.5), + central: ("npc.troll_cave.male.jaw"), + ), + tail: ( + offset: (0.0, 0.0, 0.0), + central: ("armor.empty"), + ), + second: ( + offset: (0.0, 0.0, 0.0), + central: ("armor.empty"), + ) + ), + (Mountaintroll, Male): ( + head: ( + offset: (-9.0, -8.5, -10.0), + central: ("npc.troll_mountain.male.head"), + ), + torso_upper: ( + offset: (-9.0, -10.0, -14.5), + central: ("npc.troll_mountain.male.torso_upper"), + ), + torso_lower: ( + offset: (-7.0, -5.5, -7.0), + central: ("npc.troll_mountain.male.torso_lower"), ), jaw: ( offset: (-4.0, 0.0, -4.5), - central: ("npc.troll.male.jaw"), + central: ("npc.troll_mountain.male.jaw"), + ), + tail: ( + offset: (0.0, 0.0, 0.0), + central: ("armor.empty"), + ), + second: ( + offset: (0.0, 0.0, 0.0), + central: ("armor.empty"), + ) + ), + (Mountaintroll, Female): ( + head: ( + offset: (-9.0, -8.5, -10.0), + central: ("npc.troll_mountain.male.head"), + ), + torso_upper: ( + offset: (-9.0, -10.0, -14.5), + central: ("npc.troll_mountain.male.torso_upper"), + ), + torso_lower: ( + offset: (-7.0, -5.5, -7.0), + central: ("npc.troll_mountain.male.torso_lower"), + ), + jaw: ( + offset: (-4.0, 0.0, -4.5), + central: ("npc.troll_mountain.male.jaw"), + ), + tail: ( + offset: (0.0, 0.0, 0.0), + central: ("armor.empty"), + ), + second: ( + offset: (0.0, 0.0, 0.0), + central: ("armor.empty"), + ) + ), + (Swamptroll, Male): ( + head: ( + offset: (-10.0, -6.5, -6.0), + central: ("npc.troll_swamp.male.head"), + ), + torso_upper: ( + offset: (-9.0, -9.0, -12.5), + central: ("npc.troll_swamp.male.torso_upper"), + ), + torso_lower: ( + offset: (-8.0, -6.5, -10.0), + central: ("npc.troll_swamp.male.torso_lower"), + ), + jaw: ( + offset: (-6.0, 0.0, -4.0), + central: ("npc.troll_swamp.male.jaw"), + ), + tail: ( + offset: (0.0, 0.0, 0.0), + central: ("armor.empty"), + ), + second: ( + offset: (0.0, 0.0, 0.0), + central: ("armor.empty"), + ) + ), + (Swamptroll, Female): ( + head: ( + offset: (-10.0, -6.5, -6.0), + central: ("npc.troll_swamp.male.head"), + ), + torso_upper: ( + offset: (-9.0, -9.0, -12.5), + central: ("npc.troll_swamp.male.torso_upper"), + ), + torso_lower: ( + offset: (-8.0, -6.5, -10.0), + central: ("npc.troll_swamp.male.torso_lower"), + ), + jaw: ( + offset: (-6.0, 0.0, -4.0), + central: ("npc.troll_swamp.male.jaw"), ), tail: ( offset: (0.0, 0.0, 0.0), diff --git a/assets/voxygen/voxel/biped_large_lateral_manifest.ron b/assets/voxygen/voxel/biped_large_lateral_manifest.ron index 0ba3855037..8c8f0c046b 100644 --- a/assets/voxygen/voxel/biped_large_lateral_manifest.ron +++ b/assets/voxygen/voxel/biped_large_lateral_manifest.ron @@ -203,72 +203,208 @@ lateral: ("npc.wendigo.male.foot_r"), ), ), - (Troll, Male): ( + (Cavetroll, Male): ( shoulder_l: ( - offset: (-5.0, -4.5, -11.0), - lateral: ("npc.troll.male.shoulder_l"), + offset: (-5.5, -4.0, -8.0), + lateral: ("npc.troll_cave.male.shoulder_l"), ), shoulder_r: ( - offset: (-5.0, -4.5, -11.0), - lateral: ("npc.troll.male.shoulder_r"), + offset: (-5.5, -4.0, -8.0), + lateral: ("npc.troll_cave.male.shoulder_r"), ), hand_l: ( - offset: (-3.5, -4.0, -12.0), - lateral: ("npc.troll.male.hand_l"), + offset: (-4.5, -4.0, -14.0), + lateral: ("npc.troll_cave.male.hand_l"), ), hand_r: ( - offset: (-3.5, -4.0, -12.0), - lateral: ("npc.troll.male.hand_r"), + offset: (-4.5, -4.0, -14.0), + lateral: ("npc.troll_cave.male.hand_r"), ), leg_l: ( - offset: (-3.0, -2.5, -4.5), - lateral: ("npc.troll.male.leg_l"), + offset: (-3.0, -3.0, -4.0), + lateral: ("npc.troll_cave.male.leg_l"), ), leg_r: ( - offset: (-3.0, -2.5, -4.5), - lateral: ("npc.troll.male.leg_r"), + offset: (-3.0, -3.0, -4.0), + lateral: ("npc.troll_cave.male.leg_r"), ), foot_l: ( offset: (-3.0, -5.0, -2.5), - lateral: ("npc.troll.male.foot_l"), + lateral: ("npc.troll_cave.male.foot_l"), ), foot_r: ( offset: (-3.0, -5.0, -2.5), - lateral: ("npc.troll.male.foot_r"), + lateral: ("npc.troll_cave.male.foot_r"), ), ), - (Troll, Female): ( + (Cavetroll, Female): ( shoulder_l: ( - offset: (-5.0, -4.5, -11.0), - lateral: ("npc.troll.male.shoulder_l"), + offset: (-5.5, -4.0, -8.0), + lateral: ("npc.troll_cave.male.shoulder_l"), ), shoulder_r: ( - offset: (-5.0, -4.5, -11.0), - lateral: ("npc.troll.male.shoulder_r"), + offset: (-5.5, -4.0, -8.0), + lateral: ("npc.troll_cave.male.shoulder_r"), ), hand_l: ( - offset: (-3.5, -4.0, -12.0), - lateral: ("npc.troll.male.hand_l"), + offset: (-4.5, -4.0, -14.0), + lateral: ("npc.troll_cave.male.hand_l"), ), hand_r: ( - offset: (-3.5, -4.0, -12.0), - lateral: ("npc.troll.male.hand_r"), + offset: (-4.5, -4.0, -14.0), + lateral: ("npc.troll_cave.male.hand_r"), ), leg_l: ( - offset: (-3.0, -2.5, -4.5), - lateral: ("npc.troll.male.leg_l"), + offset: (-3.0, -3.0, -4.0), + lateral: ("npc.troll_cave.male.leg_l"), ), leg_r: ( - offset: (-3.0, -2.5, -4.5), - lateral: ("npc.troll.male.leg_r"), + offset: (-3.0, -3.0, -4.0), + lateral: ("npc.troll_cave.male.leg_r"), ), foot_l: ( offset: (-3.0, -5.0, -2.5), - lateral: ("npc.troll.male.foot_l"), + lateral: ("npc.troll_cave.male.foot_l"), ), foot_r: ( offset: (-3.0, -5.0, -2.5), - lateral: ("npc.troll.male.foot_r"), + lateral: ("npc.troll_cave.male.foot_r"), + ), + ), + (Mountaintroll, Male): ( + shoulder_l: ( + offset: (-6.5, -5.0, -8.5), + lateral: ("npc.troll_mountain.male.shoulder_l"), + ), + shoulder_r: ( + offset: (-6.5, -5.0, -8.5), + lateral: ("npc.troll_mountain.male.shoulder_r"), + ), + hand_l: ( + offset: (-5.0, -4.5, -14.0), + lateral: ("npc.troll_mountain.male.hand_l"), + ), + hand_r: ( + offset: (-5.0, -4.5, -14.0), + lateral: ("npc.troll_mountain.male.hand_r"), + ), + leg_l: ( + offset: (-3.0, -3.0, -4.0), + lateral: ("npc.troll_mountain.male.leg_l"), + ), + leg_r: ( + offset: (-3.0, -3.0, -4.0), + lateral: ("npc.troll_mountain.male.leg_r"), + ), + foot_l: ( + offset: (-3.0, -5.0, -2.5), + lateral: ("npc.troll_mountain.male.foot_l"), + ), + foot_r: ( + offset: (-3.0, -5.0, -2.5), + lateral: ("npc.troll_mountain.male.foot_r"), + ), + ), + (Mountaintroll, Female): ( + shoulder_l: ( + offset: (-6.5, -5.0, -8.5), + lateral: ("npc.troll_mountain.male.shoulder_l"), + ), + shoulder_r: ( + offset: (-6.5, -5.0, -8.5), + lateral: ("npc.troll_mountain.male.shoulder_r"), + ), + hand_l: ( + offset: (-5.0, -4.5, -14.0), + lateral: ("npc.troll_mountain.male.hand_l"), + ), + hand_r: ( + offset: (-5.0, -4.5, -14.0), + lateral: ("npc.troll_mountain.male.hand_r"), + ), + leg_l: ( + offset: (-3.0, -3.0, -4.0), + lateral: ("npc.troll_mountain.male.leg_l"), + ), + leg_r: ( + offset: (-3.0, -3.0, -4.0), + lateral: ("npc.troll_mountain.male.leg_r"), + ), + foot_l: ( + offset: (-3.0, -5.0, -2.5), + lateral: ("npc.troll_mountain.male.foot_l"), + ), + foot_r: ( + offset: (-3.0, -5.0, -2.5), + lateral: ("npc.troll_mountain.male.foot_r"), + ), + ), + (Swamptroll, Male): ( + shoulder_l: ( + offset: (-5.5, -5.0, -8.5), + lateral: ("npc.troll_swamp.male.shoulder_l"), + ), + shoulder_r: ( + offset: (-5.5, -5.0, -8.5), + lateral: ("npc.troll_swamp.male.shoulder_r"), + ), + hand_l: ( + offset: (-5.0, -4.0, -16.0), + lateral: ("npc.troll_swamp.male.hand_l"), + ), + hand_r: ( + offset: (-5.0, -4.0, -16.0), + lateral: ("npc.troll_swamp.male.hand_r"), + ), + leg_l: ( + offset: (-3.0, -3.0, -4.0), + lateral: ("npc.troll_swamp.male.leg_l"), + ), + leg_r: ( + offset: (-3.0, -3.0, -4.0), + lateral: ("npc.troll_swamp.male.leg_r"), + ), + foot_l: ( + offset: (-3.0, -5.0, -2.5), + lateral: ("npc.troll_swamp.male.foot_l"), + ), + foot_r: ( + offset: (-3.0, -5.0, -2.5), + lateral: ("npc.troll_swamp.male.foot_r"), + ), + ), + (Swamptroll, Female): ( + shoulder_l: ( + offset: (-5.5, -5.0, -8.5), + lateral: ("npc.troll_swamp.male.shoulder_l"), + ), + shoulder_r: ( + offset: (-5.5, -5.0, -8.5), + lateral: ("npc.troll_swamp.male.shoulder_r"), + ), + hand_l: ( + offset: (-5.0, -4.0, -16.0), + lateral: ("npc.troll_swamp.male.hand_l"), + ), + hand_r: ( + offset: (-5.0, -4.0, -16.0), + lateral: ("npc.troll_swamp.male.hand_r"), + ), + leg_l: ( + offset: (-3.0, -3.0, -4.0), + lateral: ("npc.troll_swamp.male.leg_l"), + ), + leg_r: ( + offset: (-3.0, -3.0, -4.0), + lateral: ("npc.troll_swamp.male.leg_r"), + ), + foot_l: ( + offset: (-3.0, -5.0, -2.5), + lateral: ("npc.troll_swamp.male.foot_l"), + ), + foot_r: ( + offset: (-3.0, -5.0, -2.5), + lateral: ("npc.troll_swamp.male.foot_r"), ), ), (Dullahan, Male): ( diff --git a/assets/voxygen/voxel/bird_large_central_manifest.ron b/assets/voxygen/voxel/bird_large_central_manifest.ron index f8a0999986..a706aa79cf 100644 --- a/assets/voxygen/voxel/bird_large_central_manifest.ron +++ b/assets/voxygen/voxel/bird_large_central_manifest.ron @@ -103,4 +103,56 @@ central: ("npc.cockatrice.male.tail_rear"), ) ), + (Roc, Male): ( + head: ( + offset: (-4.5, -4.0, -6.0), + central: ("npc.roc.male.head"), + ), + beak: ( + offset: (-3.5, 0.0, -8.0), + central: ("npc.roc.male.beak"), + ), + neck: ( + offset: (-5.5, 0.0, -10.5), + central: ("npc.roc.male.neck"), + ), + chest: ( + offset: (-8.5, -12.5, -13.5), + central: ("npc.roc.male.chest"), + ), + tail_front: ( + offset: (-4.5, -9.0, -8.0), + central: ("npc.roc.male.tail_front"), + ), + tail_rear: ( + offset: (-9.5, -28.0, -6.0), + central: ("npc.roc.male.tail_rear"), + ) + ), + (Roc, Female): ( + head: ( + offset: (-4.5, -4.0, -6.0), + central: ("npc.roc.male.head"), + ), + beak: ( + offset: (-3.5, 0.0, -8.0), + central: ("npc.roc.male.beak"), + ), + neck: ( + offset: (-5.5, 0.0, -10.5), + central: ("npc.roc.male.neck"), + ), + chest: ( + offset: (-8.5, -12.5, -13.5), + central: ("npc.roc.male.chest"), + ), + tail_front: ( + offset: (-4.5, -9.0, -8.0), + central: ("npc.roc.male.tail_front"), + ), + tail_rear: ( + offset: (-9.5, -28.0, -6.0), + central: ("npc.roc.male.tail_rear"), + ) + ), }) diff --git a/assets/voxygen/voxel/bird_large_lateral_manifest.ron b/assets/voxygen/voxel/bird_large_lateral_manifest.ron index 3eca741462..fadf7ddb56 100644 --- a/assets/voxygen/voxel/bird_large_lateral_manifest.ron +++ b/assets/voxygen/voxel/bird_large_lateral_manifest.ron @@ -167,4 +167,88 @@ lateral: ("npc.cockatrice.male.foot_r"), ) ), + (Roc, Male): ( + wing_in_l: ( + offset: (-13.0, -14.0, -2.5), + lateral: ("npc.roc.male.wing_in_r"), + ), + wing_in_r: ( + offset: (0.0, -14.0, -2.5), + lateral: ("npc.roc.male.wing_in_r"), + ), + wing_mid_l: ( + offset: (-11.0, -18.0, -2.0), + lateral: ("npc.roc.male.wing_mid_r"), + ), + wing_mid_r: ( + offset: (0.0, -18.0, -2.0), + lateral: ("npc.roc.male.wing_mid_r"), + ), + wing_out_l: ( + offset: (-20.0, -18.0, -2.0), + lateral: ("npc.roc.male.wing_out_r"), + ), + wing_out_r: ( + offset: (0.0, -18.0, -2.0), + lateral: ("npc.roc.male.wing_out_r"), + ), + leg_l: ( + offset: (-4.0, -5.5, -7.5), + lateral: ("npc.roc.male.leg_r"), + ), + leg_r: ( + offset: (-4.0, -5.5, -7.5), + lateral: ("npc.roc.male.leg_r"), + ), + foot_l: ( + offset: (-5.5, -3.0, -12.0), + lateral: ("npc.roc.male.foot_r"), + ), + foot_r: ( + offset: (-5.5, -3.0, -12.0), + lateral: ("npc.roc.male.foot_r"), + ) + ), + (Roc, Female): ( + wing_in_l: ( + offset: (-13.0, -14.0, -2.5), + lateral: ("npc.roc.male.wing_in_r"), + ), + wing_in_r: ( + offset: (0.0, -14.0, -2.5), + lateral: ("npc.roc.male.wing_in_r"), + ), + wing_mid_l: ( + offset: (-11.0, -18.0, -2.0), + lateral: ("npc.roc.male.wing_mid_r"), + ), + wing_mid_r: ( + offset: (0.0, -18.0, -2.0), + lateral: ("npc.roc.male.wing_mid_r"), + ), + wing_out_l: ( + offset: (-20.0, -18.0, -2.0), + lateral: ("npc.roc.male.wing_out_r"), + ), + wing_out_r: ( + offset: (0.0, -18.0, -2.0), + lateral: ("npc.roc.male.wing_out_r"), + ), + leg_l: ( + offset: (-4.0, -5.5, -7.5), + lateral: ("npc.roc.male.leg_r"), + ), + leg_r: ( + offset: (-4.0, -5.5, -7.5), + lateral: ("npc.roc.male.leg_r"), + ), + foot_l: ( + offset: (-5.5, -3.0, -12.0), + lateral: ("npc.roc.male.foot_r"), + ), + foot_r: ( + offset: (-5.5, -3.0, -12.0), + lateral: ("npc.roc.male.foot_r"), + ) + ), }) \ No newline at end of file diff --git a/assets/voxygen/voxel/npc/roc/male/beak.vox b/assets/voxygen/voxel/npc/roc/male/beak.vox new file mode 100644 index 0000000000..eead2a2c19 --- /dev/null +++ b/assets/voxygen/voxel/npc/roc/male/beak.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:908494c22844e83f749eba053878f7b9a2025dac1ef3645bb5ff7c4c8a319a7a +size 1716 diff --git a/assets/voxygen/voxel/npc/roc/male/chest.vox b/assets/voxygen/voxel/npc/roc/male/chest.vox new file mode 100644 index 0000000000..1f836f255d --- /dev/null +++ b/assets/voxygen/voxel/npc/roc/male/chest.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0fc31c5cc5ad16914dec01999994d4f3c38caf3d5fc2ef38a09d22ba8f07ce45 +size 16556 diff --git a/assets/voxygen/voxel/npc/roc/male/foot_r.vox b/assets/voxygen/voxel/npc/roc/male/foot_r.vox new file mode 100644 index 0000000000..12e6eacd68 --- /dev/null +++ b/assets/voxygen/voxel/npc/roc/male/foot_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:41697e4f9cf309df975058049be4d2b72cbce83e0e48a30fae5245cd368966fc +size 2216 diff --git a/assets/voxygen/voxel/npc/roc/male/head.vox b/assets/voxygen/voxel/npc/roc/male/head.vox new file mode 100644 index 0000000000..b4949cf1fb --- /dev/null +++ b/assets/voxygen/voxel/npc/roc/male/head.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f5b391704993b817759d13f50f413ca2718c742a542b110fdac48cd27a86d01 +size 3236 diff --git a/assets/voxygen/voxel/npc/roc/male/leg_r.vox b/assets/voxygen/voxel/npc/roc/male/leg_r.vox new file mode 100644 index 0000000000..ec21c11e00 --- /dev/null +++ b/assets/voxygen/voxel/npc/roc/male/leg_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87045fb82df52741d6b01bdb1712499d58db6ac10a2d1bea5124310219c0e850 +size 3400 diff --git a/assets/voxygen/voxel/npc/roc/male/neck.vox b/assets/voxygen/voxel/npc/roc/male/neck.vox new file mode 100644 index 0000000000..3dce2215a0 --- /dev/null +++ b/assets/voxygen/voxel/npc/roc/male/neck.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d68bc72562b91296c1426ccc4e96df0da1736c257ec5717a1315e9ed3ed9ed38 +size 5768 diff --git a/assets/voxygen/voxel/npc/roc/male/tail_front.vox b/assets/voxygen/voxel/npc/roc/male/tail_front.vox new file mode 100644 index 0000000000..eff23adc77 --- /dev/null +++ b/assets/voxygen/voxel/npc/roc/male/tail_front.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b3ca88120eae851fba31dde22cedce0404d207f539d1d3a1515296bcb1c056e1 +size 2240 diff --git a/assets/voxygen/voxel/npc/roc/male/tail_rear.vox b/assets/voxygen/voxel/npc/roc/male/tail_rear.vox new file mode 100644 index 0000000000..c884b56c4f --- /dev/null +++ b/assets/voxygen/voxel/npc/roc/male/tail_rear.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc3d03630c67f788a46e463d24cdb8734d67157eca5c06ee3a18fb01ad6b5581 +size 3400 diff --git a/assets/voxygen/voxel/npc/roc/male/wing_in_r.vox b/assets/voxygen/voxel/npc/roc/male/wing_in_r.vox new file mode 100644 index 0000000000..a3a212a3e2 --- /dev/null +++ b/assets/voxygen/voxel/npc/roc/male/wing_in_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed3f018074a5c18226bcd857ec549bb1558c2c23b558e7a2b3ca89628ad994b8 +size 3112 diff --git a/assets/voxygen/voxel/npc/roc/male/wing_mid_r.vox b/assets/voxygen/voxel/npc/roc/male/wing_mid_r.vox new file mode 100644 index 0000000000..51239e7c94 --- /dev/null +++ b/assets/voxygen/voxel/npc/roc/male/wing_mid_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afa35e2aaf6c7572db4369aae76892583a0b9d0dac95dc145ec938143261cfba +size 3448 diff --git a/assets/voxygen/voxel/npc/roc/male/wing_out_r.vox b/assets/voxygen/voxel/npc/roc/male/wing_out_r.vox new file mode 100644 index 0000000000..bfd0ff77bb --- /dev/null +++ b/assets/voxygen/voxel/npc/roc/male/wing_out_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0bf07f759bff02d4ce47fff3529fb5abc5806a3fc28763132d266cb17036d5b0 +size 4440 diff --git a/assets/voxygen/voxel/npc/troll/male/foot_l.vox b/assets/voxygen/voxel/npc/troll/male/foot_l.vox deleted file mode 100644 index 4d01fb8f7b..0000000000 --- a/assets/voxygen/voxel/npc/troll/male/foot_l.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7841f6c64137537d9339ce27f57530714f7da32a05570abc5a53df5755c733bc -size 1772 diff --git a/assets/voxygen/voxel/npc/troll/male/foot_r.vox b/assets/voxygen/voxel/npc/troll/male/foot_r.vox deleted file mode 100644 index 614e74f9e0..0000000000 --- a/assets/voxygen/voxel/npc/troll/male/foot_r.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dadb50f16c2ecec316b734490125ceec5600dd3814fba5aa7c69b39f3bc6d163 -size 1772 diff --git a/assets/voxygen/voxel/npc/troll/male/hand_l.vox b/assets/voxygen/voxel/npc/troll/male/hand_l.vox deleted file mode 100644 index 0eac100b7e..0000000000 --- a/assets/voxygen/voxel/npc/troll/male/hand_l.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e6499cdfbca1a5fd80a3160709345f486475e531556bbf1967a7597c4adcf493 -size 2912 diff --git a/assets/voxygen/voxel/npc/troll/male/hand_r.vox b/assets/voxygen/voxel/npc/troll/male/hand_r.vox deleted file mode 100644 index 4802cd12a1..0000000000 --- a/assets/voxygen/voxel/npc/troll/male/hand_r.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:65d2871153549e7de7eb336d0d8b2d240c99d97285b44bc80442a37711f85963 -size 2912 diff --git a/assets/voxygen/voxel/npc/troll/male/head.vox b/assets/voxygen/voxel/npc/troll/male/head.vox deleted file mode 100644 index 6d56c9ee94..0000000000 --- a/assets/voxygen/voxel/npc/troll/male/head.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6090d7c9b1b722fe84eabaaa3fd7b0678dd16b35ac59ffa4f997e8d5fdb52253 -size 4704 diff --git a/assets/voxygen/voxel/npc/troll/male/jaw.vox b/assets/voxygen/voxel/npc/troll/male/jaw.vox deleted file mode 100644 index 23ccf45db1..0000000000 --- a/assets/voxygen/voxel/npc/troll/male/jaw.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3560d24655bb6dfc1e54e8f526814f99a43d626af7b3fc5a4404acd0093048aa -size 1940 diff --git a/assets/voxygen/voxel/npc/troll/male/leg_l.vox b/assets/voxygen/voxel/npc/troll/male/leg_l.vox deleted file mode 100644 index e80f022e90..0000000000 --- a/assets/voxygen/voxel/npc/troll/male/leg_l.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dd23c042d142e17a606119472bc52c2e3f773dd83ef8bee9d368baca65320ab6 -size 1664 diff --git a/assets/voxygen/voxel/npc/troll/male/leg_r.vox b/assets/voxygen/voxel/npc/troll/male/leg_r.vox deleted file mode 100644 index 4db2576313..0000000000 --- a/assets/voxygen/voxel/npc/troll/male/leg_r.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:61f27cd9bdf30ac16748abfa090eacc6113097ca73f7e937f9201c40a6bae57a -size 1664 diff --git a/assets/voxygen/voxel/npc/troll/male/shoulder_l.vox b/assets/voxygen/voxel/npc/troll/male/shoulder_l.vox deleted file mode 100644 index f1c7a99037..0000000000 --- a/assets/voxygen/voxel/npc/troll/male/shoulder_l.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:15606bec0680a834eff98efab9a06331c857a2a3dea9f140af3d0dc0ec169af2 -size 2964 diff --git a/assets/voxygen/voxel/npc/troll/male/shoulder_r.vox b/assets/voxygen/voxel/npc/troll/male/shoulder_r.vox deleted file mode 100644 index 535dc664ce..0000000000 --- a/assets/voxygen/voxel/npc/troll/male/shoulder_r.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c111e35534f571b31d72eee59ed8c512c0f9545a55040981f34b473464c51fff -size 2964 diff --git a/assets/voxygen/voxel/npc/troll/male/torso_lower.vox b/assets/voxygen/voxel/npc/troll/male/torso_lower.vox deleted file mode 100644 index e69fe423eb..0000000000 --- a/assets/voxygen/voxel/npc/troll/male/torso_lower.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:04cb99c4a0fe61494d022df4b7a557d00017e3672e3244fe1123a1d6b3b81ac7 -size 2336 diff --git a/assets/voxygen/voxel/npc/troll/male/torso_upper.vox b/assets/voxygen/voxel/npc/troll/male/torso_upper.vox deleted file mode 100644 index 8c900374a4..0000000000 --- a/assets/voxygen/voxel/npc/troll/male/torso_upper.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4abae28c1df2eaaa2b75fec7b3b754f330f159590a66fd89a69387781de22ab7 -size 10424 diff --git a/assets/voxygen/voxel/npc/troll_cave/male/foot_l.vox b/assets/voxygen/voxel/npc/troll_cave/male/foot_l.vox new file mode 100644 index 0000000000..4c97a42ee0 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_cave/male/foot_l.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1480dfe9aa192f690217f831b441303546520bf27c9eadc44ef29eb0be3eca60 +size 1792 diff --git a/assets/voxygen/voxel/npc/troll_cave/male/foot_r.vox b/assets/voxygen/voxel/npc/troll_cave/male/foot_r.vox new file mode 100644 index 0000000000..243373daaf --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_cave/male/foot_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4beb7a960e88dce016f74c945918135c983980716d30ee60019d683f0b8c1e48 +size 1792 diff --git a/assets/voxygen/voxel/npc/troll_cave/male/hand_l.vox b/assets/voxygen/voxel/npc/troll_cave/male/hand_l.vox new file mode 100644 index 0000000000..18086a74e3 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_cave/male/hand_l.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bda1327dced03be263a98b2ddc8d248b6f1df914a3400a48d1b50bb5945557b5 +size 3892 diff --git a/assets/voxygen/voxel/npc/troll_cave/male/hand_r.vox b/assets/voxygen/voxel/npc/troll_cave/male/hand_r.vox new file mode 100644 index 0000000000..770b893669 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_cave/male/hand_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f2c60a45ffdf3446e5b84f029050a43405b8daffbba6f4cac14d06e089570bf +size 3892 diff --git a/assets/voxygen/voxel/npc/troll_cave/male/head.vox b/assets/voxygen/voxel/npc/troll_cave/male/head.vox new file mode 100644 index 0000000000..6975647fa5 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_cave/male/head.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a7a1c16e75cc3c5422dcbbdabd59516df4a9218559902204226144a38762e2d +size 4860 diff --git a/assets/voxygen/voxel/npc/troll_cave/male/jaw.vox b/assets/voxygen/voxel/npc/troll_cave/male/jaw.vox new file mode 100644 index 0000000000..66b423fb91 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_cave/male/jaw.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c365c9c309e55d58cc289da3d5451a24f6b9d312ecb9912e97187f0601d5ca5 +size 2032 diff --git a/assets/voxygen/voxel/npc/troll_cave/male/leg_l.vox b/assets/voxygen/voxel/npc/troll_cave/male/leg_l.vox new file mode 100644 index 0000000000..c5ef8c1c31 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_cave/male/leg_l.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c8f500708cdba942b42890741d20b275f7b9f5458ae45fac3813882c19b6fa8 +size 1844 diff --git a/assets/voxygen/voxel/npc/troll_cave/male/leg_r.vox b/assets/voxygen/voxel/npc/troll_cave/male/leg_r.vox new file mode 100644 index 0000000000..7ce31c07a9 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_cave/male/leg_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34dfcd5f9ebdfff349942c2533c995e0d07a526374e467acff78dd839a53cf4d +size 1844 diff --git a/assets/voxygen/voxel/npc/troll_cave/male/shoulder_l.vox b/assets/voxygen/voxel/npc/troll_cave/male/shoulder_l.vox new file mode 100644 index 0000000000..46ad49ff2d --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_cave/male/shoulder_l.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d33ab14221792cbb9867b26d80e78db0ed417d704c2bd95b17d14321cbae7d9 +size 3576 diff --git a/assets/voxygen/voxel/npc/troll_cave/male/shoulder_r.vox b/assets/voxygen/voxel/npc/troll_cave/male/shoulder_r.vox new file mode 100644 index 0000000000..7898013ed7 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_cave/male/shoulder_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c98dced3fb3614e412ea30f321936575d9a98bc547e72740766b8e41d0c4e76 +size 3576 diff --git a/assets/voxygen/voxel/npc/troll_cave/male/torso_lower.vox b/assets/voxygen/voxel/npc/troll_cave/male/torso_lower.vox new file mode 100644 index 0000000000..3b2cc83635 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_cave/male/torso_lower.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b2177e310320e46de10ba867446175bc9d8adc34f4516550b644fdb6c78f66ed +size 3016 diff --git a/assets/voxygen/voxel/npc/troll_cave/male/torso_upper.vox b/assets/voxygen/voxel/npc/troll_cave/male/torso_upper.vox new file mode 100644 index 0000000000..2252446a88 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_cave/male/torso_upper.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:787fa629bcd7cdec77b7e4fc4bdcfa0830b9cdf5644eb2e06d565ff4a9ea3beb +size 12836 diff --git a/assets/voxygen/voxel/npc/troll_mountain/male/foot_l.vox b/assets/voxygen/voxel/npc/troll_mountain/male/foot_l.vox new file mode 100644 index 0000000000..3a8d7dbdce --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_mountain/male/foot_l.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10449f2e7f7a32bd1829c32d2efc600b1fd1a5450aefa70be70818c84eba5522 +size 1792 diff --git a/assets/voxygen/voxel/npc/troll_mountain/male/foot_r.vox b/assets/voxygen/voxel/npc/troll_mountain/male/foot_r.vox new file mode 100644 index 0000000000..fb5a17f957 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_mountain/male/foot_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:78d433a27a4a292dd9b67d301e6ce6ea4feb0a41ac4a5f4fdc6c425b4a7543e7 +size 1792 diff --git a/assets/voxygen/voxel/npc/troll_mountain/male/hand_l.vox b/assets/voxygen/voxel/npc/troll_mountain/male/hand_l.vox new file mode 100644 index 0000000000..c000331be5 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_mountain/male/hand_l.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a8fbcde634a5d5c876f649353e456035522144e9fd713dea169d8d20d3b0a9d +size 4380 diff --git a/assets/voxygen/voxel/npc/troll_mountain/male/hand_r.vox b/assets/voxygen/voxel/npc/troll_mountain/male/hand_r.vox new file mode 100644 index 0000000000..563acd4fc5 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_mountain/male/hand_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:59e83cf8d8cb6241a65ecdc14c84057030f44589ca7557f9a28fff8c17531c87 +size 4380 diff --git a/assets/voxygen/voxel/npc/troll_mountain/male/head.vox b/assets/voxygen/voxel/npc/troll_mountain/male/head.vox new file mode 100644 index 0000000000..53ee848827 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_mountain/male/head.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0ee0b6c88e917361d7f035895c85ad2193c3e7596251adb98dc69962dacc4c4 +size 5032 diff --git a/assets/voxygen/voxel/npc/troll_mountain/male/jaw.vox b/assets/voxygen/voxel/npc/troll_mountain/male/jaw.vox new file mode 100644 index 0000000000..6b43d3a792 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_mountain/male/jaw.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b39d0ae768f6213c4c0446274f7085f484b66e9dbb87bd527147448abcc6df35 +size 1716 diff --git a/assets/voxygen/voxel/npc/troll_mountain/male/leg_l.vox b/assets/voxygen/voxel/npc/troll_mountain/male/leg_l.vox new file mode 100644 index 0000000000..5b69dd1ea5 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_mountain/male/leg_l.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8d6dd45bed68be177695948a44fb88f8c87112d1757d10d4cd3b823ba4c2cd2b +size 1844 diff --git a/assets/voxygen/voxel/npc/troll_mountain/male/leg_r.vox b/assets/voxygen/voxel/npc/troll_mountain/male/leg_r.vox new file mode 100644 index 0000000000..fff2e85edd --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_mountain/male/leg_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3462c6eeb62e0166543725bc65a0745314042c62470fe5774f1b38de5b6166a0 +size 1844 diff --git a/assets/voxygen/voxel/npc/troll_mountain/male/shoulder_l.vox b/assets/voxygen/voxel/npc/troll_mountain/male/shoulder_l.vox new file mode 100644 index 0000000000..306a820bd7 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_mountain/male/shoulder_l.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4cbe941566ac9ca3959466198f481a1a4073a36b8329bc4eed5c47eac8213b72 +size 4280 diff --git a/assets/voxygen/voxel/npc/troll_mountain/male/shoulder_r.vox b/assets/voxygen/voxel/npc/troll_mountain/male/shoulder_r.vox new file mode 100644 index 0000000000..10ab7e8e53 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_mountain/male/shoulder_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd60e29f9c631a0beeb69950f705df6a110935c413ae3d6aa5d1a94a6a8b97fb +size 4280 diff --git a/assets/voxygen/voxel/npc/troll_mountain/male/torso_lower.vox b/assets/voxygen/voxel/npc/troll_mountain/male/torso_lower.vox new file mode 100644 index 0000000000..f5cdbce07c --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_mountain/male/torso_lower.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0658b7b334a1b1a358dbdfdb717c821fbd6e8e860951d4f80a7a964992db4144 +size 3352 diff --git a/assets/voxygen/voxel/npc/troll_mountain/male/torso_upper.vox b/assets/voxygen/voxel/npc/troll_mountain/male/torso_upper.vox new file mode 100644 index 0000000000..dfd42a133a --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_mountain/male/torso_upper.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:22e91d9fc7ec260437e2b93758c85cce0c8c4964c6dc449b41dc708b8fac5134 +size 17700 diff --git a/assets/voxygen/voxel/npc/troll_swamp/male/foot_l.vox b/assets/voxygen/voxel/npc/troll_swamp/male/foot_l.vox new file mode 100644 index 0000000000..e653439955 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_swamp/male/foot_l.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7642ee74ae6e7ce95953e5a2d3a8bb943bc5b55f3c0930c995ad2a2655ef5ce9 +size 1792 diff --git a/assets/voxygen/voxel/npc/troll_swamp/male/foot_r.vox b/assets/voxygen/voxel/npc/troll_swamp/male/foot_r.vox new file mode 100644 index 0000000000..71fbf5c5be --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_swamp/male/foot_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:324949b49db1d316abe1dbe73ac4b6df9e6ab1010e59ed516716638dfb4b5ae2 +size 1792 diff --git a/assets/voxygen/voxel/npc/troll_swamp/male/hand_l.vox b/assets/voxygen/voxel/npc/troll_swamp/male/hand_l.vox new file mode 100644 index 0000000000..86817a9b1d --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_swamp/male/hand_l.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6c27c05d8c56968cc23a2bdfb107f7f7860d64d15a5df7ab1d9c40b5abf562b0 +size 3864 diff --git a/assets/voxygen/voxel/npc/troll_swamp/male/hand_r.vox b/assets/voxygen/voxel/npc/troll_swamp/male/hand_r.vox new file mode 100644 index 0000000000..89f24c221d --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_swamp/male/hand_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:257249a24fc89f1005fdaf6c80d9360405178dfff9d3b6c24a597b48d0c14da2 +size 3864 diff --git a/assets/voxygen/voxel/npc/troll_swamp/male/head.vox b/assets/voxygen/voxel/npc/troll_swamp/male/head.vox new file mode 100644 index 0000000000..7aa317ed56 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_swamp/male/head.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:652e49b00fab3d180ef9c1afb60f55fd11e139df4be2a498ff59261ae3a571de +size 5000 diff --git a/assets/voxygen/voxel/npc/troll_swamp/male/jaw.vox b/assets/voxygen/voxel/npc/troll_swamp/male/jaw.vox new file mode 100644 index 0000000000..817683d5f5 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_swamp/male/jaw.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d7cc30f4d2a4a394ed269c27824f7ffea58479bc68ecac24571108324569b088 +size 3240 diff --git a/assets/voxygen/voxel/npc/troll_swamp/male/leg_l.vox b/assets/voxygen/voxel/npc/troll_swamp/male/leg_l.vox new file mode 100644 index 0000000000..b20571cd2d --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_swamp/male/leg_l.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75810c18ae8e9edc2f453cd06e7c53946f70f0f3196f312a29f269d1f7c36653 +size 1844 diff --git a/assets/voxygen/voxel/npc/troll_swamp/male/leg_r.vox b/assets/voxygen/voxel/npc/troll_swamp/male/leg_r.vox new file mode 100644 index 0000000000..06a40b57a4 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_swamp/male/leg_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76a925036b31a3ca58a74ab2340c896c12c36c0e2104ae97df94b99f7bfc6225 +size 1844 diff --git a/assets/voxygen/voxel/npc/troll_swamp/male/shoulder_l.vox b/assets/voxygen/voxel/npc/troll_swamp/male/shoulder_l.vox new file mode 100644 index 0000000000..c18e498017 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_swamp/male/shoulder_l.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9880df256c9aef3efbdfc8398338d342b37a8872414f1d2a440aeed54cce0348 +size 4216 diff --git a/assets/voxygen/voxel/npc/troll_swamp/male/shoulder_r.vox b/assets/voxygen/voxel/npc/troll_swamp/male/shoulder_r.vox new file mode 100644 index 0000000000..51431710c4 --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_swamp/male/shoulder_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6dd821308ff92b0cdb902d3df6d00570bc97164959babf8dfe177e9c75a751b +size 4208 diff --git a/assets/voxygen/voxel/npc/troll_swamp/male/torso_lower.vox b/assets/voxygen/voxel/npc/troll_swamp/male/torso_lower.vox new file mode 100644 index 0000000000..33ef62a61a --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_swamp/male/torso_lower.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b28a8af5f99d52a8676be3810ba27c485c26cc4efefafeb80087ff5d168fffb9 +size 4256 diff --git a/assets/voxygen/voxel/npc/troll_swamp/male/torso_upper.vox b/assets/voxygen/voxel/npc/troll_swamp/male/torso_upper.vox new file mode 100644 index 0000000000..9d36e25b7e --- /dev/null +++ b/assets/voxygen/voxel/npc/troll_swamp/male/torso_upper.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a6a36f03d750445c13299892ca9156f2b6da1e582cbb42f0d18bd64b45d49be +size 16488 diff --git a/assets/voxygen/voxel/object_manifest.ron b/assets/voxygen/voxel/object_manifest.ron index 54f85607bb..8f7cfaace4 100644 --- a/assets/voxygen/voxel/object_manifest.ron +++ b/assets/voxygen/voxel/object_manifest.ron @@ -759,4 +759,14 @@ central: ("armor.empty"), ) ), + Tornado: ( + bone0: ( + offset: (0.0, 0.0, 0.0), + central: ("armor.empty"), + ), + bone1: ( + offset: (0.0, 0.0, 0.0), + central: ("armor.empty"), + ) + ), }) diff --git a/client/src/lib.rs b/client/src/lib.rs index ee76d05767..e4f2dd66fa 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -28,7 +28,7 @@ use common::{ skills::Skill, slot::Slot, ChatMode, ControlAction, ControlEvent, Controller, ControllerInputs, GroupManip, InputKind, - InventoryAction, InventoryEvent, InventoryUpdateEvent, + InventoryAction, InventoryEvent, InventoryUpdateEvent, UtteranceKind, }, event::{EventBus, LocalEvent}, grid::Grid, @@ -1224,6 +1224,10 @@ impl Client { } } + pub fn utter(&mut self, kind: UtteranceKind) { + self.send_msg(ClientGeneral::ControlEvent(ControlEvent::Utterance(kind))); + } + pub fn toggle_sneak(&mut self) { let is_sneaking = self .state diff --git a/common/base/src/userdata_dir.rs b/common/base/src/userdata_dir.rs index a038c348d7..e1fe66c479 100644 --- a/common/base/src/userdata_dir.rs +++ b/common/base/src/userdata_dir.rs @@ -1,4 +1,5 @@ use std::path::PathBuf; +use tracing::warn; const VELOREN_USERDATA_ENV: &str = "VELOREN_USERDATA"; @@ -52,14 +53,20 @@ pub fn userdata_dir(workspace: bool, strategy: Option<&str>, manifest_dir: &str) } let exe_path = std::env::current_exe() .expect("Failed to retrieve executable path!"); - // Ensure this path exists - // Ensure that the binary path is prefixed by this path - if !path.exists() || !exe_path.starts_with(&path) { - panic!("Recompile with VELOREN_USERDATA_STRATEGY set to \"system\" or \"executable\" to run the binary outside of the project folder"); + // If this path exists + // and the binary path is prefixed by this path + // put the userdata folder there + if path.exists() && exe_path.starts_with(&path) { + path.push("userdata"); + path + } else { + // otherwise warn and fallback to the executable strategy + warn!("This binary was moved to outside the project folder where it was compiled and was not compiled with VELOREN_USERDATA_STRATEGY set to \"system\" or \"executable\". Falling back the to the \"executable\" strategy (the userdata folder will be placed in the same folder as the executable)"); + let mut path = exe_path; + path.pop(); + path.push("userdata"); + path } - - path.push("userdata"); - path }) } diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index 5fa8c3c112..f755fe58d5 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -280,7 +280,9 @@ pub enum CharacterAbility { cast_duration: f32, recover_duration: f32, summon_amount: u32, + summon_distance: (f32, f32), summon_info: basic_summon::SummonInfo, + duration: Option, }, SelfBuff { buildup_duration: f32, @@ -1400,6 +1402,7 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState { ori_modifier: *ori_modifier as f32, ability_info, }, + exhausted: false, stage: 1, timer: Duration::default(), stage_section: StageSection::Buildup, @@ -1736,15 +1739,19 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState { cast_duration, recover_duration, summon_amount, + summon_distance, summon_info, + duration, } => CharacterState::BasicSummon(basic_summon::Data { static_data: basic_summon::StaticData { buildup_duration: Duration::from_secs_f32(*buildup_duration), cast_duration: Duration::from_secs_f32(*cast_duration), recover_duration: Duration::from_secs_f32(*recover_duration), summon_amount: *summon_amount, + summon_distance: *summon_distance, summon_info: *summon_info, ability_info, + duration: *duration, }, summon_count: 0, timer: Duration::default(), diff --git a/common/src/comp/agent.rs b/common/src/comp/agent.rs index 8b792f361f..6b8059cedc 100644 --- a/common/src/comp/agent.rs +++ b/common/src/comp/agent.rs @@ -1,5 +1,5 @@ use crate::{ - comp::{humanoid, quadruped_low, quadruped_medium, quadruped_small, ship, Body}, + comp::{humanoid, quadruped_low, quadruped_medium, quadruped_small, ship, Body, UtteranceKind}, path::Chaser, rtsim::RtSimController, trade::{PendingTrade, ReducedInventory, SiteId, SitePrices, TradeId, TradeResult}, @@ -96,7 +96,7 @@ bitflags::bitflags! { /// # Behavior Component /// This component allow an Entity to register one or more behavior tags. -/// These tags act as flags of what an Entity can do, or what it is doing. +/// These tags act as flags of what an Entity can do, or what it is doing. /// Behaviors Tags can be added and removed as the Entity lives, to update its /// state when needed #[derive(Default, Copy, Clone, Debug)] @@ -117,7 +117,7 @@ impl From for Behavior { } impl Behavior { - /// Builder function + /// Builder function /// Set capabilities if Option is Some pub fn maybe_with_capabilities( mut self, @@ -261,6 +261,7 @@ pub enum AgentEvent { )>, ), ServerSound(Sound), + Hurt, } #[derive(Copy, Clone, Debug)] @@ -297,6 +298,7 @@ pub enum SoundKind { Explosion, Beam, Shockwave, + Utterance(UtteranceKind, Body), } #[derive(Clone, Debug)] diff --git a/common/src/comp/body.rs b/common/src/comp/body.rs index 34831fdf9c..ad7a499127 100644 --- a/common/src/comp/body.rs +++ b/common/src/comp/body.rs @@ -413,6 +413,7 @@ impl Body { Body::BirdLarge(body) => match body.species { bird_large::Species::Cockatrice => 4000, bird_large::Species::Phoenix => 6000, + bird_large::Species::Roc => 5000, }, Body::Humanoid(_) => 750, _ => 1000, @@ -472,13 +473,18 @@ impl Body { }, Body::FishMedium(_) => 250, Body::Dragon(_) => 5000, - Body::BirdLarge(_) => 3000, + Body::BirdLarge(bird_large) => match bird_large.species { + bird_large::Species::Roc => 2800, + _ => 3000, + }, Body::FishSmall(_) => 20, Body::BipedLarge(biped_large) => match biped_large.species { biped_large::Species::Ogre => 3200, biped_large::Species::Cyclops => 3200, biped_large::Species::Wendigo => 2800, - biped_large::Species::Troll => 2400, + biped_large::Species::Cavetroll => 2400, + biped_large::Species::Mountaintroll => 2400, + biped_large::Species::Swamptroll => 2400, biped_large::Species::Dullahan => 3000, biped_large::Species::Mindflayer => 12500, biped_large::Species::Tidalwarrior => 16000, @@ -512,6 +518,7 @@ impl Body { Body::Theropod(theropod) => match theropod.species { theropod::Species::Archaeos => 3500, theropod::Species::Odonto => 3000, + theropod::Species::Ntouka => 3000, _ => 1100, }, Body::QuadrupedLow(quadruped_low) => match quadruped_low.species { @@ -522,7 +529,7 @@ impl Body { quadruped_low::Species::Tortoise => 900, quadruped_low::Species::Rocksnapper => 1400, quadruped_low::Species::Pangolin => 400, - quadruped_low::Species::Maneater => 700, + quadruped_low::Species::Maneater => 1300, quadruped_low::Species::Sandshark => 900, quadruped_low::Species::Hakulaq => 500, quadruped_low::Species::Lavadrake => 1600, @@ -589,13 +596,18 @@ impl Body { }, Body::FishMedium(_) => 10, Body::Dragon(_) => 500, - Body::BirdLarge(_) => 120, + Body::BirdLarge(bird_large) => match bird_large.species { + bird_large::Species::Roc => 110, + _ => 120, + }, Body::FishSmall(_) => 10, Body::BipedLarge(biped_large) => match biped_large.species { biped_large::Species::Ogre => 70, biped_large::Species::Cyclops => 80, biped_large::Species::Wendigo => 80, - biped_large::Species::Troll => 60, + biped_large::Species::Cavetroll => 60, + biped_large::Species::Mountaintroll => 60, + biped_large::Species::Swamptroll => 60, biped_large::Species::Dullahan => 120, biped_large::Species::Yeti => 0, biped_large::Species::Harvester => 80, @@ -675,7 +687,11 @@ impl Body { pub fn base_poise(&self) -> u32 { match self { Body::Humanoid(_) => 100, - Body::BipedLarge(_) => 250, + Body::BipedLarge(biped_large) => match biped_large.species { + biped_large::Species::Mindflayer => 320, + biped_large::Species::Minotaur => 280, + _ => 250, + }, Body::Golem(_) => 300, _ => 100, } diff --git a/common/src/comp/body/biped_large.rs b/common/src/comp/body/biped_large.rs index 3891c0a4f8..d152693658 100644 --- a/common/src/comp/body/biped_large.rs +++ b/common/src/comp/body/biped_large.rs @@ -37,19 +37,21 @@ make_case_elim!( Ogre = 0, Cyclops = 1, Wendigo = 2, - Troll = 3, - Dullahan = 4, - Werewolf = 5, - Occultsaurok = 6, - Mightysaurok = 7, - Slysaurok = 8, - Mindflayer = 9, - Minotaur = 10, - Tidalwarrior = 11, - Yeti = 12, - Harvester = 13, - Blueoni = 14, - Redoni = 15, + Cavetroll = 3, + Mountaintroll = 4, + Swamptroll = 5, + Dullahan = 6, + Werewolf = 7, + Occultsaurok = 8, + Mightysaurok = 9, + Slysaurok = 10, + Mindflayer = 11, + Minotaur = 12, + Tidalwarrior = 13, + Yeti = 14, + Harvester = 15, + Blueoni = 16, + Redoni = 17, } ); @@ -61,7 +63,9 @@ pub struct AllSpecies { pub ogre: SpeciesMeta, pub cyclops: SpeciesMeta, pub wendigo: SpeciesMeta, - pub troll: SpeciesMeta, + pub troll_cave: SpeciesMeta, + pub troll_mountain: SpeciesMeta, + pub troll_swamp: SpeciesMeta, pub dullahan: SpeciesMeta, pub werewolf: SpeciesMeta, pub saurok_occult: SpeciesMeta, @@ -85,7 +89,9 @@ impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies Species::Ogre => &self.ogre, Species::Cyclops => &self.cyclops, Species::Wendigo => &self.wendigo, - Species::Troll => &self.troll, + Species::Cavetroll => &self.troll_cave, + Species::Mountaintroll => &self.troll_mountain, + Species::Swamptroll => &self.troll_swamp, Species::Dullahan => &self.dullahan, Species::Werewolf => &self.werewolf, Species::Occultsaurok => &self.saurok_occult, @@ -102,11 +108,13 @@ impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies } } -pub const ALL_SPECIES: [Species; 16] = [ +pub const ALL_SPECIES: [Species; 18] = [ Species::Ogre, Species::Cyclops, Species::Wendigo, - Species::Troll, + Species::Cavetroll, + Species::Mountaintroll, + Species::Swamptroll, Species::Dullahan, Species::Werewolf, Species::Occultsaurok, diff --git a/common/src/comp/body/bird_large.rs b/common/src/comp/body/bird_large.rs index 629317082a..8d282c0480 100644 --- a/common/src/comp/body/bird_large.rs +++ b/common/src/comp/body/bird_large.rs @@ -36,6 +36,7 @@ make_case_elim!( pub enum Species { Phoenix = 0, Cockatrice = 1, + Roc = 2, } ); @@ -46,6 +47,7 @@ make_case_elim!( pub struct AllSpecies { pub phoenix: SpeciesMeta, pub cockatrice: SpeciesMeta, + pub roc: SpeciesMeta, } impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies { @@ -56,11 +58,12 @@ impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies match index { Species::Phoenix => &self.phoenix, Species::Cockatrice => &self.cockatrice, + Species::Roc => &self.roc, } } } -pub const ALL_SPECIES: [Species; 2] = [Species::Phoenix, Species::Cockatrice]; +pub const ALL_SPECIES: [Species; 3] = [Species::Phoenix, Species::Cockatrice, Species::Roc]; impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies { type IntoIter = std::iter::Copied>; diff --git a/common/src/comp/body/object.rs b/common/src/comp/body/object.rs index 95d8978b9d..b452715362 100644 --- a/common/src/comp/body/object.rs +++ b/common/src/comp/body/object.rs @@ -88,6 +88,7 @@ make_case_elim!( BirdMeat = 73, FishMeat = 74, SmallMeat = 75, + Tornado = 76, } ); @@ -98,7 +99,7 @@ impl Body { } } -pub const ALL_OBJECTS: [Body; 76] = [ +pub const ALL_OBJECTS: [Body; 77] = [ Body::Arrow, Body::Bomb, Body::Scarecrow, @@ -175,6 +176,7 @@ pub const ALL_OBJECTS: [Body; 76] = [ Body::BirdMeat, Body::FishMeat, Body::SmallMeat, + Body::Tornado, ]; impl From for super::Body { @@ -260,6 +262,7 @@ impl Body { Body::BirdMeat => "bird_meat", Body::FishMeat => "fish_meat", Body::SmallMeat => "small_meat", + Body::Tornado => "tornado", } } @@ -357,6 +360,7 @@ impl Body { Body::FishMeat => 10.0, Body::BirdMeat => 10.0, Body::SmallMeat => 10.0, + Body::Tornado => 50.0, }; Mass(m) @@ -372,6 +376,7 @@ impl Body { Body::HaniwaSentry => Vec3::new(0.8, 0.8, 1.4), Body::SeaLantern => Vec3::new(0.5, 0.5, 1.0), Body::Snowball => Vec3::broadcast(2.5), + Body::Tornado => Vec3::new(2.0, 2.0, 3.4), _ => Vec3::broadcast(0.5), } } diff --git a/common/src/comp/controller.rs b/common/src/comp/controller.rs index 9e13b4e327..c27a4c1c50 100644 --- a/common/src/comp/controller.rs +++ b/common/src/comp/controller.rs @@ -96,6 +96,15 @@ pub enum GroupManip { AssignLeader(Uid), } +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum UtteranceKind { + Calm, + Angry, + Surprised, + Hurt, + Greeting, +} + #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub enum ControlEvent { //ToggleLantern, @@ -111,6 +120,7 @@ pub enum ControlEvent { GroupManip(GroupManip), RemoveBuff(BuffKind), Respawn, + Utterance(UtteranceKind), } #[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)] diff --git a/common/src/comp/inventory/loadout_builder.rs b/common/src/comp/inventory/loadout_builder.rs index eb8fc67148..d4396b2749 100644 --- a/common/src/comp/inventory/loadout_builder.rs +++ b/common/src/comp/inventory/loadout_builder.rs @@ -197,9 +197,12 @@ fn default_main_tool(body: &Body) -> Item { )), }, Body::QuadrupedLow(quadruped_low) => match quadruped_low.species { - quadruped_low::Species::Maneater | quadruped_low::Species::Asp => Some( - Item::new_from_asset_expect("common.items.npc_weapons.unique.quadlowranged"), - ), + quadruped_low::Species::Maneater => Some(Item::new_from_asset_expect( + "common.items.npc_weapons.unique.maneater", + )), + quadruped_low::Species::Asp => Some(Item::new_from_asset_expect( + "common.items.npc_weapons.unique.asp", + )), quadruped_low::Species::Crocodile | quadruped_low::Species::Alligator | quadruped_low::Species::Salamander => Some(Item::new_from_asset_expect( @@ -253,7 +256,12 @@ fn default_main_tool(body: &Body) -> Item { (biped_large::Species::Ogre, biped_large::BodyType::Female) => Some( Item::new_from_asset_expect("common.items.npc_weapons.staff.ogre_staff"), ), - (biped_large::Species::Troll, _) => Some(Item::new_from_asset_expect( + ( + biped_large::Species::Mountaintroll + | biped_large::Species::Swamptroll + | biped_large::Species::Cavetroll, + _, + ) => Some(Item::new_from_asset_expect( "common.items.npc_weapons.hammer.troll_hammer", )), (biped_large::Species::Wendigo, _) => Some(Item::new_from_asset_expect( @@ -300,6 +308,9 @@ fn default_main_tool(body: &Body) -> Item { object::Body::SeaLantern => Some(Item::new_from_asset_expect( "common.items.npc_weapons.unique.tidal_totem", )), + object::Body::Tornado => Some(Item::new_from_asset_expect( + "common.items.npc_weapons.unique.tornado", + )), _ => None, }, Body::BipedSmall(biped_small) => match (biped_small.species, biped_small.body_type) { @@ -320,6 +331,9 @@ fn default_main_tool(body: &Body) -> Item { (bird_large::Species::Phoenix, _) => Some(Item::new_from_asset_expect( "common.items.npc_weapons.unique.birdlargefire", )), + (bird_large::Species::Roc, _) => Some(Item::new_from_asset_expect( + "common.items.npc_weapons.unique.birdlargebasic", + )), }, _ => None, }; @@ -403,12 +417,52 @@ impl LoadoutBuilder { }) => self.chest(Some(Item::new_from_asset_expect( "common.items.npc_armor.biped_large.harvester", ))), + Body::BipedLarge(biped_large::Body { + species: + biped_large::Species::Ogre + | biped_large::Species::Cyclops + | biped_large::Species::Blueoni + | biped_large::Species::Redoni + | biped_large::Species::Cavetroll + | biped_large::Species::Wendigo, + .. + }) => self.chest(Some(Item::new_from_asset_expect( + "common.items.npc_armor.biped_large.generic", + ))), Body::Golem(golem::Body { species: golem::Species::ClayGolem, .. }) => self.chest(Some(Item::new_from_asset_expect( "common.items.npc_armor.golem.claygolem", ))), + Body::QuadrupedLow(quadruped_low::Body { + species: + quadruped_low::Species::Basilisk + | quadruped_low::Species::Asp + | quadruped_low::Species::Lavadrake + | quadruped_low::Species::Maneater + | quadruped_low::Species::Rocksnapper + | quadruped_low::Species::Sandshark, + .. + }) => self.chest(Some(Item::new_from_asset_expect( + "common.items.npc_armor.quadruped_low.generic", + ))), + Body::QuadrupedLow(quadruped_low::Body { + species: quadruped_low::Species::Tortoise, + .. + }) => self.chest(Some(Item::new_from_asset_expect( + "common.items.npc_armor.quadruped_low.shell", + ))), + Body::Theropod(theropod::Body { + species: + theropod::Species::Archaeos + | theropod::Species::Yale + | theropod::Species::Ntouka + | theropod::Species::Odonto, + .. + }) => self.chest(Some(Item::new_from_asset_expect( + "common.items.npc_armor.theropod.rugged", + ))), _ => self, }; diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs index 8b6b775349..2242ad236e 100644 --- a/common/src/comp/mod.rs +++ b/common/src/comp/mod.rs @@ -68,6 +68,7 @@ pub use self::{ controller::{ Climb, ControlAction, ControlEvent, Controller, ControllerInputs, GroupManip, InputAttr, InputKind, InventoryAction, InventoryEvent, InventoryManip, MountState, Mounting, + UtteranceKind, }, energy::{Energy, EnergyChange, EnergySource}, fluid_dynamics::Fluid, diff --git a/common/src/event.rs b/common/src/event.rs index d21eee05c5..ffa178fdd4 100644 --- a/common/src/event.rs +++ b/common/src/event.rs @@ -117,7 +117,7 @@ pub enum ServerEvent { pos: comp::Pos, stats: comp::Stats, skill_set: comp::SkillSet, - health: comp::Health, + health: Option, poise: comp::Poise, loadout: comp::inventory::loadout::Loadout, body: comp::Body, @@ -127,6 +127,7 @@ pub enum ServerEvent { home_chunk: Option, drop_item: Option, rtsim_entity: Option, + projectile: Option, }, CreateShip { pos: comp::Pos, diff --git a/common/src/outcome.rs b/common/src/outcome.rs index d1ec35e15c..feeb1e8fec 100644 --- a/common/src/outcome.rs +++ b/common/src/outcome.rs @@ -1,5 +1,5 @@ use crate::{comp, uid::Uid}; -use comp::{beam, item::Reagent, poise::PoiseState, skills::SkillGroupKind}; +use comp::{beam, item::Reagent, poise::PoiseState, skills::SkillGroupKind, UtteranceKind}; use hashbrown::HashSet; use serde::{Deserialize, Serialize}; use vek::*; @@ -73,6 +73,11 @@ pub enum Outcome { GroundSlam { pos: Vec3, }, + Utterance { + pos: Vec3, + body: comp::Body, + kind: UtteranceKind, + }, } impl Outcome { @@ -87,7 +92,8 @@ impl Outcome { | Outcome::Damage { pos, .. } | Outcome::Block { pos, .. } | Outcome::PoiseChange { pos, .. } - | Outcome::GroundSlam { pos } => Some(*pos), + | Outcome::GroundSlam { pos } + | Outcome::Utterance { pos, .. } => Some(*pos), Outcome::BreakBlock { pos, .. } => Some(pos.map(|e| e as f32 + 0.5)), Outcome::ExpChange { .. } | Outcome::ComboChange { .. } => None, } diff --git a/common/src/states/basic_summon.rs b/common/src/states/basic_summon.rs index 6a49e33c60..80eab6e301 100644 --- a/common/src/states/basic_summon.rs +++ b/common/src/states/basic_summon.rs @@ -2,7 +2,7 @@ use crate::{ comp::{ self, inventory::loadout_builder::{self, LoadoutBuilder}, - Behavior, BehaviorCapability, CharacterState, StateUpdate, + Behavior, BehaviorCapability, CharacterState, Projectile, StateUpdate, }, event::{LocalEvent, ServerEvent}, outcome::Outcome, @@ -11,9 +11,13 @@ use crate::{ behavior::{CharacterBehavior, JoinData}, utils::*, }, + terrain::Block, + vol::ReadVol, }; +use rand::Rng; use serde::{Deserialize, Serialize}; -use std::time::Duration; +use std::{f32::consts::PI, time::Duration}; +use vek::*; /// Separated out to condense update portions of character state #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -26,10 +30,14 @@ pub struct StaticData { pub recover_duration: Duration, /// How many creatures the state should summon pub summon_amount: u32, + /// Range of the summons relative to the summonner + pub summon_distance: (f32, f32), /// Information about the summoned creature pub summon_info: SummonInfo, /// Miscellaneous information about the ability pub ability_info: AbilityInfo, + /// Duration of the summoned entity + pub duration: Option, } #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -102,15 +110,67 @@ impl CharacterBehavior for Data { }; let stats = comp::Stats::new("Summon".to_string()); + + let health_scaling = self + .static_data + .summon_info + .health_scaling + .map(|health_scaling| comp::Health::new(body, health_scaling)); + + // Ray cast to check where summon should happen + let summon_frac = + self.summon_count as f32 / self.static_data.summon_amount as f32; + + let length = rand::thread_rng().gen_range( + self.static_data.summon_distance.0..=self.static_data.summon_distance.1, + ); + + // Summon in a clockwise fashion + let ray_vector = Vec3::new( + (summon_frac * 2.0 * PI).sin() * length, + (summon_frac * 2.0 * PI).cos() * length, + data.body.eye_height(), + ); + + // Check for collision on the xy plane + let obstacle_xy = data + .terrain + .ray(data.pos.0, data.pos.0 + length * ray_vector) + .until(Block::is_solid) + .cast() + .0; + + let collision_vector = Vec3::new( + data.pos.0.x + (summon_frac * 2.0 * PI).sin() * obstacle_xy, + data.pos.0.y + (summon_frac * 2.0 * PI).cos() * obstacle_xy, + data.pos.0.z + data.body.eye_height(), + ); + + // Check for collision in z up to 50 blocks + let obstacle_z = data + .terrain + .ray(collision_vector, collision_vector - Vec3::unit_z() * 50.0) + .until(Block::is_solid) + .cast() + .0; + + // If a duration is specified, create a projectile componenent for the npc + let projectile = self.static_data.duration.map(|duration| Projectile { + hit_solid: Vec::new(), + hit_entity: Vec::new(), + time_left: duration, + owner: Some(*data.uid), + ignore_group: true, + is_sticky: false, + is_point: false, + }); + // Send server event to create npc update.server_events.push_front(ServerEvent::CreateNpc { - pos: *data.pos, + pos: comp::Pos(collision_vector - Vec3::unit_z() * obstacle_z), stats, skill_set, - health: comp::Health::new( - body, - self.static_data.summon_info.health_scaling, - ), + health: health_scaling, poise: comp::Poise::new(body), loadout, body, @@ -129,6 +189,7 @@ impl CharacterBehavior for Data { home_chunk: None, drop_item: None, rtsim_entity: None, + projectile, }); // Send local event used for frontend shenanigans @@ -186,7 +247,7 @@ impl CharacterBehavior for Data { pub struct SummonInfo { body: comp::Body, scale: Option, - health_scaling: u16, + health_scaling: Option, // TODO: use assets for specifying skills and loadout? loadout_config: Option, skillset_config: Option, diff --git a/common/src/states/behavior.rs b/common/src/states/behavior.rs index a1fea34724..d66c827b9a 100644 --- a/common/src/states/behavior.rs +++ b/common/src/states/behavior.rs @@ -5,6 +5,7 @@ use crate::{ InventoryAction, Mass, Melee, Ori, PhysicsState, Pos, SkillSet, StateUpdate, Stats, Vel, }, resources::DeltaTime, + terrain::TerrainGrid, uid::Uid, }; use specs::{ @@ -96,6 +97,7 @@ pub struct JoinData<'a> { pub msm: &'a MaterialStatManifest, pub combo: &'a Combo, pub alignment: Option<&'a comp::Alignment>, + pub terrain: &'a TerrainGrid, } type RestrictedMut<'a, C> = PairedStorage< @@ -128,6 +130,7 @@ pub struct JoinStruct<'a> { pub skill_set: &'a SkillSet, pub combo: &'a Combo, pub alignment: Option<&'a comp::Alignment>, + pub terrain: &'a TerrainGrid, } impl<'a> JoinData<'a> { @@ -161,6 +164,7 @@ impl<'a> JoinData<'a> { msm, combo: j.combo, alignment: j.alignment, + terrain: j.terrain, } } } diff --git a/common/src/states/charged_melee.rs b/common/src/states/charged_melee.rs index 7ad6b9cb04..27d5c11896 100644 --- a/common/src/states/charged_melee.rs +++ b/common/src/states/charged_melee.rs @@ -62,7 +62,7 @@ pub struct Data { pub stage_section: StageSection, /// Timer for each stage pub timer: Duration, - /// Whether the attack fired already + /// Whether the attack executed already pub exhausted: bool, /// How much the attack charged by pub charge_amount: f32, diff --git a/common/src/states/combo_melee.rs b/common/src/states/combo_melee.rs index a59315043a..fd547dfd6a 100644 --- a/common/src/states/combo_melee.rs +++ b/common/src/states/combo_melee.rs @@ -33,6 +33,8 @@ pub struct Stage { /// Duration of stage spent in swing (controls animation stuff, and can also /// be used to handle movement separately to buildup) pub base_swing_duration: T, + /// At what fraction of the swing duration to apply the melee "hit" + pub hit_timing: f32, /// Initial recover duration of stage (how long until character exits state) pub base_recover_duration: T, /// How much forward movement there is in the swing portion of the stage @@ -53,6 +55,7 @@ impl Stage { range: self.range, angle: self.angle, base_buildup_duration: Duration::from_secs_f32(self.base_buildup_duration), + hit_timing: self.hit_timing, base_swing_duration: Duration::from_secs_f32(self.base_swing_duration), base_recover_duration: Duration::from_secs_f32(self.base_recover_duration), forward_movement: self.forward_movement, @@ -112,6 +115,8 @@ pub struct Data { /// Struct containing data that does not change over the course of the /// character state pub static_data: StaticData, + /// Whether the attack was executed already + pub exhausted: bool, /// Indicates what stage the combo is in pub stage: u32, /// Timer for each stage @@ -155,8 +160,24 @@ impl CharacterBehavior for Data { stage_section: StageSection::Swing, ..*self }); + } + }, + StageSection::Swing => { + if self.timer.as_secs_f32() + > self.static_data.stage_data[stage_index].hit_timing + * self.static_data.stage_data[stage_index] + .base_swing_duration + .as_secs_f32() + && !self.exhausted + { + // Swing + update.character = CharacterState::ComboMelee(Data { + static_data: self.static_data.clone(), + timer: tick_attack_or_default(data, self.timer, None), + exhausted: true, + ..*self + }); - // Hit attempt let damage = self.static_data.stage_data[stage_index].base_damage + (self .static_data @@ -177,6 +198,7 @@ impl CharacterBehavior for Data { CombatEffect::Poise(poise), ) .with_requirement(CombatRequirement::AnyDamage); + let knockback = AttackEffect::new( Some(GroupTarget::OutOfGroup), CombatEffect::Knockback(Knockback { @@ -185,13 +207,17 @@ impl CharacterBehavior for Data { }), ) .with_requirement(CombatRequirement::AnyDamage); + let energy = self.static_data.max_energy_gain.min( self.static_data.initial_energy_gain + data.combo.counter() as f32 * self.static_data.energy_increase, ); + let energy = AttackEffect::new(None, CombatEffect::EnergyReward(energy)) .with_requirement(CombatRequirement::AnyDamage); + let buff = CombatEffect::Buff(CombatBuff::default_physical()); + let damage = AttackDamage::new( Damage { source: DamageSource::Melee, @@ -201,8 +227,10 @@ impl CharacterBehavior for Data { Some(GroupTarget::OutOfGroup), ) .with_effect(buff); + let (crit_chance, crit_mult) = get_crit_data(data, self.static_data.ability_info); + let attack = Attack::default() .with_damage(damage) .with_crit(crit_chance, crit_mult) @@ -228,10 +256,8 @@ impl CharacterBehavior for Data { }) .filter(|(_, tool)| tool == &Some(ToolKind::Pick)), }); - } - }, - StageSection::Swing => { - if self.timer < self.static_data.stage_data[stage_index].base_swing_duration { + } else if self.timer < self.static_data.stage_data[stage_index].base_swing_duration + { handle_orientation(data, &mut update, 0.4 * self.static_data.ori_modifier); // Forward movement diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index 09fb5547ac..28533925ff 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -94,7 +94,7 @@ impl Body { quadruped_low::Species::Alligator => 110.0, quadruped_low::Species::Salamander => 85.0, quadruped_low::Species::Monitor => 160.0, - quadruped_low::Species::Asp => 130.0, + quadruped_low::Species::Asp => 110.0, quadruped_low::Species::Tortoise => 60.0, quadruped_low::Species::Rocksnapper => 70.0, quadruped_low::Species::Pangolin => 120.0, @@ -102,7 +102,7 @@ impl Body { quadruped_low::Species::Sandshark => 160.0, quadruped_low::Species::Hakulaq => 140.0, quadruped_low::Species::Lavadrake => 100.0, - quadruped_low::Species::Basilisk => 120.0, + quadruped_low::Species::Basilisk => 90.0, quadruped_low::Species::Deadwood => 140.0, }, Body::Ship(_) => 0.0, diff --git a/common/systems/src/character_behavior.rs b/common/systems/src/character_behavior.rs index e7db1e0b36..382067f7d7 100644 --- a/common/systems/src/character_behavior.rs +++ b/common/systems/src/character_behavior.rs @@ -1,6 +1,6 @@ use specs::{ - shred::ResourceId, Entities, Join, LazyUpdate, Read, ReadStorage, SystemData, World, Write, - WriteStorage, + shred::ResourceId, Entities, Join, LazyUpdate, Read, ReadExpect, ReadStorage, SystemData, + World, Write, WriteStorage, }; use common::{ @@ -16,6 +16,7 @@ use common::{ self, behavior::{CharacterBehavior, JoinData, JoinStruct}, }, + terrain::TerrainGrid, uid::Uid, }; use common_ecs::{Job, Origin, Phase, System}; @@ -67,6 +68,7 @@ pub struct ReadData<'a> { msm: Read<'a, MaterialStatManifest>, combos: ReadStorage<'a, Combo>, alignments: ReadStorage<'a, comp::Alignment>, + terrain: ReadExpect<'a, TerrainGrid>, } /// ## Character Behavior System @@ -280,6 +282,7 @@ impl<'a> System<'a> for Sys { skill_set: &skill_set, combo: &combo, alignment: read_data.alignments.get(entity), + terrain: &read_data.terrain, }; for action in actions { diff --git a/common/systems/src/controller.rs b/common/systems/src/controller.rs index 42b448ad80..2aea04b55a 100644 --- a/common/systems/src/controller.rs +++ b/common/systems/src/controller.rs @@ -1,5 +1,8 @@ use common::{ - comp::{BuffChange, ControlEvent, Controller}, + comp::{ + agent::{Sound, SoundKind}, + Body, BuffChange, ControlEvent, Controller, Pos, + }, event::{EventBus, ServerEvent}, uid::UidAllocator, }; @@ -7,7 +10,7 @@ use common_ecs::{Job, Origin, Phase, System}; use specs::{ saveload::{Marker, MarkerAllocator}, shred::ResourceId, - Entities, Join, Read, SystemData, World, WriteStorage, + Entities, Join, Read, ReadStorage, SystemData, World, WriteStorage, }; use vek::*; @@ -16,6 +19,8 @@ pub struct ReadData<'a> { entities: Entities<'a>, uid_allocator: Read<'a, UidAllocator>, server_bus: Read<'a, EventBus>, + positions: ReadStorage<'a, Pos>, + bodies: ReadStorage<'a, Body>, } #[derive(Default)] @@ -92,6 +97,20 @@ impl<'a> System<'a> for Sys { server_emitter.emit(ServerEvent::GroupManip(entity, manip)) }, ControlEvent::Respawn => server_emitter.emit(ServerEvent::Respawn(entity)), + ControlEvent::Utterance(kind) => { + if let (Some(pos), Some(body)) = ( + read_data.positions.get(entity), + read_data.bodies.get(entity), + ) { + let sound = Sound::new( + SoundKind::Utterance(kind, *body), + pos.0 + Vec3::unit_z() * body.eye_height(), + 8.0, // TODO: Come up with a better way of determining this + 1.0, + ); + server_emitter.emit(ServerEvent::Sound { sound }); + } + }, } } } diff --git a/server/src/cmd.rs b/server/src/cmd.rs index b8d56c4fbb..fcdd197e1a 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -1014,7 +1014,7 @@ fn handle_spawn( pos, comp::Stats::new(get_npc_name(id, npc::BodyType::from_body(body))), comp::SkillSet::default(), - comp::Health::new(body, 1), + Some(comp::Health::new(body, 1)), comp::Poise::new(body), inventory, body, @@ -1116,7 +1116,7 @@ fn handle_spawn_training_dummy( pos, stats, skill_set, - health, + Some(health), poise, Inventory::new_empty(), body, diff --git a/server/src/events/entity_creation.rs b/server/src/events/entity_creation.rs index c66317cf0e..014ed849a7 100644 --- a/server/src/events/entity_creation.rs +++ b/server/src/events/entity_creation.rs @@ -53,7 +53,7 @@ pub fn handle_create_npc( pos: Pos, stats: Stats, skill_set: SkillSet, - health: Health, + health: Option, poise: Poise, loadout: Loadout, body: Body, @@ -63,6 +63,7 @@ pub fn handle_create_npc( drop_item: Option, home_chunk: Option, rtsim_entity: Option, + projectile: Option, ) { let inventory = Inventory::new_with_loadout(loadout); @@ -96,6 +97,12 @@ pub fn handle_create_npc( entity }; + let entity = if let Some(projectile) = projectile { + entity.with(projectile) + } else { + entity + }; + let new_entity = entity.build(); // Add to group system if a pet diff --git a/server/src/events/entity_manipulation.rs b/server/src/events/entity_manipulation.rs index 15dd48bae3..1dfba60f4e 100644 --- a/server/src/events/entity_manipulation.rs +++ b/server/src/events/entity_manipulation.rs @@ -1,7 +1,7 @@ use crate::{ client::Client, comp::{ - agent::{Sound, SoundKind}, + agent::{Agent, AgentEvent, Sound, SoundKind}, biped_large, bird_large, quadruped_low, quadruped_medium, quadruped_small, skills::SkillGroupKind, theropod, PhysicsState, @@ -60,6 +60,13 @@ pub fn handle_damage(server: &Server, entity: EcsEntity, change: HealthChange) { if let Some(mut health) = ecs.write_storage::().get_mut(entity) { health.change_by(change); } + // This if statement filters out anything under 5 damage, for DOT ticks + // TODO: Find a better way to separate direct damage from DOT here + if change.amount < -50 { + if let Some(agent) = ecs.write_storage::().get_mut(entity) { + agent.inbox.push_front(AgentEvent::Hurt); + } + } } pub fn handle_knockback(server: &Server, entity: EcsEntity, impulse: Vec3) { @@ -423,6 +430,7 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc bird_large::Species::Cockatrice => { "common.loot_tables.creature.bird_large.cockatrice" }, + bird_large::Species::Roc => "common.loot_tables.creature.bird_large.roc", _ => "common.loot_tables.creature.bird_large.phoenix", }, Some(common::comp::Body::FishMedium(_)) => "common.loot_tables.creature.fish", @@ -431,7 +439,11 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc biped_large::Species::Wendigo => { "common.loot_tables.creature.biped_large.wendigo" }, - biped_large::Species::Troll => "common.loot_tables.creature.biped_large.troll", + biped_large::Species::Cavetroll + | biped_large::Species::Mountaintroll + | biped_large::Species::Swamptroll => { + "common.loot_tables.creature.biped_large.troll" + }, biped_large::Species::Occultsaurok | biped_large::Species::Mightysaurok | biped_large::Species::Slysaurok => { diff --git a/server/src/events/interaction.rs b/server/src/events/interaction.rs index 03b5fe992a..acd935f9a6 100644 --- a/server/src/events/interaction.rs +++ b/server/src/events/interaction.rs @@ -6,7 +6,7 @@ use common::{ assets, comp::{ self, - agent::{AgentEvent, Sound, MAX_LISTEN_DIST}, + agent::{AgentEvent, Sound, SoundKind, MAX_LISTEN_DIST}, dialogue::Subject, inventory::slot::EquipSlot, item, @@ -386,6 +386,8 @@ pub fn handle_sound(server: &mut Server, sound: &Sound) { let positions = &ecs.read_storage::(); let agents = &mut ecs.write_storage::(); + // TODO: Reduce the complexity of this problem by using spatial partitioning + // system for (agent, agent_pos) in (agents, positions).join() { // TODO: Use pathfinding for more dropoff around obstacles let agent_dist_sqrd = agent_pos.0.distance_squared(sound.pos); @@ -403,4 +405,16 @@ pub fn handle_sound(server: &mut Server, sound: &Sound) { .push_back(AgentEvent::ServerSound(propagated_sound)); } } + + // Attempt to turn this sound into an outcome to be received by frontends. + if let Some(outcome) = match sound.kind { + SoundKind::Utterance(kind, body) => Some(Outcome::Utterance { + kind, + pos: sound.pos, + body, + }), + _ => None, + } { + ecs.write_resource::>().push(outcome); + } } diff --git a/server/src/events/mod.rs b/server/src/events/mod.rs index 7079b3bda3..7ab52e6b60 100644 --- a/server/src/events/mod.rs +++ b/server/src/events/mod.rs @@ -147,6 +147,7 @@ impl Server { home_chunk, drop_item, rtsim_entity, + projectile, } => handle_create_npc( self, pos, @@ -162,6 +163,7 @@ impl Server { drop_item, home_chunk, rtsim_entity, + projectile, ), ServerEvent::CreateShip { pos, diff --git a/server/src/rtsim/tick.rs b/server/src/rtsim/tick.rs index c729445fa9..cb4457f37f 100644 --- a/server/src/rtsim/tick.rs +++ b/server/src/rtsim/tick.rs @@ -127,7 +127,7 @@ impl<'a> System<'a> for Sys { pos: comp::Pos(spawn_pos), stats: comp::Stats::new(entity.get_name()), skill_set: comp::SkillSet::default(), - health: comp::Health::new(body, 10), + health: Some(comp::Health::new(body, 10)), loadout: match body { comp::Body::Humanoid(_) => entity.get_loadout(), _ => LoadoutBuilder::new().build(), @@ -137,6 +137,11 @@ impl<'a> System<'a> for Sys { agent, alignment: match body { comp::Body::Humanoid(_) => comp::Alignment::Npc, + comp::Body::BirdLarge(bird_large) => match bird_large.species { + comp::bird_large::Species::Roc => comp::Alignment::Enemy, + comp::bird_large::Species::Cockatrice => comp::Alignment::Enemy, + _ => comp::Alignment::Wild, + }, _ => comp::Alignment::Wild, }, scale: match body { @@ -146,6 +151,7 @@ impl<'a> System<'a> for Sys { drop_item: None, home_chunk: None, rtsim_entity, + projectile: None, }, }; server_emitter.emit(event); diff --git a/server/src/state_ext.rs b/server/src/state_ext.rs index a929d8224d..339ec7b921 100644 --- a/server/src/state_ext.rs +++ b/server/src/state_ext.rs @@ -39,7 +39,7 @@ pub trait StateExt { pos: comp::Pos, stats: comp::Stats, skill_set: comp::SkillSet, - health: comp::Health, + health: Option, poise: comp::Poise, inventory: comp::Inventory, body: comp::Body, @@ -175,7 +175,7 @@ impl StateExt for State { pos: comp::Pos, stats: comp::Stats, skill_set: comp::SkillSet, - health: comp::Health, + health: Option, poise: comp::Poise, inventory: comp::Inventory, body: comp::Body, @@ -215,7 +215,7 @@ impl StateExt for State { )) .with(stats) .with(skill_set) - .with(health) + .maybe_with(health) .with(poise) .with(comp::Alignment::Npc) .with(comp::CharacterState::default()) diff --git a/server/src/sys/agent.rs b/server/src/sys/agent.rs index 152e49030b..fb4f013f69 100644 --- a/server/src/sys/agent.rs +++ b/server/src/sys/agent.rs @@ -21,7 +21,7 @@ use common::{ Agent, Alignment, BehaviorCapability, BehaviorState, Body, CharacterAbility, CharacterState, ControlAction, ControlEvent, Controller, Energy, Health, HealthChange, InputKind, Inventory, InventoryAction, LightEmitter, MountState, Ori, PhysicsState, Pos, - Scale, SkillSet, Stats, UnresolvedChatMsg, Vel, + Scale, SkillSet, Stats, UnresolvedChatMsg, UtteranceKind, Vel, }, consts::GRAVITY, effect::{BuffEffect, Effect}, @@ -116,10 +116,12 @@ pub enum Tactic { Mindflayer, BirdLargeBreathe, BirdLargeFire, + BirdLargeBasic, Minotaur, ClayGolem, TidalWarrior, Yeti, + Tornado, } #[derive(SystemData)] @@ -407,6 +409,14 @@ impl<'a> System<'a> for Sys { .uid_allocator .retrieve_entity_internal(by.id()) { + if agent.target.is_none() { + controller.push_event( + ControlEvent::Utterance( + UtteranceKind::Angry, + ), + ); + } + agent.target = Some(Target { target: attacker, hostile: true, @@ -509,6 +519,12 @@ impl<'a> System<'a> for Sys { &mut event_emitter, ); } else { + if agent.target.is_none() { + controller.push_event(ControlEvent::Utterance( + UtteranceKind::Angry, + )); + } + agent.target = Some(Target { target: attacker, hostile: true, @@ -617,11 +633,27 @@ impl<'a> AgentData<'a> { } // Interact if incoming messages if !agent.inbox.is_empty() { - if !matches!(agent.inbox.front(), Some(AgentEvent::ServerSound(_))) { + if matches!( + agent.inbox.front(), + Some(AgentEvent::ServerSound(_)) | Some(AgentEvent::Hurt) + ) { + let sound = agent.inbox.pop_front(); + match sound { + Some(AgentEvent::ServerSound(sound)) => { + agent.sounds_heard.push(sound); + agent.awareness += sound.vol; + }, + Some(AgentEvent::Hurt) => { + // Hurt utterances at random upon receiving damage + if thread_rng().gen::() < 0.4 { + controller.push_event(ControlEvent::Utterance(UtteranceKind::Hurt)); + } + }, + //Note: this should be unreachable + Some(_) | None => return, + } + } else { agent.action_state.timer = 0.1; - } else if let Some(AgentEvent::ServerSound(sound)) = agent.inbox.pop_front() { - agent.sounds_heard.push(sound); - agent.awareness += sound.vol; } } if agent.action_state.timer > 0.0 { @@ -660,6 +692,13 @@ impl<'a> AgentData<'a> { return; } + if let Some(AgentEvent::Hurt) = agent.inbox.pop_front() { + // Hurt utterances at random upon receiving damage + if thread_rng().gen::() < 0.4 { + controller.push_event(ControlEvent::Utterance(UtteranceKind::Hurt)); + } + } + if let Some(Target { target, selected_at, @@ -943,6 +982,10 @@ impl<'a> AgentData<'a> { controller.actions.push(ControlAction::Unwield); } + if thread_rng().gen::() < 0.0015 { + controller.push_event(ControlEvent::Utterance(UtteranceKind::Calm)); + } + // Sit if thread_rng().gen::() < 0.0035 { controller.actions.push(ControlAction::Sit); @@ -988,6 +1031,8 @@ impl<'a> AgentData<'a> { if self.look_toward(controller, read_data, &target) { controller.actions.push(ControlAction::Stand); controller.actions.push(ControlAction::Talk); + controller.push_event(ControlEvent::Utterance(UtteranceKind::Greeting)); + match subject { Subject::Regular => { if let ( @@ -1546,6 +1591,10 @@ impl<'a> AgentData<'a> { .min_by_key(|(_, e_pos, _, _, _, _, _)| (e_pos.0.distance_squared(self.pos.0) * 100.0) as i32) // TODO choose target by more than just distance .map(|(e, _, _, _, _, _, _)| e); + if agent.target.is_none() && target.is_some() { + controller.push_event(ControlEvent::Utterance(UtteranceKind::Angry)); + } + agent.target = target.map(|target| Target { target, hostile: true, @@ -1591,8 +1640,10 @@ impl<'a> AgentData<'a> { circle_time: 1, }, "Quad Med Basic" => Tactic::QuadMedBasic, - "Quad Low Ranged" => Tactic::QuadLowRanged, - "Quad Low Breathe" | "Quad Low Beam" => Tactic::QuadLowBeam, + "Asp" | "Maneater" => Tactic::QuadLowRanged, + "Quad Low Breathe" | "Quad Low Beam" | "Basilisk" => { + Tactic::QuadLowBeam + }, "Quad Low Tail" => Tactic::TailSlap, "Quad Low Quick" => Tactic::QuadLowQuick, "Quad Low Basic" => Tactic::QuadLowBasic, @@ -1605,6 +1656,7 @@ impl<'a> AgentData<'a> { "Haniwa Sentry" => Tactic::RotatingTurret, "Bird Large Breathe" => Tactic::BirdLargeBreathe, "Bird Large Fire" => Tactic::BirdLargeFire, + "Bird Large Basic" => Tactic::BirdLargeBasic, "Mindflayer" => Tactic::Mindflayer, "Minotaur" => Tactic::Minotaur, "Clay Golem" => Tactic::ClayGolem, @@ -1833,6 +1885,7 @@ impl<'a> AgentData<'a> { &tgt_data, &read_data, ), + Tactic::Tornado => self.handle_tornado_attack(controller), Tactic::Mindflayer => self.handle_mindflayer_attack( agent, controller, @@ -1855,6 +1908,13 @@ impl<'a> AgentData<'a> { &tgt_data, &read_data, ), + Tactic::BirdLargeBasic => self.handle_birdlarge_basic_attack( + agent, + controller, + &attack_data, + &tgt_data, + &read_data, + ), Tactic::Minotaur => { self.handle_minotaur_attack(agent, controller, &attack_data, &tgt_data, &read_data) }, @@ -2906,6 +2966,12 @@ impl<'a> AgentData<'a> { } } + fn handle_tornado_attack(&self, controller: &mut Controller) { + controller + .actions + .push(ControlAction::basic_input(InputKind::Primary)); + } + fn handle_mindflayer_attack( &self, agent: &mut Agent, @@ -3261,6 +3327,76 @@ impl<'a> AgentData<'a> { } } + fn handle_birdlarge_basic_attack( + &self, + agent: &mut Agent, + controller: &mut Controller, + attack_data: &AttackData, + tgt_data: &TargetData, + read_data: &ReadData, + ) { + const BIRD_ATTACK_RANGE: f32 = 4.0; + const BIRD_CHARGE_DISTANCE: f32 = 15.0; + let bird_attack_distance = self.body.map_or(0.0, |b| b.radius()) + BIRD_ATTACK_RANGE; + // Increase action timer + agent.action_state.timer += read_data.dt.0; + // If higher than 2 blocks + if !read_data + .terrain + .ray(self.pos.0, self.pos.0 - (Vec3::unit_z() * 2.0)) + .until(Block::is_solid) + .cast() + .1 + .map_or(true, |b| b.is_some()) + { + // Fly to target and land + controller + .actions + .push(ControlAction::basic_input(InputKind::Fly)); + let move_dir = tgt_data.pos.0 - self.pos.0; + controller.inputs.move_dir = + move_dir.xy().try_normalized().unwrap_or_else(Vec2::zero) * 2.0; + controller.inputs.move_z = move_dir.z - 0.5; + } else if agent.action_state.timer > 8.0 { + // If action timer higher than 8, make bird summon tornadoes + controller + .actions + .push(ControlAction::basic_input(InputKind::Secondary)); + if matches!(self.char_state, CharacterState::BasicSummon(c) if matches!(c.stage_section, StageSection::Recover)) + { + // Reset timer + agent.action_state.timer = 0.0; + } + } else if matches!(self.char_state, CharacterState::DashMelee(c) if !matches!(c.stage_section, StageSection::Recover)) + { + // If already in dash, keep dashing if not in recover + controller + .actions + .push(ControlAction::basic_input(InputKind::Ability(0))); + } else if matches!(self.char_state, CharacterState::ComboMelee(c) if matches!(c.stage_section, StageSection::Recover)) + { + // If already in combo keep comboing if not in recover + controller + .actions + .push(ControlAction::basic_input(InputKind::Primary)); + } else if attack_data.dist_sqrd > BIRD_CHARGE_DISTANCE.powi(2) { + // Charges at target if they are far enough away + if attack_data.angle < 60.0 { + controller + .actions + .push(ControlAction::basic_input(InputKind::Ability(0))); + } + } else if attack_data.dist_sqrd < bird_attack_distance.powi(2) { + // Combo melee target + controller + .actions + .push(ControlAction::basic_input(InputKind::Primary)); + agent.action_state.condition = true; + } + // Make bird move towards target + self.path_toward_target(agent, controller, tgt_data, read_data, true, None); + } + fn handle_minotaur_attack( &self, agent: &mut Agent, diff --git a/server/src/sys/terrain.rs b/server/src/sys/terrain.rs index 458c710b28..eb668c7690 100644 --- a/server/src/sys/terrain.rs +++ b/server/src/sys/terrain.rs @@ -239,7 +239,7 @@ impl<'a> System<'a> for Sys { loadout_builder.build() }; - let health = comp::Health::new(body, entity.level.unwrap_or(0)); + let health = Some(comp::Health::new(body, entity.level.unwrap_or(0))); let poise = comp::Poise::new(body); let can_speak = match body { @@ -293,6 +293,7 @@ impl<'a> System<'a> for Sys { home_chunk: Some(comp::HomeChunk(key)), drop_item: entity.loot_drop, rtsim_entity: None, + projectile: None, }) } diff --git a/voxygen/Cargo.toml b/voxygen/Cargo.toml index b4989e90dc..05fc942b8b 100644 --- a/voxygen/Cargo.toml +++ b/voxygen/Cargo.toml @@ -50,7 +50,7 @@ voxygen-egui = {package = "veloren-voxygen-egui", path = "egui", optional = true voxygen-dynlib = {package = "veloren-voxygen-dynlib", path = "dynlib", optional = true} # Graphics -winit = {version = "0.24.0", features = ["serde"]} +winit = {version = "0.25.0", features = ["serde"]} wgpu = { version = "=0.8.0", features = ["trace", "cross"] } wgpu-profiler = { git = "https://github.com/Imberflur/wgpu-profiler", tag = "wgpu-0.8" } bytemuck = { version="1.4", features=["derive"] } @@ -60,11 +60,11 @@ shaderc = "0.6.2" conrod_core = {git = "https://gitlab.com/veloren/conrod.git", branch="copypasta_0.7"} conrod_winit = {git = "https://gitlab.com/veloren/conrod.git", branch="copypasta_0.7"} euc = "0.5.0" -iced = {package = "iced_native", git = "https://github.com/hecrj/iced", rev = "8d882d787e6b7fd7c2435f42f82933e2ed904edf"} -iced_winit = {git = "https://github.com/hecrj/iced", rev = "8d882d787e6b7fd7c2435f42f82933e2ed904edf"} +iced = {package = "iced_native", git = "https://github.com/Imberflur/iced", tag = "winit-0.25"} +iced_winit = {git = "https://github.com/Imberflur/iced", tag = "winit-0.25"} window_clipboard = "0.2" glyph_brush = "0.7.0" -keyboard-keynames = { git = "https://gitlab.com/Frinksy/keyboard-keynames.git", rev = "a97ae509cdb9dc70cf1bf0af762d2d1d3a0d6e0c" } +keyboard-keynames = { git = "https://gitlab.com/Frinksy/keyboard-keynames.git", rev = "9ae8f89014d0b0c5b61d0e821c5aeb6140c5c0dc" } # EGUI egui = {version = "0.12", optional = true } @@ -106,7 +106,7 @@ num = "0.4" ordered-float = { version = "2.0.1", default-features = false } rand = "0.8" rayon = "1.5" -rodio = {version = "0.13", default-features = false, features = ["vorbis"]} +rodio = {version = "0.14", default-features = false, features = ["vorbis"]} ron = {version = "0.6", default-features = false} serde = {version = "1.0", features = [ "rc", "derive" ]} strum = "0.20" diff --git a/voxygen/anim/src/biped_large/mod.rs b/voxygen/anim/src/biped_large/mod.rs index 0db26fca2b..cee364ed3b 100644 --- a/voxygen/anim/src/biped_large/mod.rs +++ b/voxygen/anim/src/biped_large/mod.rs @@ -210,7 +210,9 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Ogre, Female) => (1.0, 7.5), (Cyclops, _) => (9.5, 7.5), (Wendigo, _) => (3.0, 7.5), - (Troll, _) => (6.0, 10.0), + (Cavetroll, _) => (9.0, 7.0), + (Mountaintroll, _) => (13.0, 2.0), + (Swamptroll, _) => (11.0, 2.0), (Dullahan, _) => (3.0, 6.0), (Werewolf, _) => (11.5, 1.0), (Occultsaurok, _) => (6.0, 3.5), @@ -228,7 +230,9 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Ogre, _) => (0.0, 0.0), (Cyclops, _) => (-4.5, -6.0), (Wendigo, _) => (0.0, 0.0), - (Troll, _) => (2.0, -4.0), + (Cavetroll, _) => (0.0, -4.0), + (Mountaintroll, _) => (-1.0, -8.0), + (Swamptroll, _) => (-4.0, -4.5), (Dullahan, _) => (0.0, 0.0), (Werewolf, _) => (5.0, -4.5), (Occultsaurok, _) => (1.0, -2.5), @@ -247,7 +251,9 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Ogre, Female) => (0.0, 28.0), (Cyclops, _) => (-2.0, 31.0), (Wendigo, _) => (-1.0, 29.0), - (Troll, _) => (-1.0, 26.5), + (Cavetroll, _) => (-1.0, 26.5), + (Mountaintroll, _) => (-1.0, 30.5), + (Swamptroll, _) => (-1.0, 28.5), (Dullahan, _) => (0.0, 29.0), (Werewolf, _) => (3.0, 26.0), (Occultsaurok, _) => (3.0, 24.0), @@ -266,7 +272,9 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Ogre, Female) => (0.0, -6.0), (Cyclops, _) => (1.0, -8.5), (Wendigo, _) => (-1.5, -6.0), - (Troll, _) => (1.0, -10.5), + (Cavetroll, _) => (1.0, -9.5), + (Mountaintroll, _) => (1.0, -13.5), + (Swamptroll, _) => (1.5, -11.5), (Dullahan, _) => (0.0, -6.5), (Werewolf, _) => (1.0, -10.0), (Occultsaurok, _) => (0.0, -5.0), @@ -293,7 +301,9 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Ogre, Female) => (8.0, 0.5, 2.0), (Cyclops, _) => (15.0, 3.5, 1.5), (Wendigo, _) => (9.0, 0.5, 2.5), - (Troll, _) => (11.0, 0.5, 4.5), + (Cavetroll, _) => (13.0, 0.0, 0.5), + (Mountaintroll, _) => (14.0, -0.5, -2.0), + (Swamptroll, _) => (14.0, 0.0, 0.0), (Dullahan, _) => (14.0, 0.5, 3.5), (Werewolf, _) => (9.0, 4.0, -3.0), (Occultsaurok, _) => (7.5, 1.0, 1.5), @@ -312,7 +322,9 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Ogre, Female) => (9.0, 0.5, -4.5), (Cyclops, _) => (14.0, 2.0, -5.5), (Wendigo, _) => (12.0, 0.0, -3.5), - (Troll, _) => (11.5, 0.0, -5.5), + (Cavetroll, _) => (13.5, 1.0, -6.0), + (Mountaintroll, _) => (13.5, 0.0, -10.0), + (Swamptroll, _) => (17.0, 1.0, -8.0), (Dullahan, _) => (14.5, 0.0, -2.5), (Werewolf, _) => (10.0, 2.5, -11.0), (Occultsaurok, _) => (8.0, 1.5, -5.5), @@ -331,7 +343,9 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Ogre, Female) => (0.0, 0.0, -2.0), (Cyclops, _) => (4.5, 1.0, -8.5), (Wendigo, _) => (2.0, 2.0, -2.5), - (Troll, _) => (5.0, 0.0, -6.0), + (Cavetroll, _) => (4.5, -1.0, -7.5), + (Mountaintroll, _) => (3.5, 0.0, -7.5), + (Swamptroll, _) => (4.5, -0.5, -7.5), (Dullahan, _) => (0.0, 0.0, -5.0), (Werewolf, _) => (4.5, 1.0, -5.0), (Occultsaurok, _) => (3.0, 0.5, -4.0), @@ -350,7 +364,9 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Ogre, Female) => (4.0, 0.5, -13.5), (Cyclops, _) => (6.0, 3.5, -15.5), (Wendigo, _) => (5.0, 2.5, -17.0), - (Troll, _) => (6.0, 1.5, -13.0), + (Cavetroll, _) => (5.5, 0.0, -14.0), + (Mountaintroll, _) => (4.5, 1.0, -14.0), + (Swamptroll, _) => (5.5, 0.0, -14.0), (Dullahan, _) => (4.0, 2.5, -14.0), (Werewolf, _) => (5.5, 3.0, -6.5), (Occultsaurok, _) => (3.5, 3.5, -10.0), @@ -369,7 +385,9 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Ogre, Female) => 1.12, (Cyclops, _) => 1.28, (Wendigo, _) => 1.1, - (Troll, _) => 1.1, + (Cavetroll, _) => 1.1, + (Mountaintroll, _) => 1.1, + (Swamptroll, _) => 1.1, (Dullahan, _) => 1.12, (Werewolf, _) => 1.0, (Occultsaurok, _) => 1.0, @@ -387,7 +405,9 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Ogre, Male) => 0.9, (Ogre, Female) => 0.9, (Cyclops, _) => 0.8, - (Troll, _) => 0.9, + (Cavetroll, _) => 0.9, + (Mountaintroll, _) => 0.9, + (Swamptroll, _) => 0.9, (Dullahan, _) => 0.8, (Minotaur, _) => 0.8, _ => 1.0, @@ -397,7 +417,9 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Ogre, Female) => (8.0, 0.0), (Cyclops, _) => (12.0, 0.0), (Wendigo, _) => (15.0, 0.0), - (Troll, _) => (12.0, 0.0), + (Cavetroll, _) => (13.0, 1.5), + (Mountaintroll, _) => (13.0, 1.5), + (Swamptroll, _) => (15.0, 0.5), (Dullahan, _) => (15.0, 0.0), (Werewolf, _) => (13.0, 0.0), (Occultsaurok, _) => (10.0, 0.0), @@ -428,29 +450,14 @@ impl<'a> From<&'a Body> for SkeletonAttr { }, hhl: match (body.species, body.body_type) { (Ogre, Male) => (-9.0, -10.0, 23.0, 1.57, -0.57, 0.0), - (Cyclops, _) => (-6.0, -10.0, 17.0, 1.57, -0.57, 0.0), - (Troll, _) => (-6.0, -10.0, 17.0, 1.57, -0.57, 0.0), - (Yeti, _) => (-6.0, -10.0, 17.0, 1.57, -0.57, 0.0), - (Blueoni, _) => (-6.0, -10.0, 17.0, 1.57, -0.57, 0.0), - (Redoni, _) => (-6.0, -10.0, 17.0, 1.57, -0.57, 0.0), _ => (-6.0, -10.0, 17.0, 1.57, -0.57, 0.0), }, hhr: match (body.species, body.body_type) { (Ogre, Male) => (-5.0, -13.0, 0.0, 1.57, -0.57, 0.0), - (Cyclops, _) => (-6.0, -10.0, 0.0, 1.57, -0.57, 0.0), - (Troll, _) => (-6.0, -10.0, 0.0, 1.57, -0.57, 0.0), - (Yeti, _) => (-6.0, -10.0, 0.0, 1.57, -0.57, 0.0), - (Blueoni, _) => (-6.0, -10.0, 0.0, 1.57, -0.57, 0.0), - (Redoni, _) => (-6.0, -10.0, 0.0, 1.57, -0.57, 0.0), _ => (-6.0, -10.0, 0.0, 1.57, -0.57, 0.0), }, hc: match (body.species, body.body_type) { (Ogre, Male) => (11.5, 9.0, -13.0, -0.57, -1.57, 1.0), - (Cyclops, _) => (8.5, 6.0, -12.0, -0.57, -1.57, 1.0), - (Troll, _) => (8.5, 6.0, -12.0, -0.57, -1.57, 1.0), - (Yeti, _) => (8.5, 6.0, -12.0, -0.57, -1.57, 1.0), - (Blueoni, _) => (8.5, 6.0, -12.0, -0.57, -1.57, 1.0), - (Redoni, _) => (8.5, 6.0, -12.0, -0.57, -1.57, 1.0), _ => (8.5, 6.0, -12.0, -0.57, -1.57, 1.0), }, sthl: match (body.species, body.body_type) { diff --git a/voxygen/anim/src/bird_large/dash.rs b/voxygen/anim/src/bird_large/dash.rs new file mode 100644 index 0000000000..65717f32fd --- /dev/null +++ b/voxygen/anim/src/bird_large/dash.rs @@ -0,0 +1,177 @@ +use super::{ + super::{vek::*, Animation}, + BirdLargeSkeleton, SkeletonAttr, +}; +use common::states::utils::StageSection; +use std::f32::consts::PI; + +pub struct DashAnimation; +type DashAnimationDependency<'a> = ( + Vec3, + Vec3, + Vec3, + f32, + Option, + f32, + f32, +); + +impl Animation for DashAnimation { + type Dependency<'a> = DashAnimationDependency<'a>; + type Skeleton = BirdLargeSkeleton; + + #[cfg(feature = "use-dyn-lib")] + const UPDATE_FN: &'static [u8] = b"bird_large_dash\0"; + + #[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_dash")] + fn update_skeleton_inner<'a>( + skeleton: &Self::Skeleton, + (velocity, orientation, last_ori, acc_vel, stage_section, global_time, timer): Self::Dependency<'a>, + anim_time: f32, + rate: &mut f32, + s_a: &SkeletonAttr, + ) -> Self::Skeleton { + let mut next = (*skeleton).clone(); + let speed = (Vec2::::from(velocity).magnitude()).min(22.0); + *rate = 1.0; + + let (movement1base, chargemovementbase, movement2base, movement3, legtell) = + match stage_section { + Some(StageSection::Buildup) => (anim_time.sqrt(), 0.0, 0.0, 0.0, anim_time), + Some(StageSection::Charge) => (1.0, 1.0, 0.0, 0.0, 0.0), + Some(StageSection::Swing) => (1.0, 0.0, anim_time.powi(4), 0.0, 1.0), + Some(StageSection::Recover) => (1.0, 0.0, 1.0, anim_time, 1.0), + _ => (0.0, 0.0, 0.0, 0.0, 0.0), + }; + let pullback = 1.0 - movement3; + let subtract = global_time - timer; + let check = subtract - subtract.trunc(); + let mirror = (check - 0.5).signum(); + let movement1abs = movement1base * pullback; + let movement2abs = movement2base * pullback; + let legtwitch = (legtell * 6.0).sin() * pullback; + let legswing = legtell * pullback; + let chargeanim = (chargemovementbase * anim_time * 15.0).sin(); + + //let speednorm = speed / 13.0; + let speednorm = (speed / 13.0).powf(0.25); + + let speedmult = 0.8; + let lab: f32 = 0.6; //6 + + // acc_vel and anim_time mix to make sure phase lenght isn't starting at + // +infinite + let mixed_vel = acc_vel + anim_time * 5.0; //sets run frequency using speed, with anim_time setting a floor + + let short = ((1.0 + / (0.72 + + 0.28 * ((mixed_vel * 1.0 * lab * speedmult + PI * -0.15 - 0.5).sin()).powi(2))) + .sqrt()) + * ((mixed_vel * 1.0 * lab * speedmult + PI * -0.15 - 0.5).sin()) + * speednorm; + + // + let shortalt = (mixed_vel * 1.0 * lab * speedmult + PI * 3.0 / 8.0 - 0.5).sin() * speednorm; + + let ori: Vec2 = Vec2::from(orientation); + let last_ori = Vec2::from(last_ori); + let tilt = if ::vek::Vec2::new(ori, last_ori) + .map(|o| o.magnitude_squared()) + .map(|m| m > 0.001 && m.is_finite()) + .reduce_and() + && ori.angle_between(last_ori).is_finite() + { + ori.angle_between(last_ori).min(0.2) + * last_ori.determine_side(Vec2::zero(), ori).signum() + } else { + 0.0 + } * 1.3; + + next.head.scale = Vec3::one() * 0.98; + next.neck.scale = Vec3::one() * 1.02; + next.leg_l.scale = Vec3::one() / 8.0 * 0.98; + next.leg_r.scale = Vec3::one() / 8.0 * 0.98; + next.foot_l.scale = Vec3::one() * 1.02; + next.foot_r.scale = Vec3::one() * 1.02; + next.chest.scale = Vec3::one() * s_a.scaler / 8.0; + + next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); + next.head.orientation = Quaternion::rotation_x( + -0.1 * speednorm + short * -0.05 + movement1abs * -0.8 + movement2abs * 0.2, + ) * Quaternion::rotation_y(tilt * 0.2) + * Quaternion::rotation_z(shortalt * -0.05 - tilt * 1.5); + + next.beak.position = Vec3::new(0.0, s_a.beak.0, s_a.beak.1); + next.beak.orientation = + Quaternion::rotation_x(short * -0.02 - 0.02 + movement1abs * -0.4 + movement2abs * 0.4); + + next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1); + next.neck.orientation = Quaternion::rotation_x(-0.1 * speednorm + short * -0.04) + * Quaternion::rotation_y(tilt * 0.1) + * Quaternion::rotation_z(shortalt * -0.1 - tilt * 0.5); + + next.chest.position = Vec3::new( + 0.0, + s_a.chest.0, + s_a.chest.1 + short * 0.5 + 0.5 * speednorm, + ) * s_a.scaler + / 8.0; + next.chest.orientation = + Quaternion::rotation_x(short * 0.07 + movement1abs * 0.8 + movement2abs * -1.2) + * Quaternion::rotation_y(tilt * 0.8) + * Quaternion::rotation_z(shortalt * 0.10); + + next.tail_front.position = Vec3::new(0.0, s_a.tail_front.0, s_a.tail_front.1); + next.tail_front.orientation = + Quaternion::rotation_x(0.6 + short * -0.02 + movement1abs * -0.8 + movement2abs * 0.8); + + next.tail_rear.position = Vec3::new(0.0, s_a.tail_rear.0, s_a.tail_rear.1); + next.tail_rear.orientation = Quaternion::rotation_x(-0.2 + short * -0.1); + + next.wing_in_l.position = Vec3::new(-s_a.wing_in.0, s_a.wing_in.1, s_a.wing_in.2); + next.wing_in_r.position = Vec3::new(s_a.wing_in.0, s_a.wing_in.1, s_a.wing_in.2); + + next.wing_in_l.orientation = + Quaternion::rotation_y( + -0.8 + movement1abs * 1.0 + chargeanim * 0.2 - movement2abs * 0.6, + ) * Quaternion::rotation_z(0.2 - movement1abs * 0.6 - movement2abs * 0.6); + next.wing_in_r.orientation = + Quaternion::rotation_y( + 0.8 - movement1abs * 1.0 - chargeanim * 0.2 + movement2abs * 0.6, + ) * Quaternion::rotation_z(-0.2 + movement1abs * 0.6 + movement2abs * 0.6); + + next.wing_mid_l.position = Vec3::new(-s_a.wing_mid.0, s_a.wing_mid.1, s_a.wing_mid.2); + next.wing_mid_r.position = Vec3::new(s_a.wing_mid.0, s_a.wing_mid.1, s_a.wing_mid.2); + next.wing_mid_l.orientation = Quaternion::rotation_y(-0.1) * Quaternion::rotation_z(0.7); + next.wing_mid_r.orientation = Quaternion::rotation_y(0.1) * Quaternion::rotation_z(-0.7); + + next.wing_out_l.position = Vec3::new(-s_a.wing_out.0, s_a.wing_out.1, s_a.wing_out.2); + next.wing_out_r.position = Vec3::new(s_a.wing_out.0, s_a.wing_out.1, s_a.wing_out.2); + next.wing_out_l.orientation = + Quaternion::rotation_y(-0.2 + short * 0.05) * Quaternion::rotation_z(0.2); + next.wing_out_r.orientation = + Quaternion::rotation_y(0.2 + short * -0.05) * Quaternion::rotation_z(-0.2); + + if legtell > 0.0 { + if mirror.is_sign_positive() { + next.leg_l.orientation = Quaternion::rotation_x(legswing * 1.1); + + next.foot_l.orientation = Quaternion::rotation_x(legswing * -1.1 + legtwitch * 0.5); + + next.leg_r.orientation = Quaternion::rotation_x(0.0); + + next.foot_r.orientation = Quaternion::rotation_x(0.0); + } else { + next.leg_l.orientation = Quaternion::rotation_x(0.0); + + next.foot_l.orientation = Quaternion::rotation_x(0.0); + + next.leg_r.orientation = Quaternion::rotation_x(legswing * 1.1); + + next.foot_r.orientation = Quaternion::rotation_x(legswing * -1.1 + legtwitch * 0.5); + } + } + + next + } +} diff --git a/voxygen/anim/src/bird_large/mod.rs b/voxygen/anim/src/bird_large/mod.rs index 55ac715d38..58a3ae27a1 100644 --- a/voxygen/anim/src/bird_large/mod.rs +++ b/voxygen/anim/src/bird_large/mod.rs @@ -1,5 +1,6 @@ pub mod alpha; pub mod breathe; +pub mod dash; pub mod feed; pub mod fly; pub mod idle; @@ -7,13 +8,14 @@ pub mod run; pub mod shockwave; pub mod shoot; pub mod stunned; +pub mod summon; pub mod swim; // Reexports pub use self::{ - alpha::AlphaAnimation, breathe::BreatheAnimation, feed::FeedAnimation, fly::FlyAnimation, - idle::IdleAnimation, run::RunAnimation, shockwave::ShockwaveAnimation, shoot::ShootAnimation, - stunned::StunnedAnimation, swim::SwimAnimation, + alpha::AlphaAnimation, breathe::BreatheAnimation, dash::DashAnimation, feed::FeedAnimation, + fly::FlyAnimation, idle::IdleAnimation, run::RunAnimation, shockwave::ShockwaveAnimation, + shoot::ShootAnimation, stunned::StunnedAnimation, summon::SummonAnimation, swim::SwimAnimation, }; use super::{make_bone, vek::*, FigureBoneData, Skeleton}; @@ -149,54 +151,67 @@ impl<'a> From<&'a Body> for SkeletonAttr { chest: match (body.species, body.body_type) { (Phoenix, _) => (2.5, 16.0), (Cockatrice, _) => (2.5, 16.0), + (Roc, _) => (2.5, 27.5), }, neck: match (body.species, body.body_type) { (Phoenix, _) => (2.5, -5.5), (Cockatrice, _) => (5.0, -1.5), + (Roc, _) => (9.5, -1.5), }, head: match (body.species, body.body_type) { (Phoenix, _) => (6.0, 12.0), (Cockatrice, _) => (8.0, 4.5), + (Roc, _) => (17.0, -3.5), }, beak: match (body.species, body.body_type) { (Phoenix, _) => (5.0, 3.0), (Cockatrice, _) => (2.0, -3.0), + (Roc, _) => (0.0, -3.0), }, tail_front: match (body.species, body.body_type) { (Phoenix, _) => (-9.5, -1.0), (Cockatrice, _) => (-5.0, -2.5), + (Roc, _) => (-7.5, -3.5), }, tail_rear: match (body.species, body.body_type) { (Phoenix, _) => (-11.0, 0.0), (Cockatrice, _) => (-8.0, -3.0), + (Roc, _) => (-8.0, -3.0), }, wing_in: match (body.species, body.body_type) { (Phoenix, _) => (3.0, 2.5, 2.0), (Cockatrice, _) => (3.5, 7.0, 3.5), + (Roc, _) => (5.5, 7.5, -1.0), }, wing_mid: match (body.species, body.body_type) { (Phoenix, _) => (10.0, 1.0, 0.0), (Cockatrice, _) => (6.0, 0.0, 0.0), + (Roc, _) => (12.0, 1.0, -0.5), }, wing_out: match (body.species, body.body_type) { (Phoenix, _) => (7.0, 2.0, 1.5), (Cockatrice, _) => (4.0, -1.0, 1.0), + (Roc, _) => (10.0, -2.0, 0.0), }, leg: match (body.species, body.body_type) { (Phoenix, _) => (4.0, 1.5, 12.0), (Cockatrice, _) => (3.5, 2.5, 13.0), + (Roc, _) => (5.5, -1.5, 17.5), }, foot: match (body.species, body.body_type) { (Phoenix, _) => (0.5, -0.5, -2.5), (Cockatrice, _) => (0.5, -3.0, -3.0), + (Roc, _) => (2.5, -2.5, -5.5), }, scaler: match (body.species, body.body_type) { (Phoenix, _) => (1.0), (Cockatrice, _) => (1.0), + (Roc, _) => (1.0), }, feed: match (body.species, body.body_type) { (Phoenix, _) => (-0.65), (Cockatrice, _) => (-0.5), + (Roc, _) => (-0.4), }, } } diff --git a/voxygen/anim/src/bird_large/summon.rs b/voxygen/anim/src/bird_large/summon.rs new file mode 100644 index 0000000000..5176540e77 --- /dev/null +++ b/voxygen/anim/src/bird_large/summon.rs @@ -0,0 +1,114 @@ +use super::{ + super::{vek::*, Animation}, + BirdLargeSkeleton, SkeletonAttr, +}; +use common::{states::utils::StageSection, util::Dir}; + +pub struct SummonAnimation; + +type SummonAnimationDependency = (f32, Option, f32, Dir, bool); + +impl Animation for SummonAnimation { + type Dependency<'a> = SummonAnimationDependency; + type Skeleton = BirdLargeSkeleton; + + #[cfg(feature = "use-dyn-lib")] + const UPDATE_FN: &'static [u8] = b"bird_large_summon\0"; + + #[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_summon")] + #[allow(clippy::approx_constant)] // TODO: Pending review in #587 + fn update_skeleton_inner<'a>( + skeleton: &Self::Skeleton, + (global_time, stage_section, timer, look_dir, on_ground): Self::Dependency<'a>, + anim_time: f32, + rate: &mut f32, + s_a: &SkeletonAttr, + ) -> Self::Skeleton { + *rate = 1.0; + let mut next = (*skeleton).clone(); + + let (movement1base, movement2base, movement3, twitch) = match stage_section { + Some(StageSection::Buildup) => (anim_time.powf(0.25), 0.0, 0.0, 0.0), + Some(StageSection::Cast) => (1.0, anim_time.min(1.0).powf(0.1), 0.0, anim_time), + Some(StageSection::Recover) => (1.0, 1.0, anim_time.min(1.0).powi(2), 1.0), + _ => (0.0, 0.0, 0.0, 0.0), + }; + + let pullback = 1.0 - movement3; + let subtract = global_time - timer; + let check = subtract - subtract.trunc(); + let mirror = (check - 0.5).signum(); + let twitch2 = mirror * (twitch * 20.0).sin() * pullback; + + let movement1abs = movement1base * pullback; + let movement2abs = movement2base * pullback; + + let wave_slow_cos = (anim_time * 4.5).cos(); + + next.head.scale = Vec3::one() * 0.98; + next.neck.scale = Vec3::one() * 1.02; + next.leg_l.scale = Vec3::one() / 8.0 * 0.98; + next.leg_r.scale = Vec3::one() / 8.0 * 0.98; + next.foot_l.scale = Vec3::one() * 1.02; + next.foot_r.scale = Vec3::one() * 1.02; + next.chest.scale = Vec3::one() * s_a.scaler / 8.0; + + next.chest.position = Vec3::new( + 0.0, + s_a.chest.0, + s_a.chest.1 + wave_slow_cos * 0.06 + twitch2 * 0.1, + ) * s_a.scaler + / 8.0; + + next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); + next.head.orientation = + Quaternion::rotation_x(movement1abs * -1.0 - movement2abs * 0.1 + look_dir.z * 0.4); + + next.beak.position = Vec3::new(0.0, s_a.beak.0, s_a.beak.1); + next.beak.orientation = Quaternion::rotation_x(movement1abs * -0.7 + twitch2 * 0.1); + + if on_ground { + next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1); + next.neck.orientation = Quaternion::rotation_x(movement1abs * 0.5 - movement2abs * 0.5); + + next.chest.orientation = + Quaternion::rotation_x(movement1abs * 1.1 - movement2abs * 0.1); + + next.wing_in_l.position = Vec3::new(-s_a.wing_in.0, s_a.wing_in.1, s_a.wing_in.2); + next.wing_in_r.position = Vec3::new(s_a.wing_in.0, s_a.wing_in.1, s_a.wing_in.2); + + next.wing_in_l.orientation = + Quaternion::rotation_x(movement1abs * 0.4 - movement2abs * 0.4) + * Quaternion::rotation_y(-1.0 + movement1abs * 1.6 - movement2abs * 1.8) + * Quaternion::rotation_z(0.2 - movement1abs * 1.8 + movement2abs * 0.4); + next.wing_in_r.orientation = + Quaternion::rotation_x(movement1abs * 0.4 - movement2abs * 0.4) + * Quaternion::rotation_y(1.0 - movement1abs * 1.6 + movement2abs * 1.8) + * Quaternion::rotation_z(-0.2 + movement1abs * 1.8 - movement2abs * 0.4); + + next.wing_mid_l.position = Vec3::new(-s_a.wing_mid.0, s_a.wing_mid.1, s_a.wing_mid.2); + next.wing_mid_r.position = Vec3::new(s_a.wing_mid.0, s_a.wing_mid.1, s_a.wing_mid.2); + next.wing_mid_l.orientation = + Quaternion::rotation_y(-0.1 - movement2abs * 0.4) * Quaternion::rotation_z(0.7); + next.wing_mid_r.orientation = + Quaternion::rotation_y(0.1 + movement2abs * 0.4) * Quaternion::rotation_z(-0.7); + + next.wing_out_l.position = Vec3::new(-s_a.wing_out.0, s_a.wing_out.1, s_a.wing_out.2); + next.wing_out_r.position = Vec3::new(s_a.wing_out.0, s_a.wing_out.1, s_a.wing_out.2); + next.wing_out_l.orientation = + Quaternion::rotation_y(-0.2 - movement2abs * 0.4) * Quaternion::rotation_z(0.2); + next.wing_out_r.orientation = + Quaternion::rotation_y(0.2 + movement2abs * 0.4) * Quaternion::rotation_z(-0.2); + + next.tail_front.position = Vec3::new(0.0, s_a.tail_front.0, s_a.tail_front.1); + next.tail_front.orientation = + Quaternion::rotation_x(-movement1abs * 0.1 + movement2abs * 0.1 + twitch2 * 0.02); + next.tail_rear.position = Vec3::new(0.0, s_a.tail_rear.0, s_a.tail_rear.1); + next.tail_rear.orientation = + Quaternion::rotation_x(-movement1abs * 0.1 + movement2abs * 0.1 + twitch2 * 0.02); + } else { + } + + next + } +} diff --git a/voxygen/i18n/src/analysis.rs b/voxygen/i18n/src/analysis.rs index 13344b9c30..50887955fd 100644 --- a/voxygen/i18n/src/analysis.rs +++ b/voxygen/i18n/src/analysis.rs @@ -231,17 +231,14 @@ fn complete_key_versions<'a>( let full_path = i18n_file.path(); let path = full_path.strip_prefix(root_dir).unwrap(); let i18n_blob = read_file_from_path(&repo, &head_ref, &path); - let i18n: LocalizationFragment = match from_bytes(i18n_blob.content()) { - Ok(v) => v, - Err(e) => { - eprintln!( + let i18n: LocalizationFragment = + from_bytes(i18n_blob.content()).unwrap_or_else(|e| { + panic!( "Could not parse {} RON file, skipping: {}", i18n_file.path().to_string_lossy(), e - ); - continue; - }, - }; + ) + }); i18n_key_versions.extend(generate_key_version(&repo, &i18n, &path, &i18n_blob)); } } @@ -304,17 +301,13 @@ fn test_localization_directory( // Find the localization entry state let current_blob = read_file_from_path(&repo, &head_ref, &relfile); - let current_loc: RawLocalization = match from_bytes(current_blob.content()) { - Ok(v) => v, - Err(e) => { - eprintln!( - "Could not parse {} RON file, skipping: {}", - relfile.to_string_lossy(), - e - ); - return None; - }, - }; + let current_loc: RawLocalization = from_bytes(current_blob.content()).unwrap_or_else(|e| { + panic!( + "Could not parse {} RON file, skipping: {}", + relfile.to_string_lossy(), + e + ) + }); // Gather state of current localization let mut current_i18n = gather_state( diff --git a/voxygen/src/audio/mod.rs b/voxygen/src/audio/mod.rs index d6811f77ab..e6f50f9e9f 100644 --- a/voxygen/src/audio/mod.rs +++ b/voxygen/src/audio/mod.rs @@ -209,7 +209,7 @@ impl AudioFrontend { // TODO: Should this take `underwater` into consideration? match self.play_sfx(sfx_file, self.listener.pos, None, false) { Ok(_) => {}, - Err(e) => warn!("Failed to play sfx. {}", e), + Err(e) => warn!("Failed to play sfx '{:?}'. {}", sfx_file, e), } } else { debug!("Missing sfx trigger config for external sfx event.",); @@ -244,7 +244,7 @@ impl AudioFrontend { match self.play_sfx(sfx_file, position, volume, underwater) { Ok(_) => {}, - Err(e) => warn!("Failed to play sfx. {}", e), + Err(e) => warn!("Failed to play sfx '{:?}'. {}", sfx_file, e), } } else { debug!( @@ -265,8 +265,8 @@ impl AudioFrontend { ) -> Result<(), rodio::decoder::DecoderError> { if self.audio_stream.is_some() { let sound = OggSound::load_expect(sound) - .cloned() - .decoder()? + .read() + .to_source() .amplify(vol.unwrap_or(1.0)); let listener = self.listener.clone(); @@ -291,9 +291,7 @@ impl AudioFrontend { ) { if self.audio_stream.is_some() { if let Some(channel) = self.get_ambient_channel(channel_tag, volume_multiplier) { - if let Ok(sound) = OggSound::load_expect(sound).cloned().decoder() { - channel.play(sound); - } + channel.play(OggSound::load_expect(sound).read().to_source()); } } } @@ -349,9 +347,7 @@ impl AudioFrontend { fn play_music(&mut self, sound: &str, channel_tag: MusicChannelTag) { if self.music_enabled() { if let Some(channel) = self.get_music_channel(channel_tag) { - if let Ok(sound) = OggSound::load_expect(sound).cloned().decoder() { - channel.play(sound, channel_tag); - } + channel.play(OggSound::load_expect(sound).read().to_source(), channel_tag); } } } diff --git a/voxygen/src/audio/music.rs b/voxygen/src/audio/music.rs index 5298e006b8..502bb61ced 100644 --- a/voxygen/src/audio/music.rs +++ b/voxygen/src/audio/music.rs @@ -316,7 +316,7 @@ impl MusicMgr { // Adds a bit of randomness between plays let silence_between_tracks_seconds: f32 = if matches!(music_state, MusicState::Activity(MusicActivity::Explore)) { - rng.gen_range(60.0..120.0) + rng.gen_range(90.0..180.0) } else { 0.0 }; diff --git a/voxygen/src/audio/sfx/event_mapper/combat/tests.rs b/voxygen/src/audio/sfx/event_mapper/combat/tests.rs index a024d559ea..73df919023 100644 --- a/voxygen/src/audio/sfx/event_mapper/combat/tests.rs +++ b/voxygen/src/audio/sfx/event_mapper/combat/tests.rs @@ -128,6 +128,7 @@ fn matches_ability_stage() { angle: 30.0, base_buildup_duration: Duration::from_millis(500), base_swing_duration: Duration::from_millis(200), + hit_timing: 0.5, base_recover_duration: Duration::from_millis(400), forward_movement: 0.5, damage_kind: DamageKind::Slashing, @@ -142,6 +143,7 @@ fn matches_ability_stage() { ori_modifier: 1.0, ability_info: empty_ability_info(), }, + exhausted: false, stage: 1, timer: Duration::default(), stage_section: states::utils::StageSection::Swing, @@ -187,6 +189,7 @@ fn ignores_different_ability_stage() { angle: 30.0, base_buildup_duration: Duration::from_millis(500), base_swing_duration: Duration::from_millis(200), + hit_timing: 0.5, base_recover_duration: Duration::from_millis(400), forward_movement: 0.5, damage_kind: DamageKind::Slashing, @@ -201,6 +204,7 @@ fn ignores_different_ability_stage() { ori_modifier: 1.0, ability_info: empty_ability_info(), }, + exhausted: false, stage: 1, timer: Duration::default(), stage_section: states::utils::StageSection::Swing, diff --git a/voxygen/src/audio/sfx/mod.rs b/voxygen/src/audio/sfx/mod.rs index f0ab9e4a55..65623f5bd2 100644 --- a/voxygen/src/audio/sfx/mod.rs +++ b/voxygen/src/audio/sfx/mod.rs @@ -91,11 +91,12 @@ use client::Client; use common::{ assets::{self, AssetExt, AssetHandle}, comp::{ - beam, + beam, biped_large, biped_small, humanoid, item::{ItemKind, ToolKind}, object, poise::PoiseState, - Body, CharacterAbilityType, InventoryUpdateEvent, + quadruped_low, quadruped_medium, quadruped_small, Body, CharacterAbilityType, + InventoryUpdateEvent, UtteranceKind, }, outcome::Outcome, terrain::{BlockKind, TerrainChunk}, @@ -105,7 +106,7 @@ use event_mapper::SfxEventMapper; use hashbrown::HashMap; use rand::prelude::*; use serde::Deserialize; -use tracing::warn; +use tracing::{debug, warn}; use vek::*; /// We watch the states of nearby entities in order to emit SFX at their @@ -182,6 +183,86 @@ pub enum SfxEvent { FlameThrower, PoiseChange(PoiseState), GroundSlam, + Utterance(UtteranceKind, VoiceKind), +} + +#[derive(Copy, Clone, Debug, PartialEq, Deserialize, Hash, Eq)] +pub enum VoiceKind { + HumanFemale, + HumanMale, + BipedLarge, + Wendigo, + Reptile, + Bird, + Critter, + Sheep, + Pig, + Cow, + Canine, + Lion, + Mindflayer, + Marlin, + Maneater, + Adlet, + Antelope, + Alligator, + Saurok, +} + +fn body_to_voice(body: &Body) -> Option { + Some(match body { + Body::Humanoid(body) => match &body.body_type { + humanoid::BodyType::Female => VoiceKind::HumanFemale, + humanoid::BodyType::Male => VoiceKind::HumanMale, + }, + Body::QuadrupedLow(body) => match body.species { + quadruped_low::Species::Maneater => VoiceKind::Maneater, + quadruped_low::Species::Alligator => VoiceKind::Alligator, + _ => return None, + }, + Body::QuadrupedSmall(body) => match body.species { + quadruped_small::Species::Sheep => VoiceKind::Sheep, + quadruped_small::Species::Pig | quadruped_small::Species::Boar => VoiceKind::Pig, + _ => VoiceKind::Critter, + }, + Body::QuadrupedMedium(body) => match body.species { + quadruped_medium::Species::Saber + | quadruped_medium::Species::Tiger + | quadruped_medium::Species::Lion + | quadruped_medium::Species::Frostfang + | quadruped_medium::Species::Snowleopard => VoiceKind::Lion, + quadruped_medium::Species::Wolf + | quadruped_medium::Species::Roshwalr + | quadruped_medium::Species::Tarasque + | quadruped_medium::Species::Darkhound + | quadruped_medium::Species::Bonerattler + | quadruped_medium::Species::Grolgar => VoiceKind::Canine, + quadruped_medium::Species::Cattle + | quadruped_medium::Species::Catoblepas + | quadruped_medium::Species::Highland + | quadruped_medium::Species::Yak + | quadruped_medium::Species::Moose + | quadruped_medium::Species::Dreadhorn => VoiceKind::Cow, + quadruped_medium::Species::Antelope => VoiceKind::Antelope, + _ => return None, + }, + Body::BirdMedium(_) | Body::BirdLarge(_) => VoiceKind::Bird, + Body::BipedSmall(body) => match body.species { + biped_small::Species::Adlet => VoiceKind::Adlet, + _ => return None, + }, + Body::BipedLarge(body) => match body.species { + biped_large::Species::Wendigo => VoiceKind::Wendigo, + biped_large::Species::Occultsaurok + | biped_large::Species::Mightysaurok + | biped_large::Species::Slysaurok => VoiceKind::Saurok, + biped_large::Species::Mindflayer => VoiceKind::Mindflayer, + _ => VoiceKind::BipedLarge, + }, + Body::Theropod(_) | Body::Dragon(_) => VoiceKind::Reptile, + Body::FishSmall(_) | Body::FishMedium(_) => VoiceKind::Marlin, + _ => return None, + }) } #[derive(Clone, Debug, PartialEq, Deserialize, Hash, Eq)] @@ -418,15 +499,15 @@ impl SfxMgr { }, Outcome::Damage { pos, .. } => { let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Damage); - audio.emit_sfx(sfx_trigger_item, *pos, None, false); + audio.emit_sfx(sfx_trigger_item, *pos, Some(1.5), false); }, Outcome::Block { pos, parry, .. } => { if *parry { let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Parry); - audio.emit_sfx(sfx_trigger_item, *pos, Some(2.0), false); + audio.emit_sfx(sfx_trigger_item, *pos, Some(1.5), false); } else { let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Block); - audio.emit_sfx(sfx_trigger_item, *pos, Some(2.0), false); + audio.emit_sfx(sfx_trigger_item, *pos, Some(1.5), false); } }, Outcome::PoiseChange { pos, state, .. } => match state { @@ -434,24 +515,38 @@ impl SfxMgr { PoiseState::Interrupted => { let sfx_trigger_item = triggers.get_key_value(&SfxEvent::PoiseChange(PoiseState::Interrupted)); - audio.emit_sfx(sfx_trigger_item, *pos, None, false); + audio.emit_sfx(sfx_trigger_item, *pos, Some(1.5), false); }, PoiseState::Stunned => { let sfx_trigger_item = triggers.get_key_value(&SfxEvent::PoiseChange(PoiseState::Stunned)); - audio.emit_sfx(sfx_trigger_item, *pos, None, false); + audio.emit_sfx(sfx_trigger_item, *pos, Some(1.5), false); }, PoiseState::Dazed => { let sfx_trigger_item = triggers.get_key_value(&SfxEvent::PoiseChange(PoiseState::Dazed)); - audio.emit_sfx(sfx_trigger_item, *pos, None, false); + audio.emit_sfx(sfx_trigger_item, *pos, Some(1.5), false); }, PoiseState::KnockedDown => { let sfx_trigger_item = triggers.get_key_value(&SfxEvent::PoiseChange(PoiseState::KnockedDown)); - audio.emit_sfx(sfx_trigger_item, *pos, None, false); + audio.emit_sfx(sfx_trigger_item, *pos, Some(1.5), false); }, }, + Outcome::Utterance { pos, kind, body } => { + if let Some(voice) = body_to_voice(body) { + let sfx_trigger_item = + triggers.get_key_value(&SfxEvent::Utterance(*kind, voice)); + if let Some(sfx_trigger_item) = sfx_trigger_item { + audio.emit_sfx(Some(sfx_trigger_item), *pos, Some(1.5), false); + } else { + debug!( + "No utterance sound effect exists for ({:?}, {:?})", + kind, voice + ); + } + } + }, Outcome::ExpChange { .. } | Outcome::ComboChange { .. } | Outcome::SummonedCreature { .. } => {}, diff --git a/voxygen/src/audio/soundcache.rs b/voxygen/src/audio/soundcache.rs index 545f6cef42..f08a4bdab6 100644 --- a/voxygen/src/audio/soundcache.rs +++ b/voxygen/src/audio/soundcache.rs @@ -1,7 +1,8 @@ //! Handles caching and retrieval of decoded `.ogg` sfx sound data, eliminating //! the need to decode files on each playback -use common::assets; -use std::{borrow::Cow, io, sync::Arc}; +use common::assets::{self, Loader}; +use rodio::{source::Buffered, Decoder, Source}; +use std::{borrow::Cow, io}; use tracing::warn; // Implementation of sound taken from this github issue: @@ -10,16 +11,12 @@ use tracing::warn; pub struct SoundLoader; #[derive(Clone)] -pub struct OggSound(Arc>); +pub struct OggSound(Buffered>>>); -impl AsRef<[u8]> for OggSound { - fn as_ref(&self) -> &[u8] { &self.0 } -} - -impl assets::Loader for SoundLoader { +impl Loader for SoundLoader { fn load(content: Cow<[u8]>, _: &str) -> Result { - let arc = Arc::new(content.into_owned()); - Ok(OggSound(arc)) + let source = Decoder::new(io::Cursor::new(content.into_owned()))?.buffered(); + Ok(OggSound(source)) } } @@ -37,16 +34,13 @@ impl assets::Asset for OggSound { /// Wrapper for decoded audio data impl OggSound { - pub fn decoder( - self, - ) -> Result>, rodio::decoder::DecoderError> { - let cursor = io::Cursor::new(self); - rodio::Decoder::new(cursor) - } + pub fn to_source(&self) -> impl Source + Iterator { self.0.clone() } pub fn empty() -> OggSound { - OggSound(Arc::new( - include_bytes!("../../../assets/voxygen/audio/null.ogg").to_vec(), - )) + SoundLoader::load( + Cow::Borrowed(include_bytes!("../../../assets/voxygen/audio/null.ogg")), + "empty", + ) + .unwrap() } } diff --git a/voxygen/src/ecs/sys/interpolation.rs b/voxygen/src/ecs/sys/interpolation.rs index 97dba3a071..9abe8af9c5 100644 --- a/voxygen/src/ecs/sys/interpolation.rs +++ b/voxygen/src/ecs/sys/interpolation.rs @@ -43,7 +43,11 @@ impl<'a> System<'a> for Sys { { // Update interpolation values, but don't interpolate far things or objects if i.pos.distance_squared(pos.0) < 64.0 * 64.0 && !matches!(body, Body::Object(_)) { - i.pos = Lerp::lerp(i.pos, pos.0 + vel.0 * 0.03, 10.0 * dt.0); + // Note, these values are specifically tuned for smoother motion with high + // network latency or low network sampling rate and for smooth + // block hopping (which is instantaneous) + const POS_LERP_RATE_FACTOR: f32 = 10.0; + i.pos = Lerp::lerp(i.pos, pos.0 + vel.0 * 0.03, POS_LERP_RATE_FACTOR * dt.0); i.ori = Ori::slerp(i.ori, *ori, base_ori_interp(body) * dt.0); } else { i.pos = pos.0; diff --git a/voxygen/src/hud/map.rs b/voxygen/src/hud/map.rs index f2389230ad..7ea03cf1b8 100644 --- a/voxygen/src/hud/map.rs +++ b/voxygen/src/hud/map.rs @@ -327,7 +327,9 @@ impl<'a> Widget for Map<'a> { .sum(); // Drag represents offset of view from the player_pos in chunk coords let drag_new = drag + dragged / map_size / zoom * max_zoom; - events.push(Event::SettingsChange(MapDrag(drag_new))); + if drag_new != drag { + events.push(Event::SettingsChange(MapDrag(drag_new))); + } let rect_src = position::Rect::from_xy_dim( [ @@ -392,10 +394,12 @@ impl<'a> Widget for Map<'a> { .scrolls() .map(|scroll| scroll.y) .sum(); - let new_zoom_lvl = (self.global_state.settings.interface.map_zoom - * (scrolled * 0.05 * -1.0).exp2()) - .clamped(1.25, max_zoom / 64.0); - events.push(Event::SettingsChange(MapZoom(new_zoom_lvl as f64))); + if scrolled != 0.0 { + let new_zoom_lvl = (self.global_state.settings.interface.map_zoom + * (scrolled * 0.05 * -1.0).exp2()) + .clamped(1.25, max_zoom / 64.0); + events.push(Event::SettingsChange(MapZoom(new_zoom_lvl as f64))); + } // Icon settings // Alignment Rectangle::fill_with([150.0, 200.0], color::TRANSPARENT) diff --git a/voxygen/src/hud/minimap.rs b/voxygen/src/hud/minimap.rs index 7eb760a8aa..6eabfb7275 100644 --- a/voxygen/src/hud/minimap.rs +++ b/voxygen/src/hud/minimap.rs @@ -514,6 +514,7 @@ impl<'a> Widget for MiniMap<'a> { // Set the image dimensions here, rather than recomputing each time. zoom = min_zoom.max(zoom / ZOOM_FACTOR); // set_image_dims(zoom); + events.push(Event::SettingsChange(MinimapZoom(zoom))); } if Button::image(self.imgs.mmap_plus) .w_h(18.0 * SCALE, 18.0 * SCALE) @@ -528,6 +529,7 @@ impl<'a> Widget for MiniMap<'a> { { zoom = min_zoom.max(zoom * ZOOM_FACTOR); // set_image_dims(zoom); + events.push(Event::SettingsChange(MinimapZoom(zoom))); } // Always northfacing button @@ -555,8 +557,6 @@ impl<'a> Widget for MiniMap<'a> { events.push(Event::SettingsChange(MinimapFaceNorth(!is_facing_north))); } - events.push(Event::SettingsChange(MinimapZoom(zoom))); - // Coordinates let player_pos = self .client diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index edf4734e8a..6066aea2a5 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -240,6 +240,7 @@ widget_ids! { num_lights, num_figures, num_particles, + graphics_backend, gpu_timings[], // Game Version @@ -2195,6 +2196,17 @@ impl Hud { .font_size(self.fonts.cyri.scale(14)) .set(self.ids.num_particles, ui_widgets); + // Graphics backend + Text::new(&format!( + "Graphics backend: {}", + global_state.window.renderer().graphics_backend(), + )) + .color(TEXT_COLOR) + .down_from(self.ids.num_particles, 5.0) + .font_id(self.fonts.cyri.conrod_id) + .font_size(self.fonts.cyri.scale(14)) + .set(self.ids.graphics_backend, ui_widgets); + // GPU timing for different pipelines let gpu_timings = global_state.window.renderer().timings(); if !gpu_timings.is_empty() { @@ -3378,10 +3390,12 @@ impl Hud { .clamped(1.25, max_zoom / 64.0); global_state.settings.interface.map_zoom = new_zoom_lvl; + global_state.settings.save_to_file_warn(); } else if global_state.settings.interface.minimap_show { let new_zoom_lvl = global_state.settings.interface.minimap_zoom * factor; global_state.settings.interface.minimap_zoom = new_zoom_lvl; + global_state.settings.save_to_file_warn(); } show.map && global_state.settings.interface.minimap_show diff --git a/voxygen/src/hud/settings_window/video.rs b/voxygen/src/hud/settings_window/video.rs index c064da77de..0ce0cc2b0e 100644 --- a/voxygen/src/hud/settings_window/video.rs +++ b/voxygen/src/hud/settings_window/video.rs @@ -164,9 +164,8 @@ impl<'a> Widget for Video<'a> { .window .window() .current_monitor() - .unwrap() - .video_modes() - .collect(); + .map(|monitor| monitor.video_modes().collect()) + .unwrap_or_default(); State { ids: Ids::new(id_gen), diff --git a/voxygen/src/hud/util.rs b/voxygen/src/hud/util.rs index 7f93c96049..c66f332cfd 100644 --- a/voxygen/src/hud/util.rs +++ b/voxygen/src/hud/util.rs @@ -116,13 +116,13 @@ pub fn consumable_desc(effects: &[Effect], i18n: &Localization) -> String { let buff_desc = match buff.kind { BuffKind::Saturation | BuffKind::Regeneration | BuffKind::Potion => i18n .get("buff.stat.health") - .replace("{str_total}", &str_total.to_string()), + .replace("{str_total}", &*format!("{:.1}", &str_total)), BuffKind::IncreaseMaxEnergy => i18n .get("buff.stat.increase_max_stamina") - .replace("{strength}", &strength.to_string()), + .replace("{strength}", &*format!("{:.1}", &strength)), BuffKind::IncreaseMaxHealth => i18n .get("buff.stat.increase_max_health") - .replace("{strength}", &strength.to_string()), + .replace("{strength}", &*format!("{:.1}", &strength)), BuffKind::Invulnerability => i18n.get("buff.stat.invulnerability").to_string(), BuffKind::Bleeding | BuffKind::Burning diff --git a/voxygen/src/lib.rs b/voxygen/src/lib.rs index 896dad29c8..e6b882130a 100644 --- a/voxygen/src/lib.rs +++ b/voxygen/src/lib.rs @@ -65,7 +65,7 @@ pub struct GlobalState { pub singleplayer: Option, // TODO: redo this so that the watcher doesn't have to exist for reloading to occur pub i18n: LocalizationHandle, - pub clipboard: Option, + pub clipboard: iced_winit::Clipboard, // NOTE: This can be removed from GlobalState if client state behavior is refactored to not // enter the game before confirmation of successful character load /// An error returned by Client that needs to be displayed by the UI @@ -83,6 +83,7 @@ impl GlobalState { pub fn maintain(&mut self, dt: std::time::Duration) { span!(_guard, "maintain", "GlobalState::maintain"); self.audio.maintain(dt); + self.window.renderer().maintain() } #[cfg(feature = "singleplayer")] diff --git a/voxygen/src/main.rs b/voxygen/src/main.rs index a738a7e703..ad5ccb1373 100644 --- a/voxygen/src/main.rs +++ b/voxygen/src/main.rs @@ -203,7 +203,7 @@ fn main() { // Create window let (mut window, event_loop) = Window::new(&settings).expect("Failed to create window!"); - let clipboard = iced_winit::Clipboard::new(window.window()); + let clipboard = iced_winit::Clipboard::connect(window.window()); let lazy_init = SpriteRenderContext::new(window.renderer_mut()); diff --git a/voxygen/src/menu/char_selection/ui/mod.rs b/voxygen/src/menu/char_selection/ui/mod.rs index cc1c853910..a874e8c91e 100644 --- a/voxygen/src/menu/char_selection/ui/mod.rs +++ b/voxygen/src/menu/char_selection/ui/mod.rs @@ -1564,7 +1564,7 @@ impl CharSelectionUi { .view(&global_state.settings, &client, &self.error, &i18n), global_state.window.renderer_mut(), None, - global_state.clipboard.as_ref(), + &mut global_state.clipboard, ); if self.enter_pressed { diff --git a/voxygen/src/menu/main/ui/mod.rs b/voxygen/src/menu/main/ui/mod.rs index d17c06309f..cb333a9671 100644 --- a/voxygen/src/menu/main/ui/mod.rs +++ b/voxygen/src/menu/main/ui/mod.rs @@ -569,7 +569,7 @@ impl MainMenuUi { self.controls.view(&global_state.settings, dt.as_secs_f32()), global_state.window.renderer_mut(), None, - global_state.clipboard.as_ref(), + &mut global_state.clipboard, ); messages.into_iter().for_each(|message| { diff --git a/voxygen/src/render/pipelines/figure.rs b/voxygen/src/render/pipelines/figure.rs index 662f5db4c6..5502b4babd 100644 --- a/voxygen/src/render/pipelines/figure.rs +++ b/voxygen/src/render/pipelines/figure.rs @@ -80,7 +80,7 @@ impl Default for BoneData { } pub struct FigureModel { - pub opaque: Model, + pub opaque: Option>, /* TODO: Consider using mipmaps instead of storing multiple texture atlases for different * LOD levels. */ } diff --git a/voxygen/src/render/pipelines/particle.rs b/voxygen/src/render/pipelines/particle.rs index 947c861695..381ff30cd2 100644 --- a/voxygen/src/render/pipelines/particle.rs +++ b/voxygen/src/render/pipelines/particle.rs @@ -83,6 +83,7 @@ pub enum ParticleMode { Water = 30, IceSpikes = 31, Drip = 32, + Tornado = 33, } impl ParticleMode { diff --git a/voxygen/src/render/renderer.rs b/voxygen/src/render/renderer.rs index 7f438f0121..88de873f00 100644 --- a/voxygen/src/render/renderer.rs +++ b/voxygen/src/render/renderer.rs @@ -144,6 +144,9 @@ pub struct Renderer { // This checks is added because windows resizes the window to 0,0 when // minimizing and this causes a bunch of validation errors is_minimized: bool, + + // To remember the backend info after initialization for debug purposes + graphics_backend: String, } impl Renderer { @@ -193,37 +196,73 @@ impl Renderer { )) .ok_or(RenderError::CouldNotFindAdapter)?; + let info = adapter.get_info(); + info!( + ?info.name, + ?info.vendor, + ?info.backend, + ?info.device, + ?info.device_type, + "selected graphics device" + ); + let graphics_backend = format!("{:?}", &info.backend); + let limits = wgpu::Limits { max_push_constant_size: 64, ..Default::default() }; - let (device, queue) = futures_executor::block_on( - adapter.request_device( - &wgpu::DeviceDescriptor { - // TODO - label: None, - features: wgpu::Features::DEPTH_CLAMPING - | wgpu::Features::ADDRESS_MODE_CLAMP_TO_BORDER - | wgpu::Features::PUSH_CONSTANTS - | (adapter.features() & wgpu_profiler::GpuProfiler::REQUIRED_WGPU_FEATURES), - limits, - }, - std::env::var_os("WGPU_TRACE_DIR") - .as_ref() - .map(|v| std::path::Path::new(v)), - ), - )?; + let (device, queue) = futures_executor::block_on(adapter.request_device( + &wgpu::DeviceDescriptor { + // TODO + label: None, + features: wgpu::Features::DEPTH_CLAMPING + | wgpu::Features::ADDRESS_MODE_CLAMP_TO_BORDER + | wgpu::Features::PUSH_CONSTANTS + | (adapter.features() & wgpu_profiler::GpuProfiler::REQUIRED_WGPU_FEATURES), + limits, + }, + std::env::var_os("WGPU_TRACE_DIR").as_ref().map(|v| { + let path = std::path::Path::new(v); + // We don't want to continue if we can't actually collect the api trace + if !path.exists() { + panic!( + "WGPU_TRACE_DIR is set to the path \"{}\" which doesn't exist", + path.display() + ); + } + if !path.is_dir() { + panic!( + "WGPU_TRACE_DIR is set to the path \"{}\" which is not a directory", + path.display() + ); + } + if path + .read_dir() + .expect("Could not read the directory that is specified by WGPU_TRACE_DIR") + .next() + .is_some() + { + panic!( + "WGPU_TRACE_DIR is set to the path \"{}\" which already contains other \ + files", + path.display() + ); + } + + path + }), + ))?; // Set error handler for wgpu errors // This is better for use than their default because it includes the error in // the panic message - device.on_uncaptured_error(|error| { + device.on_uncaptured_error(move |error| { error!("{}", &error); panic!( - "wgpu error (handling all wgpu errors as fatal): {:?}", - &error, - ) + "wgpu error (handling all wgpu errors as fatal):\n{:?}\n{:?}", + &error, &info, + ); }); let profiler_features_enabled = device @@ -236,19 +275,14 @@ impl Renderer { ); } - let info = adapter.get_info(); - info!( - ?info.name, - ?info.vendor, - ?info.backend, - ?info.device, - ?info.device_type, - "selected graphics device" - ); + let format = adapter + .get_swap_chain_preferred_format(&surface) + .expect("No supported swap chain format found"); + info!("Using {:?} as the swapchain format", format); let sc_desc = wgpu::SwapChainDescriptor { usage: wgpu::TextureUsage::RENDER_ATTACHMENT, - format: wgpu::TextureFormat::Bgra8UnormSrgb, + format, width: dims.width, height: dims.height, present_mode: mode.present_mode.into(), @@ -409,9 +443,14 @@ impl Renderer { egui_renderpass, is_minimized: false, + + graphics_backend, }) } + /// Get the graphics backend being used + pub fn graphics_backend(&self) -> &str { &self.graphics_backend } + /// Check the status of the intial pipeline creation /// Returns `None` if complete /// Returns `Some((total, complete))` if in progress @@ -573,6 +612,14 @@ impl Renderer { Ok(()) } + pub fn maintain(&self) { + if self.is_minimized { + self.queue.submit(std::iter::empty()); + } + + self.device.poll(wgpu::Maintain::Poll) + } + /// Create render target views fn create_rt_views( device: &wgpu::Device, diff --git a/voxygen/src/render/renderer/drawer.rs b/voxygen/src/render/renderer/drawer.rs index 123312612c..44acb5269d 100644 --- a/voxygen/src/render/renderer/drawer.rs +++ b/voxygen/src/render/renderer/drawer.rs @@ -5,7 +5,7 @@ use super::{ model::{DynamicModel, Model, SubModel}, pipelines::{ blit, clouds, debug, figure, fluid, lod_terrain, particle, shadow, skybox, sprite, - terrain, ui, ColLights, GlobalsBindGroup, + terrain, ui, ColLights, GlobalsBindGroup, ShadowTexturesBindGroup, }, }, Renderer, ShadowMap, ShadowMapRenderer, @@ -208,6 +208,7 @@ impl<'frame> Drawer<'frame> { borrow: &self.borrow, pipelines, globals: self.globals, + shadows: &shadow.bind, }) } @@ -575,6 +576,7 @@ pub struct FirstPassDrawer<'pass> { borrow: &'pass RendererBorrow<'pass>, pipelines: &'pass super::Pipelines, globals: &'pass GlobalsBindGroup, + shadows: &'pass ShadowTexturesBindGroup, } impl<'pass> FirstPassDrawer<'pass> { @@ -593,7 +595,10 @@ impl<'pass> FirstPassDrawer<'pass> { render_pass.set_pipeline(&self.pipelines.debug.pipeline); set_quad_index_buffer::(&mut render_pass, &self.borrow); - DebugDrawer { render_pass } + DebugDrawer { + render_pass, + shadows: self.shadows, + } } pub fn draw_lod_terrain<'data: 'pass>(&mut self, model: &'data Model) { @@ -666,6 +671,7 @@ impl<'pass> FirstPassDrawer<'pass> { pub struct DebugDrawer<'pass_ref, 'pass: 'pass_ref> { render_pass: Scope<'pass_ref, wgpu::RenderPass<'pass>>, + shadows: &'pass ShadowTexturesBindGroup, } impl<'pass_ref, 'pass: 'pass_ref> DebugDrawer<'pass_ref, 'pass> { @@ -680,6 +686,14 @@ impl<'pass_ref, 'pass: 'pass_ref> DebugDrawer<'pass_ref, 'pass> { } } +impl<'pass_ref, 'pass: 'pass_ref> Drop for DebugDrawer<'pass_ref, 'pass> { + fn drop(&mut self) { + // Maintain that the shadow bind group is set in + // slot 1 by default during the main pass + self.render_pass + .set_bind_group(1, &self.shadows.bind_group, &[]); + } +} pub struct FigureDrawer<'pass_ref, 'pass: 'pass_ref> { render_pass: Scope<'pass_ref, wgpu::RenderPass<'pass>>, } diff --git a/voxygen/src/render/renderer/shadow_map.rs b/voxygen/src/render/renderer/shadow_map.rs index b7361adebe..5832c77ff3 100644 --- a/voxygen/src/render/renderer/shadow_map.rs +++ b/voxygen/src/render/renderer/shadow_map.rs @@ -188,7 +188,9 @@ impl ShadowMap { let diag_two_size = u32::checked_next_power_of_two(diag_size) .filter(|&e| e <= max_texture_size) // Limit to max texture resolution rather than error. - .unwrap_or(max_texture_size); + .unwrap_or(max_texture_size) + // Make sure we don't try to create a zero sized texture (divided by 4 below) + .max(4); let point_shadow_tex = wgpu::TextureDescriptor { label: None, diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index 167bbf2571..c43d262185 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -88,11 +88,12 @@ pub struct FigureModelEntry { } impl FigureModelEntry { - pub fn lod_model(&self, lod: usize) -> SubModel { + pub fn lod_model(&self, lod: usize) -> Option> { // Note: Range doesn't impl Copy even for trivially Cloneable things self.model .opaque - .submodel(self.lod_vertex_ranges[lod].clone()) + .as_ref() + .map(|m| m.submodel(self.lod_vertex_ranges[lod].clone())) } } @@ -3480,6 +3481,70 @@ impl FigureMgr { skeleton_attr, ) }, + CharacterState::BasicSummon(s) => { + let stage_time = s.timer.as_secs_f32(); + let stage_progress = match s.stage_section { + StageSection::Buildup => { + stage_time / s.static_data.buildup_duration.as_secs_f32() + }, + + StageSection::Cast => { + stage_time / s.static_data.cast_duration.as_secs_f32() + }, + StageSection::Recover => { + stage_time / s.static_data.recover_duration.as_secs_f32() + }, + _ => 0.0, + }; + + anim::bird_large::SummonAnimation::update_skeleton( + &target_base, + ( + time, + Some(s.stage_section), + state.state_time, + look_dir, + physics.on_ground, + ), + stage_progress, + &mut state_animation_rate, + skeleton_attr, + ) + }, + CharacterState::DashMelee(s) => { + let stage_time = s.timer.as_secs_f32(); + let stage_progress = match s.stage_section { + StageSection::Buildup => { + stage_time / s.static_data.buildup_duration.as_secs_f32() + }, + StageSection::Charge => { + stage_time / s.static_data.charge_duration.as_secs_f32() + }, + StageSection::Swing => { + stage_time / s.static_data.swing_duration.as_secs_f32() + }, + StageSection::Recover => { + stage_time / s.static_data.recover_duration.as_secs_f32() + }, + _ => 0.0, + }; + anim::bird_large::DashAnimation::update_skeleton( + &target_base, + ( + rel_vel, + // TODO: Update to use the quaternion. + ori * anim::vek::Vec3::::unit_y(), + state.last_ori * anim::vek::Vec3::::unit_y(), + state.acc_vel, + Some(s.stage_section), + time, + state.state_time, + ), + stage_progress, + &mut state_animation_rate, + skeleton_attr, + ) + }, CharacterState::Stunned(s) => { let stage_time = s.timer.as_secs_f32(); let stage_progress = match s.stage_section { @@ -5163,7 +5228,7 @@ impl FigureMgr { model_entry.lod_model(0) }; - Some((bound, model, col_lights_.texture(model_entry))) + Some((bound, model?, col_lights_.texture(model_entry))) } else { // trace!("Body has no saved figure"); None @@ -5221,9 +5286,7 @@ impl FigureColLights { let col_lights = renderer.figure_bind_col_light(col_lights); let model_len = u32::try_from(opaque.vertices().len()) .expect("The model size for this figure does not fit in a u32!"); - let model = renderer - .create_model(&opaque) - .expect("The model contains no vertices!"); + let model = renderer.create_model(&opaque); vertex_ranges.iter().for_each(|range| { assert!( diff --git a/voxygen/src/scene/particle.rs b/voxygen/src/scene/particle.rs index 33452ec101..1b70bd660f 100644 --- a/voxygen/src/scene/particle.rs +++ b/voxygen/src/scene/particle.rs @@ -248,7 +248,8 @@ impl ParticleMgr { | Outcome::SkillPointGain { .. } | Outcome::ComboChange { .. } | Outcome::Damage { .. } - | Outcome::PoiseChange { .. } => {}, + | Outcome::PoiseChange { .. } + | Outcome::Utterance { .. } => {}, } } @@ -323,6 +324,9 @@ impl ParticleMgr { Body::Object(object::Body::BoltNature) => { self.maintain_boltnature_particles(scene_data, pos, vel) }, + Body::Object(object::Body::Tornado) => { + self.maintain_tornado_particles(scene_data, pos) + }, Body::Object( object::Body::Bomb | object::Body::FireworkBlue @@ -498,6 +502,24 @@ impl ParticleMgr { ); } + fn maintain_tornado_particles(&mut self, scene_data: &SceneData, pos: &Pos) { + let time = scene_data.state.get_time(); + let mut rng = thread_rng(); + + // air particles + self.particles.resize_with( + self.particles.len() + usize::from(self.scheduler.heartbeats(Duration::from_millis(5))), + || { + Particle::new( + Duration::from_millis(1000), + time, + ParticleMode::Tornado, + pos.0.map(|e| e + rng.gen_range(-0.25..0.25)), + ) + }, + ); + } + fn maintain_bomb_particles(&mut self, scene_data: &SceneData, pos: &Pos, vel: Option<&Vel>) { span!( _guard, diff --git a/voxygen/src/scene/simple.rs b/voxygen/src/scene/simple.rs index 54fd63bea4..19cec5b20d 100644 --- a/voxygen/src/scene/simple.rs +++ b/voxygen/src/scene/simple.rs @@ -366,20 +366,20 @@ impl Scene { ); if let Some(model) = model { - figure_drawer.draw( - model.lod_model(0), - self.figure_state.bound(), - &self.col_lights.texture(model), - ); + if let Some(lod) = model.lod_model(0) { + figure_drawer.draw( + lod, + self.figure_state.bound(), + &self.col_lights.texture(model), + ); + } } } if let Some((model, state)) = &self.backdrop { - figure_drawer.draw( - model.lod_model(0), - state.bound(), - &self.col_lights.texture(model), - ); + if let Some(lod) = model.lod_model(0) { + figure_drawer.draw(lod, state.bound(), &self.col_lights.texture(model)); + } } drop(figure_drawer); diff --git a/voxygen/src/session/mod.rs b/voxygen/src/session/mod.rs index 3595f9fe92..2e49a8e7fa 100644 --- a/voxygen/src/session/mod.rs +++ b/voxygen/src/session/mod.rs @@ -15,7 +15,7 @@ use common::{ inventory::slot::{EquipSlot, Slot}, invite::InviteKind, item::{tool::ToolKind, ItemDef, ItemDesc}, - ChatMsg, ChatType, InputKind, InventoryUpdateEvent, Pos, Vel, + ChatMsg, ChatType, InputKind, InventoryUpdateEvent, Pos, UtteranceKind, Vel, }, consts::{MAX_MOUNT_RANGE, MAX_PICKUP_RANGE}, outcome::Outcome, @@ -524,6 +524,11 @@ impl PlayState for SessionState { self.client.borrow_mut().toggle_dance(); } }, + GameInput::Greet => { + if state { + self.client.borrow_mut().utter(UtteranceKind::Greeting); + } + }, GameInput::Sneak => { if state { self.stop_auto_walk(); diff --git a/voxygen/src/settings/control.rs b/voxygen/src/settings/control.rs index 67b4defb63..c0b9eb1bd6 100644 --- a/voxygen/src/settings/control.rs +++ b/voxygen/src/settings/control.rs @@ -123,6 +123,7 @@ impl ControlSettings { GameInput::Jump => KeyMouse::Key(VirtualKeyCode::Space), GameInput::Sit => KeyMouse::Key(VirtualKeyCode::K), GameInput::Dance => KeyMouse::Key(VirtualKeyCode::J), + GameInput::Greet => KeyMouse::Key(VirtualKeyCode::H), GameInput::Glide => KeyMouse::Key(VirtualKeyCode::LShift), GameInput::Climb => KeyMouse::Key(VirtualKeyCode::Space), GameInput::ClimbDown => KeyMouse::Key(VirtualKeyCode::LControl), diff --git a/voxygen/src/ui/ice/mod.rs b/voxygen/src/ui/ice/mod.rs index 849ab7a76a..91393ad0cf 100644 --- a/voxygen/src/ui/ice/mod.rs +++ b/voxygen/src/ui/ice/mod.rs @@ -148,7 +148,7 @@ impl IcedUi { root: E, renderer: &mut Renderer, pool: Option<&SlowJobPool>, - clipboard: Option<&Clipboard>, + clipboard: &mut Clipboard, ) -> (Vec, mouse::Interaction) { span!(_guard, "maintain", "IcedUi::maintain"); // Handle window resizing, dpi factor change, and scale mode changing @@ -194,11 +194,8 @@ impl IcedUi { let _event_status_list = user_interface.update( &self.events, cursor_position, - match clipboard { - Some(c) => Some(c), - None => None, - }, &self.renderer, + clipboard, &mut messages, ); messages diff --git a/voxygen/src/ui/ice/renderer/mod.rs b/voxygen/src/ui/ice/renderer/mod.rs index 83eb8f1320..ae83454051 100644 --- a/voxygen/src/ui/ice/renderer/mod.rs +++ b/voxygen/src/ui/ice/renderer/mod.rs @@ -711,14 +711,9 @@ impl IcedRenderer { if intersection.is_valid() && intersection.size().map(|s| s > 0).reduce_and() { intersection } else { - // Create a aabr with width 1 and height 1, technically - // it would be more correct to do it with 0,0 but that's - // a validation error in wgpu so enjoy your funky pixel - // in the top left of your screen - Aabr { - min: Vec2::zero(), - max: Vec2::one(), - } + // If the intersection is invalid or zero sized we don't need to process + // the content primitive + return; } }; // Not expecting this case: new_scissor == current_scissor @@ -737,8 +732,8 @@ impl IcedRenderer { self.draw_commands.push(DrawCommand::Scissor(new_scissor)); // TODO: support nested clips? - // TODO: if last command is a clip changing back to the default replace it with - // this + // TODO: if previous command was a clip changing back to the default replace it + // with this // TODO: cull primitives outside the current scissor // Renderer child diff --git a/voxygen/src/ui/ice/renderer/widget/button.rs b/voxygen/src/ui/ice/renderer/widget/button.rs index cf05a448bf..40a6bff71c 100644 --- a/voxygen/src/ui/ice/renderer/widget/button.rs +++ b/voxygen/src/ui/ice/renderer/widget/button.rs @@ -5,7 +5,7 @@ impl button::Renderer for IcedRenderer { // TODO: what if this gets large enough to not be copied around? type Style = style::button::Style; - const DEFAULT_PADDING: u16 = 0; + const DEFAULT_PADDING: iced::Padding = iced::Padding::ZERO; fn draw( &mut self, diff --git a/voxygen/src/ui/ice/widget/aspect_ratio_container.rs b/voxygen/src/ui/ice/widget/aspect_ratio_container.rs index 8db9bd33ca..e420f22441 100644 --- a/voxygen/src/ui/ice/widget/aspect_ratio_container.rs +++ b/voxygen/src/ui/ice/widget/aspect_ratio_container.rs @@ -119,17 +119,17 @@ where event: Event, layout: Layout<'_>, cursor_position: Point, - messages: &mut Vec, renderer: &R, - clipboard: Option<&dyn Clipboard>, + clipboard: &mut dyn Clipboard, + messages: &mut Vec, ) -> iced::event::Status { self.content.on_event( event, layout.children().next().unwrap(), cursor_position, - messages, renderer, clipboard, + messages, ) } diff --git a/voxygen/src/ui/ice/widget/background_container.rs b/voxygen/src/ui/ice/widget/background_container.rs index ce267b7a13..53de3a647d 100644 --- a/voxygen/src/ui/ice/widget/background_container.rs +++ b/voxygen/src/ui/ice/widget/background_container.rs @@ -255,17 +255,17 @@ where event: Event, layout: Layout<'_>, cursor_position: Point, - messages: &mut Vec, renderer: &R, - clipboard: Option<&dyn Clipboard>, + clipboard: &mut dyn Clipboard, + messages: &mut Vec, ) -> iced::event::Status { self.content.on_event( event, layout.children().next().unwrap(), cursor_position, - messages, renderer, clipboard, + messages, ) } diff --git a/voxygen/src/ui/ice/widget/mouse_detector.rs b/voxygen/src/ui/ice/widget/mouse_detector.rs index a93df67ae5..036a2f19a9 100644 --- a/voxygen/src/ui/ice/widget/mouse_detector.rs +++ b/voxygen/src/ui/ice/widget/mouse_detector.rs @@ -48,9 +48,9 @@ where event: Event, layout: Layout<'_>, _cursor_position: Point, - _messages: &mut Vec, _renderer: &R, - _clipboard: Option<&dyn Clipboard>, + _clipboard: &mut dyn Clipboard, + _messages: &mut Vec, ) -> iced::event::Status { if let Event::Mouse(mouse::Event::CursorMoved { position: Point { x, y }, diff --git a/voxygen/src/ui/ice/widget/overlay.rs b/voxygen/src/ui/ice/widget/overlay.rs index c9b1ff66b9..0bcd0d3833 100644 --- a/voxygen/src/ui/ice/widget/overlay.rs +++ b/voxygen/src/ui/ice/widget/overlay.rs @@ -1,6 +1,6 @@ use iced::{ - layout, mouse, Align, Clipboard, Element, Event, Hasher, Layout, Length, Point, Rectangle, - Size, Widget, + layout, mouse, Align, Clipboard, Element, Event, Hasher, Layout, Length, Padding, Point, + Rectangle, Size, Widget, }; use std::hash::Hash; @@ -10,7 +10,7 @@ use std::hash::Hash; /// the front widget /// Alignment and padding is used for the front widget pub struct Overlay<'a, M, R: self::Renderer> { - padding: u16, + padding: Padding, width: Length, height: Length, max_width: u32, @@ -32,7 +32,7 @@ where U: Into>, { Self { - padding: 0, + padding: Padding::ZERO, width: Length::Shrink, height: Length::Shrink, max_width: u32::MAX, @@ -44,8 +44,8 @@ where } } - pub fn padding(mut self, pad: u16) -> Self { - self.padding = pad; + pub fn padding>(mut self, pad: P) -> Self { + self.padding = pad.into(); self } @@ -99,8 +99,6 @@ where fn height(&self) -> Length { self.height } fn layout(&self, renderer: &R, limits: &layout::Limits) -> layout::Node { - let padding = self.padding as f32; - let limits = limits .loose() .max_width(self.max_width) @@ -111,16 +109,22 @@ where let under = self.under.layout(renderer, &limits.loose()); let under_size = under.size(); - let limits = limits.pad(padding); + let limits = limits.pad(self.padding); let mut over = self.over.layout(renderer, &limits.loose()); let over_size = over.size(); - let size = limits.resolve(Size { - width: under_size.width.max(over_size.width + padding * 2.0), - height: under_size.height.max(over_size.height + padding * 2.0), - }); + let size = limits.resolve( + Size { + width: under_size.width.max(over_size.width), + height: under_size.height.max(over_size.height), + } + .pad(self.padding), + ); - over.move_to(Point::new(padding, padding)); + over.move_to(Point::new( + self.padding.left.into(), + self.padding.top.into(), + )); over.align(self.horizontal_alignment, self.vertical_alignment, size); layout::Node::with_children(size, vec![over, under]) @@ -131,9 +135,9 @@ where event: Event, layout: Layout<'_>, cursor_position: Point, - messages: &mut Vec, renderer: &R, - clipboard: Option<&dyn Clipboard>, + clipboard: &mut dyn Clipboard, + messages: &mut Vec, ) -> iced::event::Status { let mut children = layout.children(); let over_layout = children.next().unwrap(); @@ -143,9 +147,9 @@ where event.clone(), over_layout, cursor_position, - messages, renderer, clipboard, + messages, ); // If mouse press check if over the overlay widget before sending to under @@ -158,9 +162,9 @@ where event, children.next().unwrap(), cursor_position, - messages, renderer, clipboard, + messages, ) .merge(status) } else { diff --git a/voxygen/src/ui/ice/widget/tooltip.rs b/voxygen/src/ui/ice/widget/tooltip.rs index 2e616a1f85..7ef1e58a42 100644 --- a/voxygen/src/ui/ice/widget/tooltip.rs +++ b/voxygen/src/ui/ice/widget/tooltip.rs @@ -189,17 +189,17 @@ where event: Event, layout: Layout<'_>, cursor_position: Point, - messages: &mut Vec, renderer: &R, - clipboard: Option<&dyn Clipboard>, + clipboard: &mut dyn Clipboard, + messages: &mut Vec, ) -> iced::event::Status { self.content.on_event( event, layout, cursor_position, - messages, renderer, clipboard, + messages, ) } diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs index e72590f769..118fe109e9 100644 --- a/voxygen/src/window.rs +++ b/voxygen/src/window.rs @@ -39,6 +39,7 @@ pub enum GameInput { Jump, Sit, Dance, + Greet, Glide, Climb, ClimbDown, @@ -94,6 +95,7 @@ impl GameInput { GameInput::Jump => "gameinput.jump", GameInput::Sit => "gameinput.sit", GameInput::Dance => "gameinput.dance", + GameInput::Greet => "gameinput.greet", GameInput::Glide => "gameinput.glide", GameInput::Climb => "gameinput.climb", GameInput::ClimbDown => "gameinput.climbdown", @@ -159,6 +161,7 @@ impl GameInput { GameInput::Jump, GameInput::Sit, GameInput::Dance, + GameInput::Greet, GameInput::Glide, GameInput::Climb, GameInput::ClimbDown, @@ -1130,7 +1133,10 @@ impl Window { pub fn is_fullscreen(&self) -> bool { self.fullscreen.enabled } - pub fn select_video_mode_rec( + /// Select a video mode that fits the specified requirements + /// Returns None if a matching video mode doesn't exist or if + /// the current monitor can't be retrieved + fn select_video_mode_rec( &self, resolution: [u16; 2], bit_depth: Option, @@ -1142,15 +1148,16 @@ impl Window { // if a previous iteration of this method filtered the available video modes for // the correct resolution already, load that value, otherwise filter it // in this iteration - let correct_res = correct_res.unwrap_or_else(|| { - self.window - .current_monitor() - .unwrap() + let correct_res = match correct_res { + Some(correct_res) => correct_res, + None => self + .window + .current_monitor()? .video_modes() .filter(|mode| mode.size().width == resolution[0] as u32) .filter(|mode| mode.size().height == resolution[1] as u32) - .collect() - }); + .collect(), + }; match bit_depth { // A bit depth is given @@ -1270,12 +1277,12 @@ impl Window { } } - pub fn select_video_mode( + fn select_video_mode( &self, resolution: [u16; 2], bit_depth: Option, refresh_rate: Option, - ) -> VideoMode { + ) -> Option { // (resolution, bit depth, refresh rate) represents a video mode // spec: as specified // max: maximum value available @@ -1285,24 +1292,34 @@ impl Window { // (spec, spec, max), (spec, max, spec) // (spec, max, max) // (max, max, max) - self.select_video_mode_rec(resolution, bit_depth, refresh_rate, None, None, None) - // if there is no video mode with the specified resolution, fall back to the video mode with max resolution, bit depth and refresh rate - .unwrap_or_else(|| { + match self.select_video_mode_rec(resolution, bit_depth, refresh_rate, None, None, None) { + Some(mode) => Some(mode), + // if there is no video mode with the specified resolution, + // fall back to the video mode with max resolution, bit depth and refresh rate + None => { warn!( "Resolution specified in settings is incompatible with the monitor. Choosing \ highest resolution possible instead." ); + if let Some(monitor) = self.window.current_monitor() { + let mode = monitor + .video_modes() + // Prefer bit depth over refresh rate + .sorted_by_key(|mode| mode.refresh_rate()) + .sorted_by_key(|mode| mode.bit_depth()) + .max_by_key(|mode| mode.size().width); - self - .window - .current_monitor().unwrap() - .video_modes() - // Prefer bit depth over refresh rate - .sorted_by_key(|mode| mode.refresh_rate()) - .sorted_by_key(|mode| mode.bit_depth()) - .max_by_key(|mode| mode.size().width) - .expect("No video modes available!!") - }) + if mode.is_none() { + warn!("Failed to select video mode, no video modes available!!") + } + + mode + } else { + warn!("Failed to select video mode, can't get the current monitor!"); + None + } + }, + } } pub fn set_fullscreen_mode(&mut self, fullscreen: FullScreenSettings) { @@ -1310,14 +1327,23 @@ impl Window { self.fullscreen = fullscreen; window.set_fullscreen(fullscreen.enabled.then(|| match fullscreen.mode { FullscreenMode::Exclusive => { - winit::window::Fullscreen::Exclusive(self.select_video_mode( + if let Some(video_mode) = self.select_video_mode( fullscreen.resolution, fullscreen.bit_depth, fullscreen.refresh_rate, - )) + ) { + winit::window::Fullscreen::Exclusive(video_mode) + } else { + warn!( + "Failed to select a video mode for exclusive fullscreen. Falling back to \ + borderless fullscreen." + ); + winit::window::Fullscreen::Borderless(None) + } }, FullscreenMode::Borderless => { - winit::window::Fullscreen::Borderless(window.current_monitor()) + // None here will fullscreen on the current monitor + winit::window::Fullscreen::Borderless(None) }, })); } diff --git a/world/src/layer/mod.rs b/world/src/layer/mod.rs index 9c12b4c130..f448f71f79 100644 --- a/world/src/layer/mod.rs +++ b/world/src/layer/mod.rs @@ -328,7 +328,7 @@ pub fn apply_caves_to(canvas: &mut Canvas, rng: &mut impl Rng) { // Scatter things in caves if cave_depth > 40.0 && cave_depth < 80.0 { - if rng.gen::() < 0.2 * (cave_x.max(0.5).powf(4.0)) && !vein_condition { + if rng.gen::() < 0.14 * (cave_x.max(0.5).powf(4.0)) && !vein_condition { let kind = *Lottery::::load_expect("common.cave_scatter.shallow_floor") .read() @@ -349,7 +349,7 @@ pub fn apply_caves_to(canvas: &mut Canvas, rng: &mut impl Rng) { ); } } else if cave_depth < 200.0 && cave_depth > 80.0 { - if rng.gen::() < 0.12 * (cave_x.max(0.5).powf(4.0)) && !vein_condition { + if rng.gen::() < 0.065 * (cave_x.max(0.5).powf(4.0)) && !vein_condition { let kind = *Lottery::::load_expect("common.cave_scatter.deep_floor") .read() @@ -370,7 +370,7 @@ pub fn apply_caves_to(canvas: &mut Canvas, rng: &mut impl Rng) { ); } } else { - if rng.gen::() < 0.12 * (cave_x.max(0.5).powf(4.0)) + if rng.gen::() < 0.08 * (cave_x.max(0.5).powf(4.0)) && cave_depth > 40.0 && !vein_condition { @@ -445,7 +445,7 @@ pub fn apply_caves_supplement<'a>( .map_or(true, |b| b.is_fluid()) }) }) { - if RandomField::new(index.seed).chance(wpos2d.into(), 0.0018) + if RandomField::new(index.seed).chance(wpos2d.into(), 0.0014) && cave_base < surface_z as i32 - 40 { let is_hostile: bool; @@ -470,7 +470,7 @@ pub fn apply_caves_supplement<'a>( }; comp::quadruped_low::Body::random_with(dynamic_rng, &species) .into() - } else if cave_depth < 200.0 { + } else if cave_depth < 190.0 { is_hostile = true; let species = match dynamic_rng.gen_range(0..3) { 0 => comp::quadruped_low::Species::Rocksnapper, @@ -489,7 +489,7 @@ pub fn apply_caves_supplement<'a>( 0 => comp::biped_large::Species::Blueoni, _ => comp::biped_large::Species::Redoni, }, - _ => comp::biped_large::Species::Troll, + _ => comp::biped_large::Species::Cavetroll, }; comp::biped_large::Body::random_with(dynamic_rng, &species) .into() diff --git a/world/src/layer/wildlife.rs b/world/src/layer/wildlife.rs index f15ec3a9bc..362fcf2fed 100644 --- a/world/src/layer/wildlife.rs +++ b/world/src/layer/wildlife.rs @@ -119,9 +119,15 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( Entry { make_entity: |pos, rng| { EntityInfo::at(pos) - .with_body( - biped_large::Body::random_with(rng, &biped_large::Species::Wendigo).into(), - ) + .with_body(match rng.gen_range(0..2) { + 0 => biped_large::Body::random_with(rng, &biped_large::Species::Wendigo) + .into(), + _ => biped_large::Body::random_with( + rng, + &biped_large::Species::Mountaintroll, + ) + .into(), + }) .with_alignment(Alignment::Enemy) }, group_size: 1..2, @@ -454,9 +460,8 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( 0 => { biped_large::Body::random_with(rng, &biped_large::Species::Ogre).into() }, - 1 => { - biped_large::Body::random_with(rng, &biped_large::Species::Troll).into() - }, + 1 => biped_large::Body::random_with(rng, &biped_large::Species::Swamptroll) + .into(), _ => biped_large::Body::random_with(rng, &biped_large::Species::Cyclops) .into(), }) @@ -624,7 +629,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( Entry { make_entity: |pos, rng| { EntityInfo::at(pos) - .with_body(match rng.gen_range(0..4) { + .with_body(match rng.gen_range(0..5) { 0 => theropod::Body::random_with(rng, &theropod::Species::Odonto).into(), 1 => { biped_large::Body::random_with(rng, &biped_large::Species::Mightysaurok) @@ -634,6 +639,8 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( biped_large::Body::random_with(rng, &biped_large::Species::Occultsaurok) .into() }, + 3 => bird_large::Body::random_with(rng, &bird_large::Species::Cockatrice) + .into(), _ => biped_large::Body::random_with(rng, &biped_large::Species::Slysaurok) .into(), }) @@ -653,12 +660,11 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( Entry { make_entity: |pos, rng| { EntityInfo::at(pos) - .with_body(match rng.gen_range(0..4) { + .with_body(match rng.gen_range(0..3) { 0 => bird_medium::Body::random_with(rng, &bird_medium::Species::Parrot) .into(), - 1 => bird_large::Body::random_with(rng, &bird_large::Species::Cockatrice) - .into(), - 2 => quadruped_small::Body::random_with( + + 1 => quadruped_small::Body::random_with( rng, &quadruped_small::Species::Quokka, )