diff --git a/assets/common/abilities/ability_set_manifest.ron b/assets/common/abilities/ability_set_manifest.ron index 5f42e92da1..1b742e8ef1 100644 --- a/assets/common/abilities/ability_set_manifest.ron +++ b/assets/common/abilities/ability_set_manifest.ron @@ -197,7 +197,7 @@ secondary: Simple(None, "common.abilities.hammer.wide_wallop"), abilities: [ Simple(Hammer(ScornfulSwipe), "common.abilities.hammer.scornful_swipe"), - // Simple(Hammer(Tremor), "common.abilities.hammer.tremor"), + Simple(Hammer(Tremor), "common.abilities.hammer.tremor"), // Simple(Hammer(VigorousBash), "common.abilities.hammer.vigorous_bash"), // Simple(Hammer(Retaliate), "common.abilities.hammer.retaliate"), // Simple(Hammer(SpineCracker), "common.abilities.hammer.spine_cracker"), diff --git a/assets/common/abilities/custom/birdlargefire/fireshockwave.ron b/assets/common/abilities/custom/birdlargefire/fireshockwave.ron index 9f627d5c96..e4736430d7 100644 --- a/assets/common/abilities/custom/birdlargefire/fireshockwave.ron +++ b/assets/common/abilities/custom/birdlargefire/fireshockwave.ron @@ -15,4 +15,6 @@ Shockwave( damage_kind: Energy, specifier: Fire, ori_rate: 1.0, + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/custom/claysteed/shockwave.ron b/assets/common/abilities/custom/claysteed/shockwave.ron index 2c9c1efe13..e7a491d988 100644 --- a/assets/common/abilities/custom/claysteed/shockwave.ron +++ b/assets/common/abilities/custom/claysteed/shockwave.ron @@ -15,4 +15,6 @@ Shockwave( damage_kind: Crushing, specifier: Ground, ori_rate: 1.0, + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/custom/cloudwyvern/lightningshockwave.ron b/assets/common/abilities/custom/cloudwyvern/lightningshockwave.ron index f50fc14f98..cf7a87f6a3 100644 --- a/assets/common/abilities/custom/cloudwyvern/lightningshockwave.ron +++ b/assets/common/abilities/custom/cloudwyvern/lightningshockwave.ron @@ -21,4 +21,6 @@ Shockwave( strength: Value(0.3), chance: 1.0, ))), + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/custom/coralgolem/shockwave.ron b/assets/common/abilities/custom/coralgolem/shockwave.ron index 02979caa9c..2728da02b5 100644 --- a/assets/common/abilities/custom/coralgolem/shockwave.ron +++ b/assets/common/abilities/custom/coralgolem/shockwave.ron @@ -15,4 +15,6 @@ Shockwave( damage_kind: Crushing, specifier: Water, ori_rate: 1.0, + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/custom/cyclops/hammer_shockwave.ron b/assets/common/abilities/custom/cyclops/hammer_shockwave.ron index ffd8ed3724..c749c6265f 100644 --- a/assets/common/abilities/custom/cyclops/hammer_shockwave.ron +++ b/assets/common/abilities/custom/cyclops/hammer_shockwave.ron @@ -15,4 +15,6 @@ Shockwave( damage_kind: Piercing, specifier: Ground, ori_rate: 1.0, + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/custom/dagon/steamwave.ron b/assets/common/abilities/custom/dagon/steamwave.ron index acf6cb6b39..3920651b92 100644 --- a/assets/common/abilities/custom/dagon/steamwave.ron +++ b/assets/common/abilities/custom/dagon/steamwave.ron @@ -15,4 +15,6 @@ Shockwave( damage_kind: Crushing, specifier: Steam, ori_rate: 1.0, + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/custom/dwarves/flamekeeper/lavawave.ron b/assets/common/abilities/custom/dwarves/flamekeeper/lavawave.ron index d63306dd5e..15c8d00237 100644 --- a/assets/common/abilities/custom/dwarves/flamekeeper/lavawave.ron +++ b/assets/common/abilities/custom/dwarves/flamekeeper/lavawave.ron @@ -15,4 +15,6 @@ Shockwave( damage_kind: Crushing, specifier: Fire, ori_rate: 1.0, + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/custom/dwarves/snaretongue/wave.ron b/assets/common/abilities/custom/dwarves/snaretongue/wave.ron index 700c67ac2c..92194301f8 100644 --- a/assets/common/abilities/custom/dwarves/snaretongue/wave.ron +++ b/assets/common/abilities/custom/dwarves/snaretongue/wave.ron @@ -15,4 +15,6 @@ Shockwave( damage_kind: Crushing, specifier: Water, ori_rate: 1.0, + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/custom/flamewyvern/fireshockwave.ron b/assets/common/abilities/custom/flamewyvern/fireshockwave.ron index 3ef4ef8934..9210d61279 100644 --- a/assets/common/abilities/custom/flamewyvern/fireshockwave.ron +++ b/assets/common/abilities/custom/flamewyvern/fireshockwave.ron @@ -21,4 +21,6 @@ Shockwave( strength: DamageFraction(0.3), chance: 1.0, ))), + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/custom/frostwyvern/iceshockwave.ron b/assets/common/abilities/custom/frostwyvern/iceshockwave.ron index 277ab59e64..16fff38046 100644 --- a/assets/common/abilities/custom/frostwyvern/iceshockwave.ron +++ b/assets/common/abilities/custom/frostwyvern/iceshockwave.ron @@ -21,4 +21,6 @@ Shockwave( strength: Value(0.3), chance: 1.0, ))), + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/custom/gigas_frost/flashfreeze.ron b/assets/common/abilities/custom/gigas_frost/flashfreeze.ron index db863fd963..75394151c6 100644 --- a/assets/common/abilities/custom/gigas_frost/flashfreeze.ron +++ b/assets/common/abilities/custom/gigas_frost/flashfreeze.ron @@ -21,4 +21,6 @@ Shockwave( strength: Value(3.0), chance: 1.0, ))), + timing: PostBuildup, + emit_outcome: true, ) \ No newline at end of file diff --git a/assets/common/abilities/custom/gravewarden/shockwave.ron b/assets/common/abilities/custom/gravewarden/shockwave.ron index b6ff6a5f7c..0959389f5b 100644 --- a/assets/common/abilities/custom/gravewarden/shockwave.ron +++ b/assets/common/abilities/custom/gravewarden/shockwave.ron @@ -15,4 +15,6 @@ Shockwave( damage_kind: Crushing, specifier: Ground, ori_rate: 1.0, + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/custom/jiangshi/poisonshockwave.ron b/assets/common/abilities/custom/jiangshi/poisonshockwave.ron index e7a0691fbb..ac9779e551 100644 --- a/assets/common/abilities/custom/jiangshi/poisonshockwave.ron +++ b/assets/common/abilities/custom/jiangshi/poisonshockwave.ron @@ -21,4 +21,6 @@ Shockwave( strength: DamageFraction(0.6), chance: 1.0, ))), + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/custom/roshwalr/freezeshockwave.ron b/assets/common/abilities/custom/roshwalr/freezeshockwave.ron index b9e9feaa52..f10c63b180 100644 --- a/assets/common/abilities/custom/roshwalr/freezeshockwave.ron +++ b/assets/common/abilities/custom/roshwalr/freezeshockwave.ron @@ -21,4 +21,6 @@ Shockwave( strength: DamageFraction(0.06), chance: 1, ))), + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/custom/seawyvern/inkshockwave.ron b/assets/common/abilities/custom/seawyvern/inkshockwave.ron index 4a7ecf8ce1..7814f35a20 100644 --- a/assets/common/abilities/custom/seawyvern/inkshockwave.ron +++ b/assets/common/abilities/custom/seawyvern/inkshockwave.ron @@ -21,5 +21,7 @@ Shockwave( strength: Value(0.3), chance: 1.0, ))), + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/custom/stonegolemfist/shockwave.ron b/assets/common/abilities/custom/stonegolemfist/shockwave.ron index 52fe37b10c..4fa1f98df5 100644 --- a/assets/common/abilities/custom/stonegolemfist/shockwave.ron +++ b/assets/common/abilities/custom/stonegolemfist/shockwave.ron @@ -15,4 +15,6 @@ Shockwave( damage_kind: Crushing, specifier: Ground, ori_rate: 1.0, + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/custom/tidalwarrior/totem_wave.ron b/assets/common/abilities/custom/tidalwarrior/totem_wave.ron index 81cc0a58ac..a260075e9c 100644 --- a/assets/common/abilities/custom/tidalwarrior/totem_wave.ron +++ b/assets/common/abilities/custom/tidalwarrior/totem_wave.ron @@ -15,4 +15,6 @@ Shockwave( damage_kind: Crushing, specifier: Water, ori_rate: 0.0, + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/custom/treant_sapling/shockwave.ron b/assets/common/abilities/custom/treant_sapling/shockwave.ron index eaa8ae1ce0..aeae667faa 100644 --- a/assets/common/abilities/custom/treant_sapling/shockwave.ron +++ b/assets/common/abilities/custom/treant_sapling/shockwave.ron @@ -15,4 +15,6 @@ Shockwave( damage_kind: Crushing, specifier: Ground, ori_rate: 1.0, + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/custom/wealdwyvern/poisonshockwave.ron b/assets/common/abilities/custom/wealdwyvern/poisonshockwave.ron index 08e6a7ec55..080b13216d 100644 --- a/assets/common/abilities/custom/wealdwyvern/poisonshockwave.ron +++ b/assets/common/abilities/custom/wealdwyvern/poisonshockwave.ron @@ -21,5 +21,7 @@ Shockwave( strength: DamageFraction(0.3), chance: 1.0, ))), + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/custom/woodgolem/shockwave.ron b/assets/common/abilities/custom/woodgolem/shockwave.ron index 414f1db81e..8ac1c5d64f 100644 --- a/assets/common/abilities/custom/woodgolem/shockwave.ron +++ b/assets/common/abilities/custom/woodgolem/shockwave.ron @@ -15,4 +15,6 @@ Shockwave( damage_kind: Crushing, specifier: Ground, ori_rate: 1.0, + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/custom/yeti/icespikes.ron b/assets/common/abilities/custom/yeti/icespikes.ron index b70e2a7550..0a70a8f293 100644 --- a/assets/common/abilities/custom/yeti/icespikes.ron +++ b/assets/common/abilities/custom/yeti/icespikes.ron @@ -21,4 +21,6 @@ Shockwave( strength: DamageFraction(0.1), chance: 0.1, ))), + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/gnarling/chieftain/fireshockwave.ron b/assets/common/abilities/gnarling/chieftain/fireshockwave.ron index 81bb67dcca..26ce3ab2e9 100644 --- a/assets/common/abilities/gnarling/chieftain/fireshockwave.ron +++ b/assets/common/abilities/gnarling/chieftain/fireshockwave.ron @@ -15,4 +15,6 @@ Shockwave( damage_kind: Energy, specifier: Fire, ori_rate: 1.0, + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/common/abilities/hammer/tremor.ron b/assets/common/abilities/hammer/tremor.ron new file mode 100644 index 0000000000..529c007614 --- /dev/null +++ b/assets/common/abilities/hammer/tremor.ron @@ -0,0 +1,20 @@ +Shockwave( + energy_cost: 0, + buildup_duration: 0.4, + swing_duration: 0.3, + recover_duration: 0.3, + damage: 30, + poise_damage: 40, + knockback: (strength: 15.0, direction: Up), + shockwave_angle: 60.0, + shockwave_vertical_angle: 45.0, + shockwave_speed: 10.0, + shockwave_duration: 1.5, + dodgeable: Jump, + move_efficiency: 0.0, + damage_kind: Crushing, + specifier: Ground, + ori_rate: 0.2, + timing: PostAction, + emit_outcome: false, +) \ No newline at end of file diff --git a/assets/common/abilities/staff/fireshockwave.ron b/assets/common/abilities/staff/fireshockwave.ron index 913dc7939b..944e28d628 100644 --- a/assets/common/abilities/staff/fireshockwave.ron +++ b/assets/common/abilities/staff/fireshockwave.ron @@ -15,4 +15,6 @@ Shockwave( damage_kind: Energy, specifier: Fire, ori_rate: 1.0, + timing: PostBuildup, + emit_outcome: true, ) diff --git a/assets/voxygen/element/skills/hammer/tremor.png b/assets/voxygen/element/skills/hammer/tremor.png new file mode 100644 index 0000000000..601a212b96 --- /dev/null +++ b/assets/voxygen/element/skills/hammer/tremor.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:999897075eca91a21a874c5165090b6d6955dbf3026b3fe460b1095f57519bd0 +size 1058 diff --git a/assets/voxygen/i18n/en/hud/ability.ftl b/assets/voxygen/i18n/en/hud/ability.ftl index 25e44c77ee..c03d11fb8b 100644 --- a/assets/voxygen/i18n/en/hud/ability.ftl +++ b/assets/voxygen/i18n/en/hud/ability.ftl @@ -386,3 +386,6 @@ common-abilities-hammer-wide_wallop = Wide Wallop common-abilities-hammer-scornful_swipe = Scornful Swipe .desc = Bolster your fortitude and stamina by taunting your enemies before striking at them. If you fall to an enemy they become empowered. +common-abilities-hammer-tremor = Tremor + .desc = + Strike the earth with enough force that the ground beneath your foes trembles. diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index 92ec1b96b3..445b151c72 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -933,6 +933,8 @@ pub enum CharacterAbility { specifier: comp::shockwave::FrontendSpecifier, ori_rate: f32, damage_effect: Option, + timing: shockwave::Timing, + emit_outcome: bool, #[serde(default)] meta: AbilityMeta, }, @@ -1532,6 +1534,8 @@ impl CharacterAbility { specifier: _, ori_rate: _, ref mut damage_effect, + timing: _, + emit_outcome: _, meta: _, } => { *buildup_duration /= stats.speed; @@ -2572,6 +2576,8 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { specifier, ori_rate, damage_effect, + timing, + emit_outcome, meta: _, } => CharacterState::Shockwave(shockwave::Data { static_data: shockwave::StaticData { @@ -2592,6 +2598,8 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { damage_kind: *damage_kind, specifier: *specifier, ori_rate: *ori_rate, + timing: *timing, + emit_outcome: *emit_outcome, }, timer: Duration::default(), stage_section: StageSection::Buildup, diff --git a/common/src/states/shockwave.rs b/common/src/states/shockwave.rs index 4614ca6ab0..fd79076a8e 100644 --- a/common/src/states/shockwave.rs +++ b/common/src/states/shockwave.rs @@ -53,8 +53,12 @@ pub struct StaticData { pub damage_kind: DamageKind, /// Used to specify the shockwave to the frontend pub specifier: shockwave::FrontendSpecifier, + /// Controls outcome emission + pub emit_outcome: bool, /// How fast enemy can rotate pub ori_rate: f32, + /// Timing of shockwave + pub timing: Timing, } #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -85,50 +89,9 @@ impl CharacterBehavior for Data { }); } else { // Attack - let poise = AttackEffect::new( - Some(GroupTarget::OutOfGroup), - CombatEffect::Poise(self.static_data.poise_damage), - ) - .with_requirement(CombatRequirement::AnyDamage); - let knockback = AttackEffect::new( - Some(GroupTarget::OutOfGroup), - CombatEffect::Knockback(self.static_data.knockback), - ) - .with_requirement(CombatRequirement::AnyDamage); - let mut damage = AttackDamage::new( - Damage { - source: DamageSource::Shockwave, - kind: self.static_data.damage_kind, - value: self.static_data.damage, - }, - Some(GroupTarget::OutOfGroup), - rand::random(), - ); - if let Some(effect) = self.static_data.damage_effect { - damage = damage.with_effect(effect); + if matches!(self.static_data.timing, Timing::PostBuildup) { + self.attack(data, output_events); } - let precision_mult = combat::compute_precision_mult(data.inventory, data.msm); - let attack = Attack::default() - .with_damage(damage) - .with_precision(precision_mult) - .with_effect(poise) - .with_effect(knockback) - .with_combo_increment(); - let properties = shockwave::Properties { - angle: self.static_data.shockwave_angle, - vertical_angle: self.static_data.shockwave_vertical_angle, - speed: self.static_data.shockwave_speed, - duration: self.static_data.shockwave_duration, - attack, - dodgeable: self.static_data.dodgeable, - owner: Some(*data.uid), - specifier: self.static_data.specifier, - }; - output_events.emit_server(ShockwaveEvent { - properties, - pos: *data.pos, - ori: *data.ori, - }); // Transitions to swing update.character = CharacterState::Shockwave(Data { @@ -146,43 +109,56 @@ impl CharacterBehavior for Data { ..*self }); // Send local event used for frontend shenanigans - match self.static_data.specifier { - shockwave::FrontendSpecifier::IceSpikes => { - output_events.emit_local(LocalEvent::CreateOutcome( - Outcome::FlashFreeze { - pos: data.pos.0 - + *data.ori.look_dir() * (data.body.max_radius()), - }, - )); - }, - shockwave::FrontendSpecifier::Ground => { - output_events.emit_local(LocalEvent::CreateOutcome( - Outcome::GroundSlam { - pos: data.pos.0 - + *data.ori.look_dir() * (data.body.max_radius()), - }, - )); - }, - shockwave::FrontendSpecifier::Steam => { - output_events.emit_local(LocalEvent::CreateOutcome(Outcome::Steam { - pos: data.pos.0 + *data.ori.look_dir() * (data.body.max_radius()), - })); - }, - shockwave::FrontendSpecifier::Fire => { - output_events.emit_local(LocalEvent::CreateOutcome( - Outcome::FireShockwave { - pos: data.pos.0 - + *data.ori.look_dir() * (data.body.max_radius()), - }, - )); - }, - _ => { - output_events.emit_local(LocalEvent::CreateOutcome(Outcome::Swoosh { - pos: data.pos.0 + *data.ori.look_dir() * (data.body.max_radius()), - })); - }, + if self.static_data.emit_outcome { + match self.static_data.specifier { + shockwave::FrontendSpecifier::IceSpikes => { + output_events.emit_local(LocalEvent::CreateOutcome( + Outcome::FlashFreeze { + pos: data.pos.0 + + *data.ori.look_dir() * (data.body.max_radius()), + }, + )); + }, + shockwave::FrontendSpecifier::Ground => { + output_events.emit_local(LocalEvent::CreateOutcome( + Outcome::GroundSlam { + pos: data.pos.0 + + *data.ori.look_dir() * (data.body.max_radius()), + }, + )); + }, + shockwave::FrontendSpecifier::Steam => { + output_events.emit_local(LocalEvent::CreateOutcome( + Outcome::Steam { + pos: data.pos.0 + + *data.ori.look_dir() * (data.body.max_radius()), + }, + )); + }, + shockwave::FrontendSpecifier::Fire => { + output_events.emit_local(LocalEvent::CreateOutcome( + Outcome::FireShockwave { + pos: data.pos.0 + + *data.ori.look_dir() * (data.body.max_radius()), + }, + )); + }, + _ => { + output_events.emit_local(LocalEvent::CreateOutcome( + Outcome::Swoosh { + pos: data.pos.0 + + *data.ori.look_dir() * (data.body.max_radius()), + }, + )); + }, + } } } else { + // Attack + if matches!(self.static_data.timing, Timing::PostAction) { + self.attack(data, output_events); + } + // Transitions to recover update.character = CharacterState::Shockwave(Data { timer: Duration::default(), @@ -215,3 +191,58 @@ impl CharacterBehavior for Data { update } } + +impl Data { + fn attack(&self, data: &JoinData, output_events: &mut OutputEvents) { + let poise = AttackEffect::new( + Some(GroupTarget::OutOfGroup), + CombatEffect::Poise(self.static_data.poise_damage), + ) + .with_requirement(CombatRequirement::AnyDamage); + let knockback = AttackEffect::new( + Some(GroupTarget::OutOfGroup), + CombatEffect::Knockback(self.static_data.knockback), + ) + .with_requirement(CombatRequirement::AnyDamage); + let mut damage = AttackDamage::new( + Damage { + source: DamageSource::Shockwave, + kind: self.static_data.damage_kind, + value: self.static_data.damage, + }, + Some(GroupTarget::OutOfGroup), + rand::random(), + ); + if let Some(effect) = self.static_data.damage_effect { + damage = damage.with_effect(effect); + } + let precision_mult = combat::compute_precision_mult(data.inventory, data.msm); + let attack = Attack::default() + .with_damage(damage) + .with_precision(precision_mult) + .with_effect(poise) + .with_effect(knockback) + .with_combo_increment(); + let properties = shockwave::Properties { + angle: self.static_data.shockwave_angle, + vertical_angle: self.static_data.shockwave_vertical_angle, + speed: self.static_data.shockwave_speed, + duration: self.static_data.shockwave_duration, + attack, + dodgeable: self.static_data.dodgeable, + owner: Some(*data.uid), + specifier: self.static_data.specifier, + }; + output_events.emit_server(ShockwaveEvent { + properties, + pos: *data.pos, + ori: *data.ori, + }); + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub enum Timing { + PostBuildup, + PostAction, +} diff --git a/voxygen/anim/src/character/shockwave.rs b/voxygen/anim/src/character/shockwave.rs index 605d1f298a..57fb7057a9 100644 --- a/voxygen/anim/src/character/shockwave.rs +++ b/voxygen/anim/src/character/shockwave.rs @@ -1,11 +1,8 @@ use super::{ super::{vek::*, Animation}, - CharacterSkeleton, SkeletonAttr, -}; -use common::{ - comp::item::Hands, - states::utils::{AbilityInfo, StageSection}, + hammer_start, twist_back, twist_forward, CharacterSkeleton, SkeletonAttr, }; +use common::states::utils::StageSection; pub struct Input { pub attack: bool, @@ -13,13 +10,7 @@ pub struct Input { pub struct ShockwaveAnimation; impl Animation for ShockwaveAnimation { - type Dependency<'a> = ( - Option, - (Option, Option), - f32, - f32, - Option, - ); + type Dependency<'a> = (Option<&'a str>, f32, f32, Option); type Skeleton = CharacterSkeleton; #[cfg(feature = "use-dyn-lib")] @@ -28,7 +19,7 @@ impl Animation for ShockwaveAnimation { #[cfg_attr(feature = "be-dyn-lib", export_name = "character_shockwave")] fn update_skeleton_inner( skeleton: &Self::Skeleton, - (_ability_info, hands, _global_time, velocity, stage_section): Self::Dependency<'_>, + (ability_id, _global_time, velocity, stage_section): Self::Dependency<'_>, anim_time: f32, rate: &mut f32, s_a: &SkeletonAttr, @@ -36,6 +27,11 @@ impl Animation for ShockwaveAnimation { *rate = 1.0; let mut next = (*skeleton).clone(); + if matches!(stage_section, Some(StageSection::Action)) { + next.main_weapon_trail = true; + next.off_weapon_trail = true; + } + let (move1, move2, move3) = match stage_section { Some(StageSection::Buildup) => (anim_time, 0.0, 0.0), Some(StageSection::Action) => (1.0, anim_time, 0.0), @@ -43,79 +39,104 @@ impl Animation for ShockwaveAnimation { _ => (0.0, 0.0, 0.0), }; - if matches!( - stage_section, - Some(StageSection::Action | StageSection::Recover) - ) { - next.main_weapon_trail = true; - next.off_weapon_trail = true; - } - next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); + match ability_id { + Some( + "common.abilities.staff.fireshockwave" + | "common.abilities.sceptre.healingaura" + | "common.abilities.sceptre.wardingaura", + ) => { + next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); - next.hand_l.position = Vec3::new(s_a.sthl.0, s_a.sthl.1, s_a.sthl.2); - next.hand_l.orientation = - Quaternion::rotation_x(s_a.sthl.3) * Quaternion::rotation_y(s_a.sthl.4); - next.hand_r.position = Vec3::new(s_a.sthr.0, s_a.sthr.1, s_a.sthr.2); - next.hand_r.orientation = - Quaternion::rotation_x(s_a.sthr.3) * Quaternion::rotation_y(s_a.sthr.4); - next.main.position = Vec3::new(0.0, 0.0, 0.0); - next.main.orientation = Quaternion::rotation_x(0.0); + next.hand_l.position = Vec3::new(s_a.sthl.0, s_a.sthl.1, s_a.sthl.2); + next.hand_l.orientation = + Quaternion::rotation_x(s_a.sthl.3) * Quaternion::rotation_y(s_a.sthl.4); + next.hand_r.position = Vec3::new(s_a.sthr.0, s_a.sthr.1, s_a.sthr.2); + next.hand_r.orientation = + Quaternion::rotation_x(s_a.sthr.3) * Quaternion::rotation_y(s_a.sthr.4); + next.main.position = Vec3::new(0.0, 0.0, 0.0); + next.main.orientation = Quaternion::rotation_x(0.0); - next.control.position = Vec3::new(s_a.stc.0, s_a.stc.1, s_a.stc.2); - next.control.orientation = - Quaternion::rotation_x(s_a.stc.3) * Quaternion::rotation_y(s_a.stc.4); + next.control.position = Vec3::new(s_a.stc.0, s_a.stc.1, s_a.stc.2); + next.control.orientation = + Quaternion::rotation_x(s_a.stc.3) * Quaternion::rotation_y(s_a.stc.4); - let twist = move1 * 0.8; + let twist = move1 * 0.8; - next.control.position = Vec3::new( - s_a.stc.0 + (move1 * 5.0) * (1.0 - move3), - s_a.stc.1 + (move1 * 5.0) * (1.0 - move3), - s_a.stc.2 + (move1 * 10.0 + move2 * -10.0) * (1.0 - move3), - ); - next.control.orientation = - Quaternion::rotation_x(s_a.stc.3 + (move1 * 0.8) * (1.0 - move3)) - * Quaternion::rotation_y( - s_a.stc.4 + (move1 * -0.15 + move2 * -0.15) * (1.0 - move3), - ) - * Quaternion::rotation_z((move1 * 0.8 + move2 * -0.8) * (1.0 - move3)); + next.control.position = Vec3::new( + s_a.stc.0 + (move1 * 5.0) * (1.0 - move3), + s_a.stc.1 + (move1 * 5.0) * (1.0 - move3), + s_a.stc.2 + (move1 * 10.0 + move2 * -10.0) * (1.0 - move3), + ); + next.control.orientation = + Quaternion::rotation_x(s_a.stc.3 + (move1 * 0.8) * (1.0 - move3)) + * Quaternion::rotation_y( + s_a.stc.4 + (move1 * -0.15 + move2 * -0.15) * (1.0 - move3), + ) + * Quaternion::rotation_z((move1 * 0.8 + move2 * -0.8) * (1.0 - move3)); - next.head.orientation = Quaternion::rotation_x((move1 * 0.4) * (1.0 - move3)) - * Quaternion::rotation_z((twist * 0.2 + move2 * -0.8) * (1.0 - move3)); + next.head.orientation = Quaternion::rotation_x((move1 * 0.4) * (1.0 - move3)) + * Quaternion::rotation_z((twist * 0.2 + move2 * -0.8) * (1.0 - move3)); - next.chest.position = Vec3::new( - 0.0, - s_a.chest.0, - s_a.chest.1 + (move1 * 2.0 + move2 * -4.0) * (1.0 - move3), - ); - next.chest.orientation = Quaternion::rotation_x((move2 * -0.8) * (1.0 - move3)) - * Quaternion::rotation_z(twist * -0.2 + move2 * -0.1 + (1.0 - move3)); + next.chest.position = Vec3::new( + 0.0, + s_a.chest.0, + s_a.chest.1 + (move1 * 2.0 + move2 * -4.0) * (1.0 - move3), + ); + next.chest.orientation = Quaternion::rotation_x((move2 * -0.8) * (1.0 - move3)) + * Quaternion::rotation_z(twist * -0.2 + move2 * -0.1 + (1.0 - move3)); - next.belt.orientation = Quaternion::rotation_x((move2 * 0.2) * (1.0 - move3)) - * Quaternion::rotation_z((twist * 0.6 + move2 * -0.48) * (1.0 - move3)); + next.belt.orientation = Quaternion::rotation_x((move2 * 0.2) * (1.0 - move3)) + * Quaternion::rotation_z((twist * 0.6 + move2 * -0.48) * (1.0 - move3)); - next.shorts.orientation = Quaternion::rotation_x((move2 * 0.3) * (1.0 - move3)) - * Quaternion::rotation_z((twist + move2 * -0.8) * (1.0 - move3)); + next.shorts.orientation = Quaternion::rotation_x((move2 * 0.3) * (1.0 - move3)) + * Quaternion::rotation_z((twist + move2 * -0.8) * (1.0 - move3)); - if velocity < 0.5 { - next.foot_l.position = Vec3::new( - -s_a.foot.0, - s_a.foot.1 + move1 * -7.0 + move2 * 7.0, - s_a.foot.2, - ); - next.foot_l.orientation = Quaternion::rotation_x(move1 * -0.8 + move2 * 0.8) - * Quaternion::rotation_z(move1 * 0.3 + move2 * -0.3); + if velocity < 0.5 { + next.foot_l.position = Vec3::new( + -s_a.foot.0, + s_a.foot.1 + move1 * -7.0 + move2 * 7.0, + s_a.foot.2, + ); + next.foot_l.orientation = Quaternion::rotation_x(move1 * -0.8 + move2 * 0.8) + * Quaternion::rotation_z(move1 * 0.3 + move2 * -0.3); - next.foot_r.position = Vec3::new( - s_a.foot.0, - s_a.foot.1 + move1 * 5.0 + move2 * -5.0, - s_a.foot.2, - ); - next.foot_r.orientation = Quaternion::rotation_y(move1 * -0.3 + move2 * 0.3) - * Quaternion::rotation_z(move1 * 0.4 + move2 * -0.4); - } + next.foot_r.position = Vec3::new( + s_a.foot.0, + s_a.foot.1 + move1 * 5.0 + move2 * -5.0, + s_a.foot.2, + ); + next.foot_r.orientation = Quaternion::rotation_y(move1 * -0.3 + move2 * 0.3) + * Quaternion::rotation_z(move1 * 0.4 + move2 * -0.4); + } + }, + Some("common.abilities.hammer.tremor") => { + hammer_start(&mut next, s_a); + let (move1, move2, move3) = match stage_section { + Some(StageSection::Buildup) => (anim_time, 0.0, 0.0), + Some(StageSection::Action) => (1.0, anim_time, 0.0), + Some(StageSection::Recover) => (1.0, 1.0, anim_time), + _ => (0.0, 0.0, 0.0), + }; + let pullback = 1.0 - move3; + let move1 = move1 * pullback; + let move2 = move2 * pullback; - if let (None, Some(Hands::Two)) = hands { - next.second = next.main; + twist_back(&mut next, move1, 1.4, 0.7, 0.5, 0.9); + next.foot_l.orientation.rotate_z(move1 * 1.4); + next.foot_l.position += Vec3::new(-1.0, -3.0, 0.0) * move1; + next.control.orientation.rotate_x(move1 * 2.6); + next.control.orientation.rotate_y(move1 * 0.8); + + twist_forward(&mut next, move2, 2.1, 1.2, 0.9, 1.6); + next.foot_l.orientation.rotate_z(move2 * -1.4); + next.foot_l.position += Vec3::new(2.0, 7.0, 0.0) * move2; + next.control.orientation.rotate_z(move2 * 2.1); + next.control.orientation.rotate_x(move2 * -2.0); + next.control.orientation.rotate_z(move2 * 1.2); + next.control.position += Vec3::new(-16.0, 0.0, 0.0) * move2; + next.chest.orientation.rotate_x(-0.8 * move2); + }, + _ => {}, } next diff --git a/voxygen/src/hud/img_ids.rs b/voxygen/src/hud/img_ids.rs index 04c572512f..4c0ec5f6a3 100644 --- a/voxygen/src/hud/img_ids.rs +++ b/voxygen/src/hud/img_ids.rs @@ -318,6 +318,7 @@ image_ids! { hammer_solid_smash: "voxygen.element.skills.hammer.solid_smash", hammer_wide_wallop: "voxygen.element.skills.hammer.wide_wallop", hammer_scornful_swipe: "voxygen.element.skills.hammer.scornful_swipe", + hammer_tremor: "voxygen.element.skills.hammer.tremor", // Skilltree Icons health_plus_skill: "voxygen.element.skills.skilltree.health_plus", energy_plus_skill: "voxygen.element.skills.skilltree.energy_plus", diff --git a/voxygen/src/hud/util.rs b/voxygen/src/hud/util.rs index 548aa6a197..e1118643d5 100644 --- a/voxygen/src/hud/util.rs +++ b/voxygen/src/hud/util.rs @@ -625,6 +625,7 @@ pub fn ability_image(imgs: &img_ids::Imgs, ability_id: &str) -> image::Id { "common.abilities.hammer.solid_smash" => imgs.hammer_solid_smash, "common.abilities.hammer.wide_wallop" => imgs.hammer_wide_wallop, "common.abilities.hammer.scornful_swipe" => imgs.hammer_scornful_swipe, + "common.abilities.hammer.tremor" => imgs.hammer_tremor, // Bow "common.abilities.bow.charged" => imgs.bow_m1, "common.abilities.bow.repeater" => imgs.bow_m2, diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index fdbdf7dfc1..0eaa728f50 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -1652,13 +1652,7 @@ impl FigureMgr { }; anim::character::ShockwaveAnimation::update_skeleton( &target_base, - ( - Some(s.static_data.ability_info), - hands, - time, - rel_vel.magnitude(), - Some(s.stage_section), - ), + (ability_id, time, rel_vel.magnitude(), Some(s.stage_section)), stage_progress, &mut state_animation_rate, skeleton_attr, @@ -1678,15 +1672,11 @@ impl FigureMgr { }, _ => 0.0, }; + + // ? Aura confirmed just shockwave anim::character::ShockwaveAnimation::update_skeleton( &target_base, - ( - Some(s.static_data.ability_info), - hands, - time, - rel_vel.magnitude(), - Some(s.stage_section), - ), + (ability_id, time, rel_vel.magnitude(), Some(s.stage_section)), stage_progress, &mut state_animation_rate, skeleton_attr,