From 8cf8e5196270f1946274021cf1577748fa5b7bbd Mon Sep 17 00:00:00 2001 From: Snowram Date: Wed, 21 Apr 2021 00:36:40 +0200 Subject: [PATCH] Phoenix npc + AI (WIP) --- .../unique/birdlargefire/firebomb.ron | 17 ++ .../unique/birdlargefire/fireshockwave.ron | 15 ++ .../unique/birdlargefire/flamethrower.ron | 14 ++ .../unique/birdlargefire/triplestrike.ron | 53 +++++ .../abilities/weapon_ability_manifest.ron | 8 + .../npc_weapons/unique/birdlargefire.ron | 18 ++ .../voxel/bird_large_central_manifest.ron | 28 +-- .../voxel/bird_large_lateral_manifest.ron | 40 ++-- .../voxygen/voxel/npc/phoenix/male/beak.vox | 4 +- .../voxygen/voxel/npc/phoenix/male/chest.vox | 4 +- .../voxygen/voxel/npc/phoenix/male/foot_r.vox | 4 +- .../voxygen/voxel/npc/phoenix/male/head.vox | 4 +- .../voxygen/voxel/npc/phoenix/male/leg_r.vox | 4 +- .../voxygen/voxel/npc/phoenix/male/neck.vox | 4 +- .../voxel/npc/phoenix/male/tail_front.vox | 4 +- .../voxel/npc/phoenix/male/tail_rear.vox | 4 +- .../voxel/npc/phoenix/male/wing_in_r.vox | 4 +- .../voxel/npc/phoenix/male/wing_mid_r.vox | 4 +- .../voxel/npc/phoenix/male/wing_out_r.vox | 4 +- common/src/comp/agent.rs | 4 +- common/src/comp/body.rs | 6 +- common/src/comp/inventory/item/tool.rs | 1 + common/src/comp/inventory/loadout_builder.rs | 6 +- common/src/states/utils.rs | 2 +- server/src/sys/agent.rs | 220 ++++++++++++++++++ voxygen/anim/src/bird_large/alpha.rs | 22 +- voxygen/anim/src/bird_large/breathe.rs | 1 - voxygen/anim/src/bird_large/feed.rs | 9 +- voxygen/anim/src/bird_large/idle.rs | 13 +- voxygen/anim/src/bird_large/mod.rs | 38 +-- voxygen/anim/src/bird_large/shockwave.rs | 99 ++++++++ voxygen/anim/src/bird_large/shoot.rs | 136 +++++++++++ voxygen/anim/src/bird_large/stunned.rs | 1 - voxygen/anim/src/bird_large/swim.rs | 102 ++++++++ voxygen/src/scene/figure/mod.rs | 74 +++++- voxygen/src/session/mod.rs | 1 + 36 files changed, 875 insertions(+), 97 deletions(-) create mode 100644 assets/common/abilities/unique/birdlargefire/firebomb.ron create mode 100644 assets/common/abilities/unique/birdlargefire/fireshockwave.ron create mode 100644 assets/common/abilities/unique/birdlargefire/flamethrower.ron create mode 100644 assets/common/abilities/unique/birdlargefire/triplestrike.ron create mode 100644 assets/common/items/npc_weapons/unique/birdlargefire.ron create mode 100644 voxygen/anim/src/bird_large/shockwave.rs create mode 100644 voxygen/anim/src/bird_large/shoot.rs create mode 100644 voxygen/anim/src/bird_large/swim.rs diff --git a/assets/common/abilities/unique/birdlargefire/firebomb.ron b/assets/common/abilities/unique/birdlargefire/firebomb.ron new file mode 100644 index 0000000000..def79061ea --- /dev/null +++ b/assets/common/abilities/unique/birdlargefire/firebomb.ron @@ -0,0 +1,17 @@ +BasicRanged( + energy_cost: 0, + buildup_duration: 0.5, + recover_duration: 0.35, + projectile: Fireball( + damage: 100.0, + radius: 5.0, + energy_regen: 50, + ), + projectile_body: Object(BoltFire), + /*projectile_light: Some(LightEmitter { + col: (1.0, 0.75, 0.11).into(), + ..Default::default() + }),*/ + projectile_gravity: Some(Gravity(0.15)), + projectile_speed: 60.0, +) diff --git a/assets/common/abilities/unique/birdlargefire/fireshockwave.ron b/assets/common/abilities/unique/birdlargefire/fireshockwave.ron new file mode 100644 index 0000000000..e7e1f67a0f --- /dev/null +++ b/assets/common/abilities/unique/birdlargefire/fireshockwave.ron @@ -0,0 +1,15 @@ +Shockwave( + energy_cost: 600, + buildup_duration: 0.7, + swing_duration: 0.1, + recover_duration: 0.2, + damage: 200, + poise_damage: 0, + knockback: ( strength: 25.0, direction: Away), + shockwave_angle: 360.0, + shockwave_vertical_angle: 90.0, + shockwave_speed: 20.0, + shockwave_duration: 0.5, + requires_ground: false, + move_efficiency: 0.1, +) diff --git a/assets/common/abilities/unique/birdlargefire/flamethrower.ron b/assets/common/abilities/unique/birdlargefire/flamethrower.ron new file mode 100644 index 0000000000..4bf507fa86 --- /dev/null +++ b/assets/common/abilities/unique/birdlargefire/flamethrower.ron @@ -0,0 +1,14 @@ +BasicBeam( + buildup_duration: 0.4, + recover_duration: 0.25, + beam_duration: 0.5, + damage: 50, + tick_rate: 3.0, + range: 15.0, + max_angle: 22.5, + damage_effect: None, + energy_regen: 0, + energy_drain: 0, + orientation_behavior: Normal, + specifier: Flamethrower, +) \ No newline at end of file diff --git a/assets/common/abilities/unique/birdlargefire/triplestrike.ron b/assets/common/abilities/unique/birdlargefire/triplestrike.ron new file mode 100644 index 0000000000..2eaa09c043 --- /dev/null +++ b/assets/common/abilities/unique/birdlargefire/triplestrike.ron @@ -0,0 +1,53 @@ +ComboMelee( + stage_data: [ + ( + stage: 1, + base_damage: 100, + 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, + base_recover_duration: 0.3, + forward_movement: 2.0, + ), + ( + stage: 2, + base_damage: 80, + 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, + base_recover_duration: 0.3, + forward_movement: 1.5, + ), + ( + stage: 3, + base_damage: 130, + 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, + base_recover_duration: 0.3, + forward_movement: 1.5, + ), + ], + 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, +) diff --git a/assets/common/abilities/weapon_ability_manifest.ron b/assets/common/abilities/weapon_ability_manifest.ron index b952cbe08a..d990e18d61 100644 --- a/assets/common/abilities/weapon_ability_manifest.ron +++ b/assets/common/abilities/weapon_ability_manifest.ron @@ -212,6 +212,14 @@ secondary: "common.abilities.unique.birdlargebreathe.triplestrike", abilities: [], ), + Unique(BirdLargeFire): ( + primary: "common.abilities.unique.birdlargefire.flamethrower", + secondary: "common.abilities.unique.birdlargefire.triplestrike", + abilities: [ + (None, "common.abilities.staff.fireshockwave"), + (None, "common.abilities.staff.firebomb"), + ], + ), Debug: ( primary: "common.abilities.debug.forwardboost", secondary: "common.abilities.debug.upboost", diff --git a/assets/common/items/npc_weapons/unique/birdlargefire.ron b/assets/common/items/npc_weapons/unique/birdlargefire.ron new file mode 100644 index 0000000000..b092a15f0f --- /dev/null +++ b/assets/common/items/npc_weapons/unique/birdlargefire.ron @@ -0,0 +1,18 @@ +ItemDef( + name: "Bird Large Fire", + description: "testing123", + kind: Tool(( + kind: Unique(BirdLargeFire), + 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: [], +) \ No newline at end of file diff --git a/assets/voxygen/voxel/bird_large_central_manifest.ron b/assets/voxygen/voxel/bird_large_central_manifest.ron index c09bbae0b3..f8a0999986 100644 --- a/assets/voxygen/voxel/bird_large_central_manifest.ron +++ b/assets/voxygen/voxel/bird_large_central_manifest.ron @@ -1,53 +1,53 @@ ({ (Phoenix, Male): ( head: ( - offset: (-2.0, -1.0, -0.0), + offset: (-4.0, -4.0, 0.0), central: ("npc.phoenix.male.head"), ), beak: ( - offset: (-2.0, 0.0, -1.0), + offset: (-2.0, 0.0, -3.0), central: ("npc.phoenix.male.beak"), ), neck: ( - offset: (-2.0, -0.0, -0.0), + offset: (-4.0, 0.0, 0.0), central: ("npc.phoenix.male.neck"), ), chest: ( - offset: (-3.0, -5.5, -4.0), + offset: (-6.0, -9.5, -7.5), central: ("npc.phoenix.male.chest"), ), tail_front: ( - offset: (-2.0, -3.0, -3.0), + offset: (-10.0, -14.0, -3.0), central: ("npc.phoenix.male.tail_front"), ), tail_rear: ( - offset: (-1.0, -3.0, -3.0), + offset: (-9.0, -30.0, -2.0), central: ("npc.phoenix.male.tail_rear"), ) ), (Phoenix, Female): ( head: ( - offset: (-2.0, -1.0, -0.0), + offset: (-4.0, -4.0, 0.0), central: ("npc.phoenix.male.head"), ), beak: ( - offset: (-2.0, 0.0, -1.0), + offset: (-2.0, 0.0, -3.0), central: ("npc.phoenix.male.beak"), ), neck: ( - offset: (-2.0, -0.0, -0.0), + offset: (-4.0, 0.0, 0.0), central: ("npc.phoenix.male.neck"), ), chest: ( - offset: (-3.0, -5.5, -4.0), + offset: (-6.0, -9.5, -7.5), central: ("npc.phoenix.male.chest"), ), tail_front: ( - offset: (-2.0, -3.0, -3.0), + offset: (-10.0, -14.0, -3.0), central: ("npc.phoenix.male.tail_front"), ), tail_rear: ( - offset: (-1.0, -3.0, -3.0), + offset: (-9.0, -30.0, -2.0), central: ("npc.phoenix.male.tail_rear"), ) ), @@ -61,7 +61,7 @@ central: ("npc.cockatrice.male.beak"), ), neck: ( - offset: (-3.5, -0.0, -6.0), + offset: (-3.5, 0.0, -6.0), central: ("npc.cockatrice.male.neck"), ), chest: ( @@ -87,7 +87,7 @@ central: ("npc.cockatrice.male.beak"), ), neck: ( - offset: (-3.5, -0.0, -6.0), + offset: (-3.5, 0.0, -6.0), central: ("npc.cockatrice.male.neck"), ), chest: ( diff --git a/assets/voxygen/voxel/bird_large_lateral_manifest.ron b/assets/voxygen/voxel/bird_large_lateral_manifest.ron index f739190d0e..3eca741462 100644 --- a/assets/voxygen/voxel/bird_large_lateral_manifest.ron +++ b/assets/voxygen/voxel/bird_large_lateral_manifest.ron @@ -1,85 +1,85 @@ ({ (Phoenix, Male): ( wing_in_l: ( - offset: (-6.0, -5.0, -2.0), + offset: (-10.0, -12.0, -1.5), lateral: ("npc.phoenix.male.wing_in_r"), ), wing_in_r: ( - offset: (0.0, -5.0, -2.0), + offset: (0.0, -12.0, -1.5), lateral: ("npc.phoenix.male.wing_in_r"), ), wing_mid_l: ( - offset: (-2.5, -7.0, -2.0), + offset: (-7.0, -15.0, -0.5), lateral: ("npc.phoenix.male.wing_mid_r"), ), wing_mid_r: ( - offset: (-2.5, -7.0, -2.0), + offset: (0.0, -15.0, -0.5), lateral: ("npc.phoenix.male.wing_mid_r"), ), wing_out_l: ( - offset: (-9.0, -8.0, -2.0), + offset: (-18.0, -18.0, -2.0), lateral: ("npc.phoenix.male.wing_out_r"), ), wing_out_r: ( - offset: (0.0, -8.0, -2.0), + offset: (0.0, -18.0, -2.0), lateral: ("npc.phoenix.male.wing_out_r"), ), leg_l: ( - offset: (-1.5, -1.5, -1.5), + offset: (-4.0, -5.0, -4.5), lateral: ("npc.phoenix.male.leg_r"), ), leg_r: ( - offset: (-1.5, -1.5, -1.5), + offset: (-4.0, -5.0, -4.5), lateral: ("npc.phoenix.male.leg_r"), ), foot_l: ( - offset: (-1.5, -2.0, -4.0), + offset: (-3.5, -4.5, -9.0), lateral: ("npc.phoenix.male.foot_r"), ), foot_r: ( - offset: (-1.5, -2.0, -4.0), + offset: (-3.5, -4.5, -9.0), lateral: ("npc.phoenix.male.foot_r"), ) ), (Phoenix, Female): ( wing_in_l: ( - offset: (-6.0, -5.0, -2.0), + offset: (-10.0, -12.0, -1.5), lateral: ("npc.phoenix.male.wing_in_r"), ), wing_in_r: ( - offset: (0.0, -5.0, -2.0), + offset: (0.0, -12.0, -1.5), lateral: ("npc.phoenix.male.wing_in_r"), ), wing_mid_l: ( - offset: (-2.5, -7.0, -2.0), + offset: (-7.0, -15.0, -0.5), lateral: ("npc.phoenix.male.wing_mid_r"), ), wing_mid_r: ( - offset: (-2.5, -7.0, -2.0), + offset: (0.0, -15.0, -0.5), lateral: ("npc.phoenix.male.wing_mid_r"), ), wing_out_l: ( - offset: (-9.0, -8.0, -2.0), + offset: (-18.0, -18.0, -2.0), lateral: ("npc.phoenix.male.wing_out_r"), ), wing_out_r: ( - offset: (0.0, -8.0, -2.0), + offset: (0.0, -18.0, -2.0), lateral: ("npc.phoenix.male.wing_out_r"), ), leg_l: ( - offset: (-1.5, -1.5, -1.5), + offset: (-4.0, -5.0, -4.5), lateral: ("npc.phoenix.male.leg_r"), ), leg_r: ( - offset: (-1.5, -1.5, -1.5), + offset: (-4.0, -5.0, -4.5), lateral: ("npc.phoenix.male.leg_r"), ), foot_l: ( - offset: (-1.5, -2.0, -4.0), + offset: (-3.5, -4.5, -9.0), lateral: ("npc.phoenix.male.foot_r"), ), foot_r: ( - offset: (-1.5, -2.0, -4.0), + offset: (-3.5, -4.5, -9.0), lateral: ("npc.phoenix.male.foot_r"), ) ), diff --git a/assets/voxygen/voxel/npc/phoenix/male/beak.vox b/assets/voxygen/voxel/npc/phoenix/male/beak.vox index 3e741877d1..50b2c09489 100644 --- a/assets/voxygen/voxel/npc/phoenix/male/beak.vox +++ b/assets/voxygen/voxel/npc/phoenix/male/beak.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:87f096438df3e7962be2a18123c76e229877f7b0cc87cd464812041ee10185bb -size 26739 +oid sha256:5d9f547cf2cb789ca4a8daa442657a41db25a91fe08594c8970083bf8e7ce7bc +size 1248 diff --git a/assets/voxygen/voxel/npc/phoenix/male/chest.vox b/assets/voxygen/voxel/npc/phoenix/male/chest.vox index cda3cf94e9..26f09c93fe 100644 --- a/assets/voxygen/voxel/npc/phoenix/male/chest.vox +++ b/assets/voxygen/voxel/npc/phoenix/male/chest.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5e5532902efb783e2c98cc17d8e19264cadd3040d0805ba975db528476876140 -size 2120 +oid sha256:57e8567128e75585de5ed2ac048c2c570cbca4dc4e0d7c2a116c9767619498bb +size 8448 diff --git a/assets/voxygen/voxel/npc/phoenix/male/foot_r.vox b/assets/voxygen/voxel/npc/phoenix/male/foot_r.vox index bde15a7c43..076bc736c0 100644 --- a/assets/voxygen/voxel/npc/phoenix/male/foot_r.vox +++ b/assets/voxygen/voxel/npc/phoenix/male/foot_r.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b9f61f8cfac427534cd542007480b88893f669a95c12c69640abed0a83d7cf75 -size 1156 +oid sha256:8df02041d931946f0a053c24faebcacaccb5de301c42b4a32df06e798bad5d5b +size 1628 diff --git a/assets/voxygen/voxel/npc/phoenix/male/head.vox b/assets/voxygen/voxel/npc/phoenix/male/head.vox index 7ecd09f783..6db2f6d043 100644 --- a/assets/voxygen/voxel/npc/phoenix/male/head.vox +++ b/assets/voxygen/voxel/npc/phoenix/male/head.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8c0de42ab8cca96d8c3cea12a7bcf57229ffc5ab4eb7a7a31265129afc48fa7b -size 1408 +oid sha256:022ea7752438f738ebd2bb47f68ff827cb6c8f85fab05dc4286e01f31102e482 +size 3392 diff --git a/assets/voxygen/voxel/npc/phoenix/male/leg_r.vox b/assets/voxygen/voxel/npc/phoenix/male/leg_r.vox index 3399409d3a..e2f83fba5e 100644 --- a/assets/voxygen/voxel/npc/phoenix/male/leg_r.vox +++ b/assets/voxygen/voxel/npc/phoenix/male/leg_r.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d31f5f6553d9b9e1739c0afc4ebe2f3d84eadfa8f88eed13c6a74ad94ce3cec8 -size 1172 +oid sha256:59bec4734dd00e6fed8320b68e7f9a33be3956105ef78994d6ed689512e200e5 +size 2644 diff --git a/assets/voxygen/voxel/npc/phoenix/male/neck.vox b/assets/voxygen/voxel/npc/phoenix/male/neck.vox index 0fca2ba645..3c47ead3e8 100644 --- a/assets/voxygen/voxel/npc/phoenix/male/neck.vox +++ b/assets/voxygen/voxel/npc/phoenix/male/neck.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:62e1607fb522f218a0ed7273449bb08bf65a9b1b8265417768abc104461be4fe -size 1240 +oid sha256:091faef09b43d101a523ef5b46a74c4754057ecbf20d7ed3d9f8c609b7b4a7f1 +size 4536 diff --git a/assets/voxygen/voxel/npc/phoenix/male/tail_front.vox b/assets/voxygen/voxel/npc/phoenix/male/tail_front.vox index 96064d0c2e..62436cadc9 100644 --- a/assets/voxygen/voxel/npc/phoenix/male/tail_front.vox +++ b/assets/voxygen/voxel/npc/phoenix/male/tail_front.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c6e7de90bc10879198eacdd3a90c2b79555976e11bd22391cec26c68ced49ea6 -size 1136 +oid sha256:234c8e396b9cace8165d9118793817df5a8ff78140b700cb5b655ef5df326ac8 +size 2768 diff --git a/assets/voxygen/voxel/npc/phoenix/male/tail_rear.vox b/assets/voxygen/voxel/npc/phoenix/male/tail_rear.vox index c6520c5d71..3da4400bf0 100644 --- a/assets/voxygen/voxel/npc/phoenix/male/tail_rear.vox +++ b/assets/voxygen/voxel/npc/phoenix/male/tail_rear.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:23b717da1b45a0991c1da78baedff2f1d3b10ab8b8d1db56fa4151413428ddf0 -size 1120 +oid sha256:77ea457f336df7c1321c89279d061c2e278455743810027dbea19064f59b7c53 +size 3032 diff --git a/assets/voxygen/voxel/npc/phoenix/male/wing_in_r.vox b/assets/voxygen/voxel/npc/phoenix/male/wing_in_r.vox index de19144625..33ac105cb6 100644 --- a/assets/voxygen/voxel/npc/phoenix/male/wing_in_r.vox +++ b/assets/voxygen/voxel/npc/phoenix/male/wing_in_r.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ef70ed895f052308aea2b1d9302597d981a8b60ad581857663753aa8b27d9815 -size 1248 +oid sha256:0f0fc4eaebdd0dfbdceecd73f4bbef61df1ad41a4f02e74466fe38e4d73ef81a +size 1840 diff --git a/assets/voxygen/voxel/npc/phoenix/male/wing_mid_r.vox b/assets/voxygen/voxel/npc/phoenix/male/wing_mid_r.vox index cd9a41ac54..eaf3532512 100644 --- a/assets/voxygen/voxel/npc/phoenix/male/wing_mid_r.vox +++ b/assets/voxygen/voxel/npc/phoenix/male/wing_mid_r.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f1098fd85915c6ee7a96be7cbd2926c3b1a3565f87a23798cc0a564f3ead1d04 -size 1204 +oid sha256:476c07d679d1fe9ca356390ea16da02f843ed94637e767bff4fa2e875bc09ad4 +size 1748 diff --git a/assets/voxygen/voxel/npc/phoenix/male/wing_out_r.vox b/assets/voxygen/voxel/npc/phoenix/male/wing_out_r.vox index 46444d12ed..7d4af77900 100644 --- a/assets/voxygen/voxel/npc/phoenix/male/wing_out_r.vox +++ b/assets/voxygen/voxel/npc/phoenix/male/wing_out_r.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:70636fce4dd61aa20c975f43c516e4586afad18d47eca78d5125b1aee66f4e70 -size 1272 +oid sha256:085ca80b33c9b0962a4b8614fa17211abae68c0b13b9e7f0044e6109b3d8c429 +size 2648 diff --git a/common/src/comp/agent.rs b/common/src/comp/agent.rs index 68b30b314f..237a480119 100644 --- a/common/src/comp/agent.rs +++ b/common/src/comp/agent.rs @@ -38,6 +38,8 @@ pub enum Tactic { FixedTurret, RotatingTurret, Mindflayer, + BirdLargeBreathe, + BirdLargeFire, } #[derive(Copy, Clone, Debug, PartialEq)] @@ -247,7 +249,7 @@ impl<'a> From<&'a Body> for Psyche { }, Body::BipedSmall(_) => 0.5, Body::BirdMedium(_) => 0.5, - Body::BirdLarge(_) => 0.4, + Body::BirdLarge(_) => 0.9, Body::FishMedium(_) => 0.15, Body::FishSmall(_) => 0.0, Body::BipedLarge(_) => 1.0, diff --git a/common/src/comp/body.rs b/common/src/comp/body.rs index b48678bd18..2c00e94280 100644 --- a/common/src/comp/body.rs +++ b/common/src/comp/body.rs @@ -372,6 +372,10 @@ impl Body { biped_large::Species::Dullahan => 4000, _ => 3000, }, + Body::BirdLarge(body) => match body.species { + bird_large::Species::Cockatrice => 4000, + bird_large::Species::Phoenix => 6000, + }, Body::Humanoid(_) => 750, _ => 1000, } @@ -583,7 +587,7 @@ impl Body { pub fn flying_height(&self) -> f32 { match self { - Body::BirdLarge(_) => 30.0, + Body::BirdLarge(_) => 50.0, Body::BirdMedium(_) => 40.0, Body::Dragon(_) => 60.0, Body::Ship(ship::Body::DefaultAirship) => 60.0, diff --git a/common/src/comp/inventory/item/tool.rs b/common/src/comp/inventory/item/tool.rs index 13f7f2b56d..9bf489e6e8 100644 --- a/common/src/comp/inventory/item/tool.rs +++ b/common/src/comp/inventory/item/tool.rs @@ -442,4 +442,5 @@ pub enum UniqueKind { WoodenSpear, MindflayerStaff, BirdLargeBreathe, + BirdLargeFire, } diff --git a/common/src/comp/inventory/loadout_builder.rs b/common/src/comp/inventory/loadout_builder.rs index 3bba61a08d..e1fb785727 100644 --- a/common/src/comp/inventory/loadout_builder.rs +++ b/common/src/comp/inventory/loadout_builder.rs @@ -339,7 +339,11 @@ impl LoadoutBuilder { "common.items.npc_weapons.unique.birdlargebreathe", )); }, - _ => {}, + (bird_large::Species::Phoenix, _) => { + main_tool = Some(Item::new_from_asset_expect( + "common.items.npc_weapons.unique.birdlargefire", + )); + }, }, _ => {}, }; diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index 9b8e4f75de..8a30596df9 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -188,7 +188,7 @@ impl Body { pub fn fly_thrust(&self) -> Option { match self { Body::BirdMedium(_) => Some(GRAVITY * self.mass().0 * 2.0), - Body::BirdLarge(_) => Some(GRAVITY * self.mass().0 * 2.0), + Body::BirdLarge(_) => Some(GRAVITY * self.mass().0 * 3.0), Body::Dragon(_) => Some(200_000.0), Body::Ship(ship::Body::DefaultAirship) => Some(300_000.0), _ => None, diff --git a/server/src/sys/agent.rs b/server/src/sys/agent.rs index 68ba3e23a1..cc46acc65b 100644 --- a/server/src/sys/agent.rs +++ b/server/src/sys/agent.rs @@ -1538,6 +1538,8 @@ impl<'a> AgentData<'a> { Some(ToolKind::Unique(UniqueKind::TheropodBird)) => Tactic::Theropod, Some(ToolKind::Unique(UniqueKind::ObjectTurret)) => Tactic::Turret, Some(ToolKind::Unique(UniqueKind::MindflayerStaff)) => Tactic::Mindflayer, + Some(ToolKind::Unique(UniqueKind::BirdLargeBreathe)) => Tactic::BirdLargeBreathe, + Some(ToolKind::Unique(UniqueKind::BirdLargeFire)) => Tactic::BirdLargeFire, _ => Tactic::Melee, }; @@ -2587,6 +2589,224 @@ impl<'a> AgentData<'a> { controller.inputs.move_z = bearing.z; } }, + Tactic::BirdLargeFire => { + if self.physics_state.on_ground { + controller + .actions + .push(ControlAction::CancelInput(InputKind::Fly)); + if self.energy.current() > 600 && thread_rng().gen_bool(0.3) { + if thread_rng().gen_bool(0.99) { + if dist_sqrd < (2.5 * min_attack_dist).powi(2) + && self.energy.current() > 600 + { + dbg!("shockwave"); + controller + .actions + .push(ControlAction::basic_input(InputKind::Ability(0))); + } else { + if let Some((bearing, speed)) = agent.chaser.chase( + &*terrain, + self.pos.0, + self.vel.0, + tgt_pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..self.traversal_config + }, + ) { + if can_see_tgt(&*terrain, self.pos, tgt_pos, dist_sqrd) + && agent.action_timer > 1.0 + { + dbg!("fireball1"); + controller.inputs.move_dir = bearing + .xy() + .rotated_z(thread_rng().gen_range(-1.57..-0.5)) + .try_normalized() + .unwrap_or_else(Vec2::zero) + * speed; + controller.actions.push(ControlAction::basic_input( + InputKind::Ability(1), + )); + agent.action_timer = 0.0; + } else { + dbg!("walk to player1"); + controller.inputs.move_dir = bearing + .xy() + .try_normalized() + .unwrap_or_else(Vec2::zero) + * speed; + self.jump_if(controller, bearing.z > 1.5); + controller.inputs.move_z = bearing.z; + agent.action_timer += dt.0; + } + } + } + } else { + dbg!("fly"); + controller + .actions + .push(ControlAction::basic_input(InputKind::Fly)); + controller + .actions + .push(ControlAction::basic_input(InputKind::Jump)); + controller.inputs.move_z = 6.0; + } + } else { + if dist_sqrd < (2.0 * min_attack_dist).powi(2) { + dbg!("triple strike"); + controller + .actions + .push(ControlAction::basic_input(InputKind::Secondary)); + } else if let Some((bearing, speed)) = agent.chaser.chase( + &*terrain, + self.pos.0, + self.vel.0, + tgt_pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..self.traversal_config + }, + ) { + dbg!("walk to player2"); + controller.inputs.move_dir = + bearing.xy().try_normalized().unwrap_or_else(Vec2::zero) * speed; + self.jump_if(controller, bearing.z > 1.5); + controller.inputs.move_z = bearing.z; + } + } + } else { + if read_data + .terrain + .ray(self.pos.0, self.pos.0 - (Vec3::unit_z() * 5.0)) + .until(Block::is_solid) + .cast() + .1 + .map_or(true, |b| b.is_some()) + { + controller.inputs.move_z = 1.0; + } + if self.energy.current() > 50 { + if thread_rng().gen_bool(0.99) { + if dist_sqrd < (3.5 * min_attack_dist).powi(2) { + dbg!("flamethrower1"); + controller + .actions + .push(ControlAction::basic_input(InputKind::Primary)); + } else { + if let Some((bearing, speed)) = agent.chaser.chase( + &*terrain, + self.pos.0, + self.vel.0, + tgt_pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..self.traversal_config + }, + ) { + if can_see_tgt(&*terrain, self.pos, tgt_pos, dist_sqrd) { + if agent.action_timer > 3.0 { + dbg!("fireball2"); + controller.actions.push(ControlAction::basic_input( + InputKind::Ability(1), + )); + agent.action_timer = 0.0; + } else { + dbg!("fly to player1"); + controller.inputs.move_dir = bearing + .xy() + .rotated_z(thread_rng().gen_range(-1.57..-0.5)) + .try_normalized() + .unwrap_or_else(Vec2::zero) + * speed; + agent.action_timer += dt.0; + } + } else { + dbg!("fly to player2"); + controller.inputs.move_dir = bearing + .xy() + .try_normalized() + .unwrap_or_else(Vec2::zero) + * speed; + self.jump_if(controller, bearing.z > 1.5); + controller.inputs.move_z = bearing.z; + } + } + } + } else { + dbg!("land1"); + controller.inputs.move_z = -1.0; + controller + .actions + .push(ControlAction::CancelInput(InputKind::Fly)); + } + } else { + if dist_sqrd < (2.5 * min_attack_dist).powi(2) { + dbg!("land2"); + controller.inputs.move_z = -1.0; + controller + .actions + .push(ControlAction::CancelInput(InputKind::Fly)); + } else { + dbg!("fly to player"); + } + } + } + }, + Tactic::BirdLargeBreathe => { + if dist_sqrd < (2.5 * min_attack_dist).powi(2) { + controller.inputs.move_dir = Vec2::zero(); + controller + .actions + .push(ControlAction::basic_input(InputKind::Secondary)); + } else if dist_sqrd < (7.0 * min_attack_dist).powi(2) { + if agent.action_timer < 2.0 { + controller.inputs.move_dir = (tgt_pos.0 - self.pos.0) + .xy() + .rotated_z(0.47 * PI) + .try_normalized() + .unwrap_or_else(Vec2::unit_y); + controller + .actions + .push(ControlAction::basic_input(InputKind::Primary)); + agent.action_timer += dt.0; + } else if agent.action_timer < 4.0 { + controller.inputs.move_dir = (tgt_pos.0 - self.pos.0) + .xy() + .rotated_z(-0.47 * PI) + .try_normalized() + .unwrap_or_else(Vec2::unit_y); + controller + .actions + .push(ControlAction::basic_input(InputKind::Primary)); + agent.action_timer += dt.0; + } else if agent.action_timer < 6.0 { + controller + .actions + .push(ControlAction::basic_input(InputKind::Ability(0))); + agent.action_timer += dt.0; + } else { + agent.action_timer = 0.0; + } + } else if dist_sqrd < MAX_CHASE_DIST.powi(2) { + if let Some((bearing, speed)) = agent.chaser.chase( + &*terrain, + self.pos.0, + self.vel.0, + tgt_pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..self.traversal_config + }, + ) { + controller.inputs.move_dir = + bearing.xy().try_normalized().unwrap_or_else(Vec2::zero) * speed; + self.jump_if(controller, bearing.z > 1.5); + controller.inputs.move_z = bearing.z; + } + } else { + agent.target = None; + } + }, } } diff --git a/voxygen/anim/src/bird_large/alpha.rs b/voxygen/anim/src/bird_large/alpha.rs index 378851e192..013d8416c1 100644 --- a/voxygen/anim/src/bird_large/alpha.rs +++ b/voxygen/anim/src/bird_large/alpha.rs @@ -7,7 +7,7 @@ use common::states::utils::StageSection; pub struct AlphaAnimation; impl Animation for AlphaAnimation { - type Dependency = (Option, f32, f32); + type Dependency = (Option, Vec3, Vec3, f32, f32); type Skeleton = BirdLargeSkeleton; #[cfg(feature = "use-dyn-lib")] @@ -16,7 +16,7 @@ impl Animation for AlphaAnimation { #[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_alpha")] fn update_skeleton_inner( skeleton: &Self::Skeleton, - (stage_section, _global_time, _timer): Self::Dependency, + (stage_section, orientation, last_ori, _global_time, _timer): Self::Dependency, anim_time: f32, _rate: &mut f32, s_a: &SkeletonAttr, @@ -37,9 +37,22 @@ impl Animation for AlphaAnimation { let move1 = move1base * pullback; let move2 = move2base * pullback; + 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.beak.scale = Vec3::one() * 0.98; 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; @@ -51,7 +64,8 @@ impl Animation for AlphaAnimation { next.chest.orientation = Quaternion::rotation_x(move1 * 0.5 - move2 * 0.8); next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1); - next.neck.orientation = Quaternion::rotation_x(move1 * 0.5 - move2 * 0.8); + next.neck.orientation = Quaternion::rotation_x(move1 * 0.5 - move2 * 0.8) + * Quaternion::rotation_z(move1 * tilt * 1.5); next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); next.head.orientation = Quaternion::rotation_x(move1 * 0.5 - move2 * 0.8); diff --git a/voxygen/anim/src/bird_large/breathe.rs b/voxygen/anim/src/bird_large/breathe.rs index 96cc860f9b..904fc13d29 100644 --- a/voxygen/anim/src/bird_large/breathe.rs +++ b/voxygen/anim/src/bird_large/breathe.rs @@ -54,7 +54,6 @@ impl Animation for BreatheAnimation { next.head.scale = Vec3::one() * 0.98; next.neck.scale = Vec3::one() * 1.02; - next.beak.scale = Vec3::one() * 0.98; 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; diff --git a/voxygen/anim/src/bird_large/feed.rs b/voxygen/anim/src/bird_large/feed.rs index 9e61647de6..59daa60311 100644 --- a/voxygen/anim/src/bird_large/feed.rs +++ b/voxygen/anim/src/bird_large/feed.rs @@ -41,7 +41,6 @@ impl Animation for FeedAnimation { next.head.scale = Vec3::one() * 0.98; next.neck.scale = Vec3::one() * 1.02; - next.beak.scale = Vec3::one() * 0.98; 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; @@ -51,7 +50,7 @@ impl Animation for FeedAnimation { next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + wave_slow_cos * 0.06 - 1.8) * s_a.scaler / 8.0; - next.chest.orientation = Quaternion::rotation_x(-0.5); + next.chest.orientation = Quaternion::rotation_x(s_a.feed); next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1); next.neck.orientation = Quaternion::rotation_x(-0.2); @@ -72,11 +71,9 @@ impl Animation for FeedAnimation { 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(-s_a.wings_angle + 0.3 + wave_fast * 0.08) - * Quaternion::rotation_z(0.2); + Quaternion::rotation_y(-0.7 + wave_fast * 0.08) * Quaternion::rotation_z(0.2); next.wing_in_r.orientation = - Quaternion::rotation_y(s_a.wings_angle - 0.3 - wave_fast * 0.08) - * Quaternion::rotation_z(-0.2); + Quaternion::rotation_y(0.7 - wave_fast * 0.08) * Quaternion::rotation_z(-0.2); 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); diff --git a/voxygen/anim/src/bird_large/idle.rs b/voxygen/anim/src/bird_large/idle.rs index 1b4a8243df..ced671cb26 100644 --- a/voxygen/anim/src/bird_large/idle.rs +++ b/voxygen/anim/src/bird_large/idle.rs @@ -39,7 +39,6 @@ impl Animation for IdleAnimation { next.head.scale = Vec3::one() * 0.98; next.neck.scale = Vec3::one() * 1.02; - next.beak.scale = Vec3::one() * 0.98; 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; @@ -62,17 +61,17 @@ impl Animation for IdleAnimation { next.beak.orientation = Quaternion::rotation_x(wave_slow_cos * -0.02 - 0.02); 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.0); + next.tail_front.orientation = Quaternion::rotation_x(0.6); 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.0); + next.tail_rear.orientation = Quaternion::rotation_x(-0.2); 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(-1.0 + wave_slow_cos * 0.06) * Quaternion::rotation_z(0.2); + Quaternion::rotation_y(-0.8 + wave_slow_cos * 0.06) * Quaternion::rotation_z(0.2); next.wing_in_r.orientation = - Quaternion::rotation_y(1.0 - wave_slow_cos * 0.06) * Quaternion::rotation_z(-0.2); + Quaternion::rotation_y(0.8 - wave_slow_cos * 0.06) * Quaternion::rotation_z(-0.2); 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); @@ -81,8 +80,8 @@ impl Animation for IdleAnimation { 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) * Quaternion::rotation_z(0.2); - next.wing_out_r.orientation = Quaternion::rotation_y(0.2) * Quaternion::rotation_z(-0.2); + next.wing_out_l.orientation = Quaternion::rotation_y(-0.4) * Quaternion::rotation_z(0.2); + next.wing_out_r.orientation = Quaternion::rotation_y(0.4) * Quaternion::rotation_z(-0.2); next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0; next.leg_l.orientation = Quaternion::rotation_x(0.0); diff --git a/voxygen/anim/src/bird_large/mod.rs b/voxygen/anim/src/bird_large/mod.rs index eef7b229c6..55ac715d38 100644 --- a/voxygen/anim/src/bird_large/mod.rs +++ b/voxygen/anim/src/bird_large/mod.rs @@ -4,12 +4,16 @@ pub mod feed; pub mod fly; pub mod idle; pub mod run; +pub mod shockwave; +pub mod shoot; pub mod stunned; +pub mod swim; // Reexports pub use self::{ alpha::AlphaAnimation, breathe::BreatheAnimation, feed::FeedAnimation, fly::FlyAnimation, - idle::IdleAnimation, run::RunAnimation, stunned::StunnedAnimation, + idle::IdleAnimation, run::RunAnimation, shockwave::ShockwaveAnimation, shoot::ShootAnimation, + stunned::StunnedAnimation, swim::SwimAnimation, }; use super::{make_bone, vek::*, FigureBoneData, Skeleton}; @@ -104,7 +108,7 @@ pub struct SkeletonAttr { leg: (f32, f32, f32), foot: (f32, f32, f32), scaler: f32, - wings_angle: f32, + feed: f32, } impl<'a> std::convert::TryFrom<&'a comp::Body> for SkeletonAttr { @@ -133,7 +137,7 @@ impl Default for SkeletonAttr { leg: (0.0, 0.0, 0.0), foot: (0.0, 0.0, 0.0), scaler: 0.0, - wings_angle: 0.0, + feed: 0.0, } } } @@ -143,56 +147,56 @@ impl<'a> From<&'a Body> for SkeletonAttr { use comp::bird_large::Species::*; Self { chest: match (body.species, body.body_type) { - (Phoenix, _) => (2.5, 8.0), + (Phoenix, _) => (2.5, 16.0), (Cockatrice, _) => (2.5, 16.0), }, neck: match (body.species, body.body_type) { - (Phoenix, _) => (0.5, 3.0), + (Phoenix, _) => (2.5, -5.5), (Cockatrice, _) => (5.0, -1.5), }, head: match (body.species, body.body_type) { - (Phoenix, _) => (2.0, 2.0), + (Phoenix, _) => (6.0, 12.0), (Cockatrice, _) => (8.0, 4.5), }, beak: match (body.species, body.body_type) { - (Phoenix, _) => (2.0, 1.0), + (Phoenix, _) => (5.0, 3.0), (Cockatrice, _) => (2.0, -3.0), }, tail_front: match (body.species, body.body_type) { - (Phoenix, _) => (-5.5, -2.0), + (Phoenix, _) => (-9.5, -1.0), (Cockatrice, _) => (-5.0, -2.5), }, tail_rear: match (body.species, body.body_type) { - (Phoenix, _) => (-3.0, -3.0), + (Phoenix, _) => (-11.0, 0.0), (Cockatrice, _) => (-8.0, -3.0), }, wing_in: match (body.species, body.body_type) { - (Phoenix, _) => (3.0, 2.5, 3.0), + (Phoenix, _) => (3.0, 2.5, 2.0), (Cockatrice, _) => (3.5, 7.0, 3.5), }, wing_mid: match (body.species, body.body_type) { - (Phoenix, _) => (6.5, -1.0, 0.0), + (Phoenix, _) => (10.0, 1.0, 0.0), (Cockatrice, _) => (6.0, 0.0, 0.0), }, wing_out: match (body.species, body.body_type) { - (Phoenix, _) => (0.5, -1.0, 0.0), + (Phoenix, _) => (7.0, 2.0, 1.5), (Cockatrice, _) => (4.0, -1.0, 1.0), }, leg: match (body.species, body.body_type) { - (Phoenix, _) => (2.5, -2.5, -3.5), + (Phoenix, _) => (4.0, 1.5, 12.0), (Cockatrice, _) => (3.5, 2.5, 13.0), }, foot: match (body.species, body.body_type) { - (Phoenix, _) => (0.0, -0.5, -0.5), + (Phoenix, _) => (0.5, -0.5, -2.5), (Cockatrice, _) => (0.5, -3.0, -3.0), }, scaler: match (body.species, body.body_type) { (Phoenix, _) => (1.0), (Cockatrice, _) => (1.0), }, - wings_angle: match (body.species, body.body_type) { - (Phoenix, _) => (1.3), - (Cockatrice, _) => (0.9), + feed: match (body.species, body.body_type) { + (Phoenix, _) => (-0.65), + (Cockatrice, _) => (-0.5), }, } } diff --git a/voxygen/anim/src/bird_large/shockwave.rs b/voxygen/anim/src/bird_large/shockwave.rs new file mode 100644 index 0000000000..dfe31308ba --- /dev/null +++ b/voxygen/anim/src/bird_large/shockwave.rs @@ -0,0 +1,99 @@ +use super::{ + super::{vek::*, Animation}, + BirdLargeSkeleton, SkeletonAttr, +}; +use common::states::utils::StageSection; + +pub struct ShockwaveAnimation; + +impl Animation for ShockwaveAnimation { + #[allow(clippy::type_complexity)] + type Dependency = (f32, f32, Option); + type Skeleton = BirdLargeSkeleton; + + #[cfg(feature = "use-dyn-lib")] + const UPDATE_FN: &'static [u8] = b"bird_large_shockwave\0"; + + #[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_shockwave")] + fn update_skeleton_inner( + skeleton: &Self::Skeleton, + (_global_time, _velocity, stage_section): Self::Dependency, + anim_time: f32, + _rate: &mut f32, + s_a: &SkeletonAttr, + ) -> Self::Skeleton { + let mut next = (*skeleton).clone(); + + let (movement1base, movement2base, movement3, _twitch) = match stage_section { + Some(StageSection::Buildup) => (anim_time.powf(0.5), 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, 1.0), + _ => (0.0, 0.0, 0.0, 0.0), + }; + + let pullback = 1.0 - movement3; + + 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 + movement1abs * 1.5) * s_a.scaler / 8.0; + next.chest.orientation = Quaternion::rotation_x(movement1abs * 1.0 + movement2abs * -1.0); + + next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1); + next.neck.orientation = Quaternion::rotation_x(-0.2); + + next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); + next.head.orientation = Quaternion::rotation_x(wave_slow_cos * 0.01); + + next.beak.position = Vec3::new(0.0, s_a.beak.0, s_a.beak.1); + next.beak.orientation = Quaternion::rotation_x(wave_slow_cos * -0.02 - 0.02); + + 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); + 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); + + 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.6 + movement2abs * -1.6) + * Quaternion::rotation_z(0.2 + movement1abs * -0.8); + next.wing_in_r.orientation = + Quaternion::rotation_y(0.8 + movement1abs * -1.6 + movement2abs * 1.6) + * Quaternion::rotation_z(-0.2 + movement1abs * 0.8); + + 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.4) * Quaternion::rotation_z(0.2); + next.wing_out_r.orientation = Quaternion::rotation_y(0.4) * Quaternion::rotation_z(-0.2); + + next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0; + next.leg_l.orientation = Quaternion::rotation_x(0.0); + next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0; + next.leg_r.orientation = Quaternion::rotation_x(0.0); + + next.foot_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2); + next.foot_l.orientation = Quaternion::rotation_x(0.0); + next.foot_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2); + next.foot_r.orientation = Quaternion::rotation_x(0.0); + + next + } +} diff --git a/voxygen/anim/src/bird_large/shoot.rs b/voxygen/anim/src/bird_large/shoot.rs new file mode 100644 index 0000000000..16a67df318 --- /dev/null +++ b/voxygen/anim/src/bird_large/shoot.rs @@ -0,0 +1,136 @@ +use super::{ + super::{vek::*, Animation}, + BirdLargeSkeleton, SkeletonAttr, +}; +use common::{states::utils::StageSection, util::Dir}; + +pub struct ShootAnimation; + +type ShootAnimationDependency = ( + f32, + f32, + Vec3, + Vec3, + Option, + f32, + Dir, + bool, +); + +impl Animation for ShootAnimation { + type Dependency = ShootAnimationDependency; + type Skeleton = BirdLargeSkeleton; + + #[cfg(feature = "use-dyn-lib")] + const UPDATE_FN: &'static [u8] = b"bird_large_shoot\0"; + + #[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_shoot")] + fn update_skeleton_inner( + skeleton: &Self::Skeleton, + (_velocity, global_time, orientation, last_ori, stage_section, timer, look_dir, on_ground): Self::Dependency, + anim_time: f32, + _rate: &mut f32, + s_a: &SkeletonAttr, + ) -> Self::Skeleton { + 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, 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.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.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); + next.head.orientation = + Quaternion::rotation_x(movement1abs * 0.5 - movement2abs * 0.5 + 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.chest.orientation = + Quaternion::rotation_x(movement1abs * 0.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_y(-1.0 + movement1abs * 0.8 - movement2abs * 0.4) + * Quaternion::rotation_z(0.2 - movement1abs * 0.8 + movement2abs * 0.4); + next.wing_in_r.orientation = + Quaternion::rotation_y(1.0 - movement1abs * 0.8 + movement2abs * 0.4) + * Quaternion::rotation_z(-0.2 + movement1abs * 0.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) * 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) * Quaternion::rotation_z(0.2); + next.wing_out_r.orientation = + Quaternion::rotation_y(0.2) * 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 { + 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.chest.orientation = + Quaternion::rotation_x(movement1abs * 0.1 - movement2abs * 0.1) + * Quaternion::rotation_y(tilt * 1.8); + } + + next + } +} diff --git a/voxygen/anim/src/bird_large/stunned.rs b/voxygen/anim/src/bird_large/stunned.rs index 62a1905a7e..5377b3cdbb 100644 --- a/voxygen/anim/src/bird_large/stunned.rs +++ b/voxygen/anim/src/bird_large/stunned.rs @@ -39,7 +39,6 @@ impl Animation for StunnedAnimation { next.head.scale = Vec3::one() * 0.98; next.neck.scale = Vec3::one() * 1.02; - next.beak.scale = Vec3::one() * 0.98; 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; diff --git a/voxygen/anim/src/bird_large/swim.rs b/voxygen/anim/src/bird_large/swim.rs new file mode 100644 index 0000000000..d81cc092d1 --- /dev/null +++ b/voxygen/anim/src/bird_large/swim.rs @@ -0,0 +1,102 @@ +use super::{ + super::{vek::*, Animation}, + BirdLargeSkeleton, SkeletonAttr, +}; +use std::ops::Mul; + +pub struct SwimAnimation; + +impl Animation for SwimAnimation { + #[allow(clippy::type_complexity)] + type Dependency = (Vec3, Vec3, Vec3, f32); + type Skeleton = BirdLargeSkeleton; + + #[cfg(feature = "use-dyn-lib")] + const UPDATE_FN: &'static [u8] = b"bird_large_swim\0"; + + #[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_swim")] + fn update_skeleton_inner( + skeleton: &Self::Skeleton, + (_velocity, _orientation, _last_ori, global_time): Self::Dependency, + anim_time: f32, + _rate: &mut f32, + s_a: &SkeletonAttr, + ) -> Self::Skeleton { + let mut next = (*skeleton).clone(); + + let duck_head_look = Vec2::new( + (global_time / 2.0 + anim_time / 8.0) + .floor() + .mul(7331.0) + .sin() + * 0.5, + (global_time / 2.0 + anim_time / 8.0) + .floor() + .mul(1337.0) + .sin() + * 0.25, + ); + let wave_slow_cos = (anim_time * 4.5).cos(); + + let wave_fast = (anim_time * 6.0).sin(); + let wave_fast_cos = (anim_time * 6.0).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 + 1.5) + * s_a.scaler + / 8.0; + next.chest.orientation = Quaternion::rotation_x(0.0); + + next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1); + next.neck.orientation = Quaternion::rotation_x(0.0); + + next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); + next.head.orientation = Quaternion::rotation_z(duck_head_look.x) + * Quaternion::rotation_x(-duck_head_look.y.abs() + wave_slow_cos * 0.01); + + next.beak.position = Vec3::new(0.0, s_a.beak.0, s_a.beak.1); + next.beak.orientation = Quaternion::rotation_x(wave_slow_cos * -0.02 - 0.02); + + 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); + 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); + + 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 + wave_slow_cos * 0.06) * Quaternion::rotation_z(0.2); + next.wing_in_r.orientation = + Quaternion::rotation_y(0.8 - wave_slow_cos * 0.06) * Quaternion::rotation_z(-0.2); + + 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.4) * Quaternion::rotation_z(0.2); + next.wing_out_r.orientation = Quaternion::rotation_y(0.4) * Quaternion::rotation_z(-0.2); + + next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0; + next.leg_l.orientation = Quaternion::rotation_x(-0.8 + wave_fast * 0.5); + next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0; + next.leg_r.orientation = Quaternion::rotation_x(-0.8 + wave_fast_cos * 0.5); + + next.foot_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2); + next.foot_l.orientation = Quaternion::rotation_x(0.0); + next.foot_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2); + next.foot_r.orientation = Quaternion::rotation_x(0.0); + + next + } +} diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index baaacc7f60..6e63d4547b 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -3332,6 +3332,20 @@ impl FigureMgr { &mut state_animation_rate, skeleton_attr, ), + // Swim + (_, true, _) => anim::bird_large::SwimAnimation::update_skeleton( + &BirdLargeSkeleton::default(), + ( + rel_vel, + // TODO: Update to use the quaternion. + ori * anim::vek::Vec3::::unit_y(), + state.last_ori * anim::vek::Vec3::::unit_y(), + time, + ), + state.state_time, + &mut state_animation_rate, + skeleton_attr, + ), // TODO! _ => anim::bird_large::IdleAnimation::update_skeleton( &BirdLargeSkeleton::default(), @@ -3407,7 +3421,65 @@ impl FigureMgr { anim::bird_large::AlphaAnimation::update_skeleton( &target_base, - (Some(s.stage_section), time, state.state_time), + ( + Some(s.stage_section), + ori * anim::vek::Vec3::::unit_y(), + state.last_ori * anim::vek::Vec3::::unit_y(), + time, + state.state_time, + ), + stage_progress, + &mut state_animation_rate, + skeleton_attr, + ) + }, + CharacterState::BasicRanged(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::Recover => { + stage_time / s.static_data.recover_duration.as_secs_f32() + }, + + _ => 0.0, + }; + anim::bird_large::ShootAnimation::update_skeleton( + &target_base, + ( + rel_vel.magnitude(), + time, + ori * anim::vek::Vec3::::unit_y(), + state.last_ori * anim::vek::Vec3::::unit_y(), + Some(s.stage_section), + state.state_time, + look_dir, + physics.on_ground, + ), + stage_progress, + &mut state_animation_rate, + skeleton_attr, + ) + }, + CharacterState::Shockwave(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::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::ShockwaveAnimation::update_skeleton( + &target_base, + (time, rel_vel.magnitude(), Some(s.stage_section)), stage_progress, &mut state_animation_rate, skeleton_attr, diff --git a/voxygen/src/session/mod.rs b/voxygen/src/session/mod.rs index fa1b98732c..a0e9895f88 100644 --- a/voxygen/src/session/mod.rs +++ b/voxygen/src/session/mod.rs @@ -522,6 +522,7 @@ impl PlayState for SessionState { select_pos, target_entity.map(|t| t.0), ); + dbg!(self.key_state.fly); }, GameInput::Climb => { self.key_state.climb_up = state;