From 909363d33ca28eeaf0a65ebe62767c371c78905a Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 19 Feb 2024 14:41:22 -0500 Subject: [PATCH] Vigorous bash --- .../common/abilities/ability_set_manifest.ron | 2 +- assets/common/abilities/axe/cleave.ron | 2 +- assets/common/abilities/axe/plunder.ron | 2 +- assets/common/abilities/axe/rising_tide.ron | 2 +- assets/common/abilities/hammer/tremor.ron | 2 +- .../common/abilities/hammer/vigorous_bash.ron | 27 +++++++++++++++ .../element/skills/hammer/vigorous_bash.png | 3 ++ assets/voxygen/i18n/en/hud/ability.ftl | 5 ++- common/src/combat.rs | 16 ++++++--- common/src/comp/ability.rs | 13 ++++--- common/src/comp/melee.rs | 34 +++++++++++++------ common/src/states/charged_melee.rs | 21 ++++++++---- common/src/states/combo_melee2.rs | 12 +++---- common/src/states/dash_melee.rs | 2 +- voxygen/anim/src/character/combomelee.rs | 24 ++++++++++++- voxygen/src/hud/img_ids.rs | 1 + voxygen/src/hud/util.rs | 1 + 17 files changed, 127 insertions(+), 42 deletions(-) create mode 100644 assets/common/abilities/hammer/vigorous_bash.ron create mode 100644 assets/voxygen/element/skills/hammer/vigorous_bash.png diff --git a/assets/common/abilities/ability_set_manifest.ron b/assets/common/abilities/ability_set_manifest.ron index 1b742e8ef1..dd05bd8ac4 100644 --- a/assets/common/abilities/ability_set_manifest.ron +++ b/assets/common/abilities/ability_set_manifest.ron @@ -198,7 +198,7 @@ abilities: [ Simple(Hammer(ScornfulSwipe), "common.abilities.hammer.scornful_swipe"), Simple(Hammer(Tremor), "common.abilities.hammer.tremor"), - // Simple(Hammer(VigorousBash), "common.abilities.hammer.vigorous_bash"), + Simple(Hammer(VigorousBash), "common.abilities.hammer.vigorous_bash"), // Simple(Hammer(Retaliate), "common.abilities.hammer.retaliate"), // Simple(Hammer(SpineCracker), "common.abilities.hammer.spine_cracker"), // Simple(Hammer(Breach), "common.abilities.hammer.breach"), diff --git a/assets/common/abilities/axe/cleave.ron b/assets/common/abilities/axe/cleave.ron index 6f965e3d5c..c3c96c2df9 100644 --- a/assets/common/abilities/axe/cleave.ron +++ b/assets/common/abilities/axe/cleave.ron @@ -22,5 +22,5 @@ ChargedMelee( swing_duration: 0.1, hit_timing: 0.2, recover_duration: 0.2, - additional_combo: 4, + custom_combo: Some((additional: 4)), ) diff --git a/assets/common/abilities/axe/plunder.ron b/assets/common/abilities/axe/plunder.ron index fbce7af835..e46aafe79c 100644 --- a/assets/common/abilities/axe/plunder.ron +++ b/assets/common/abilities/axe/plunder.ron @@ -20,7 +20,7 @@ ComboMelee2( swing: Some(Forward(0.7)), ), ori_modifier: 0.6, - additional_combo: 4, + custom_combo: Some((additional: 4)), ), ], energy_cost_per_strike: 10, diff --git a/assets/common/abilities/axe/rising_tide.ron b/assets/common/abilities/axe/rising_tide.ron index 6c46e77df9..c60e22d266 100644 --- a/assets/common/abilities/axe/rising_tide.ron +++ b/assets/common/abilities/axe/rising_tide.ron @@ -16,7 +16,7 @@ ComboMelee2( hit_timing: 0.5, recover_duration: 0.3, ori_modifier: 0.6, - additional_combo: 4, + custom_combo: Some((additional: 4)), ), ], energy_cost_per_strike: 10, diff --git a/assets/common/abilities/hammer/tremor.ron b/assets/common/abilities/hammer/tremor.ron index 529c007614..d989b9a2c6 100644 --- a/assets/common/abilities/hammer/tremor.ron +++ b/assets/common/abilities/hammer/tremor.ron @@ -1,5 +1,5 @@ Shockwave( - energy_cost: 0, + energy_cost: 20, buildup_duration: 0.4, swing_duration: 0.3, recover_duration: 0.3, diff --git a/assets/common/abilities/hammer/vigorous_bash.ron b/assets/common/abilities/hammer/vigorous_bash.ron new file mode 100644 index 0000000000..ad37c11adc --- /dev/null +++ b/assets/common/abilities/hammer/vigorous_bash.ron @@ -0,0 +1,27 @@ +ComboMelee2( + strikes: [ + ( + melee_constructor: ( + kind: Bash( + damage: 15, + poise: 15, + knockback: 5, + energy_regen: 0, + ), + range: 4.0, + angle: 15.0, + ), + buildup_duration: 0.2, + swing_duration: 0.2, + hit_timing: 0.2, + recover_duration: 0.1, + movement: ( + buildup: Some(Forward(0.2)), + swing: Some(Forward(0.3)), + ), + ori_modifier: 0.6, + custom_combo: Some((additional: 9, requirement: Some(TargetPoised))), + ), + ], + energy_cost_per_strike: 0, +) diff --git a/assets/voxygen/element/skills/hammer/vigorous_bash.png b/assets/voxygen/element/skills/hammer/vigorous_bash.png new file mode 100644 index 0000000000..64fc6cc8aa --- /dev/null +++ b/assets/voxygen/element/skills/hammer/vigorous_bash.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f62ef8546cab964b85ab1f33f550c42ee314ff8db8af7da4ea37c29ed52b7cdf +size 1054 diff --git a/assets/voxygen/i18n/en/hud/ability.ftl b/assets/voxygen/i18n/en/hud/ability.ftl index c03d11fb8b..5a751087c5 100644 --- a/assets/voxygen/i18n/en/hud/ability.ftl +++ b/assets/voxygen/i18n/en/hud/ability.ftl @@ -384,8 +384,11 @@ common-abilities-hammer-wide_wallop = Wide Wallop .desc = Pull back and send them flying common-abilities-hammer-scornful_swipe = Scornful Swipe - .desc = + .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. +common-abilities-hammer-vigorous_bash = Vigorous Bash + .desc = + Use the head of your hammer to quickly strike your foes. diff --git a/common/src/combat.rs b/common/src/combat.rs index c98743e296..24e9e943b5 100644 --- a/common/src/combat.rs +++ b/common/src/combat.rs @@ -136,13 +136,17 @@ impl Attack { } #[must_use] - pub fn with_combo(self, combo: i32) -> Self { + pub fn with_combo_requirement(self, combo: i32, requirement: CombatRequirement) -> Self { self.with_effect( - AttackEffect::new(None, CombatEffect::Combo(combo)) - .with_requirement(CombatRequirement::AnyDamage), + AttackEffect::new(None, CombatEffect::Combo(combo)).with_requirement(requirement), ) } + #[must_use] + pub fn with_combo(self, combo: i32) -> Self { + self.with_combo_requirement(combo, CombatRequirement::AnyDamage) + } + #[must_use] pub fn with_combo_increment(self) -> Self { self.with_combo(1) } @@ -648,6 +652,9 @@ impl Attack { CombatRequirement::TargetHasBuff(buff) => { target.buffs.map_or(false, |buffs| buffs.contains(*buff)) }, + CombatRequirement::TargetPoised => { + target.char_state.map_or(false, |cs| cs.is_stunned()) + }, }); if requirements_met { is_applied = true; @@ -1000,12 +1007,13 @@ impl CombatEffect { } } -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq)] pub enum CombatRequirement { AnyDamage, Energy(f32), Combo(u32), TargetHasBuff(BuffKind), + TargetPoised, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index 445b151c72..d6e80dfc88 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -14,7 +14,7 @@ use crate::{ slot::EquipSlot, Inventory, }, - melee::{MeleeConstructor, MeleeConstructorKind}, + melee::{CustomCombo, MeleeConstructor, MeleeConstructorKind}, projectile::ProjectileConstructor, skillset::{ skills::{self, Skill, SKILL_MODIFIERS}, @@ -889,8 +889,7 @@ pub enum CharacterAbility { melee_constructor: MeleeConstructor, specifier: Option, damage_effect: Option, - #[serde(default)] - additional_combo: i32, + custom_combo: Option, #[serde(default)] meta: AbilityMeta, }, @@ -1112,7 +1111,7 @@ impl Default for CharacterAbility { multi_target: None, damage_effect: None, simultaneous_hits: 1, - combo_gain: 1, + custom_combo: None, }, ori_modifier: 1.0, frontend_specifier: None, @@ -1466,7 +1465,7 @@ impl CharacterAbility { specifier: _, ref mut damage_effect, meta: _, - additional_combo: _, + custom_combo: _, } => { *swing_duration /= stats.speed; *buildup_strike = buildup_strike @@ -2450,7 +2449,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { melee_constructor, specifier, damage_effect, - additional_combo, + custom_combo, meta: _, } => CharacterState::ChargedMelee(charged_melee::Data { static_data: charged_melee::StaticData { @@ -2466,7 +2465,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { ability_info, specifier: *specifier, damage_effect: *damage_effect, - additional_combo: *additional_combo, + custom_combo: *custom_combo, }, stage_section: if buildup_strike.is_some() { StageSection::Buildup diff --git a/common/src/comp/melee.rs b/common/src/comp/melee.rs index f3f589efea..bd08d8b6cf 100644 --- a/common/src/comp/melee.rs +++ b/common/src/comp/melee.rs @@ -51,7 +51,6 @@ impl Component for Melee { } fn default_simultaneous_hits() -> u32 { 1 } -fn default_combo_gain() -> i32 { 1 } #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct Scaled { @@ -76,8 +75,13 @@ pub struct MeleeConstructor { pub damage_effect: Option, #[serde(default = "default_simultaneous_hits")] pub simultaneous_hits: u32, - #[serde(default = "default_combo_gain")] - pub combo_gain: i32, + pub custom_combo: Option, +} + +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct CustomCombo { + pub additional: i32, + pub requirement: Option, } impl MeleeConstructor { @@ -140,7 +144,6 @@ impl MeleeConstructor { .with_effect(energy) .with_effect(poise) .with_effect(knockback) - .with_combo(self.combo_gain) }, Stab { damage, @@ -191,7 +194,6 @@ impl MeleeConstructor { .with_effect(energy) .with_effect(poise) .with_effect(knockback) - .with_combo(self.combo_gain) }, Bash { damage, @@ -234,7 +236,6 @@ impl MeleeConstructor { .with_effect(energy) .with_effect(poise) .with_effect(knockback) - .with_combo(self.combo_gain) }, Hook { damage, @@ -281,7 +282,6 @@ impl MeleeConstructor { .with_precision(precision_mult) .with_effect(poise) .with_effect(knockback) - .with_combo(self.combo_gain) }, NecroticVortex { damage, @@ -319,7 +319,6 @@ impl MeleeConstructor { .with_damage(damage) .with_precision(precision_mult) .with_effect(knockback) - .with_combo(self.combo_gain) }, SonicWave { damage, @@ -358,10 +357,23 @@ impl MeleeConstructor { .with_precision(precision_mult) .with_effect(poise) .with_effect(knockback) - .with_combo(self.combo_gain) }, }; + let attack = match self.custom_combo { + None => attack.with_combo_increment(), + Some(CustomCombo { + additional, + requirement: None, + }) => attack.with_combo(1 + additional), + Some(CustomCombo { + additional, + requirement: Some(req), + }) => attack + .with_combo_increment() + .with_combo_requirement(additional, req), + }; + Melee { attack, range: self.range, @@ -517,8 +529,8 @@ impl MeleeConstructor { } #[must_use] - pub fn with_combo(mut self, combo: i32) -> Self { - self.combo_gain = combo; + pub fn custom_combo(mut self, custom: Option) -> Self { + self.custom_combo = custom; self } } diff --git a/common/src/states/charged_melee.rs b/common/src/states/charged_melee.rs index ce4bb3c3b2..9fac060941 100644 --- a/common/src/states/charged_melee.rs +++ b/common/src/states/charged_melee.rs @@ -1,6 +1,9 @@ use crate::{ combat::{self, CombatEffect}, - comp::{character_state::OutputEvents, CharacterState, MeleeConstructor, StateUpdate}, + comp::{ + character_state::OutputEvents, melee::CustomCombo, CharacterState, MeleeConstructor, + StateUpdate, + }, event::LocalEvent, outcome::Outcome, states::{ @@ -38,7 +41,7 @@ pub struct StaticData { /// Adds an effect onto the main damage of the attack pub damage_effect: Option, /// The actual additional combo is modified by duration of charge - pub additional_combo: i32, + pub custom_combo: Option, } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -156,15 +159,21 @@ impl CharacterBehavior for Data { let precision_mult = combat::compute_precision_mult(data.inventory, data.msm); let tool_stats = get_tool_stats(data, self.static_data.ability_info); - let additional_combo = - (self.charge_amount * self.static_data.additional_combo as f32 + 0.5) - .floor() as i32; + let custom_combo = self.static_data.custom_combo.map(|c| { + let additional = + (self.charge_amount * c.additional as f32 + 0.5).floor() as i32; + + CustomCombo { + additional, + requirement: c.requirement, + } + }); data.updater.insert( data.entity, self.static_data .melee_constructor - .with_combo(1 + additional_combo) + .custom_combo(custom_combo) .handle_scaling(self.charge_amount) .create_melee(precision_mult, tool_stats), ); diff --git a/common/src/states/combo_melee2.rs b/common/src/states/combo_melee2.rs index e77a994557..530e4dcce1 100644 --- a/common/src/states/combo_melee2.rs +++ b/common/src/states/combo_melee2.rs @@ -2,8 +2,8 @@ use crate::{ combat, combat::{Attack, AttackDamage, Damage, DamageKind::Crushing, DamageSource, GroupTarget}, comp::{ - character_state::OutputEvents, item::Reagent, tool::Stats, CharacterState, - MeleeConstructor, StateUpdate, + character_state::OutputEvents, item::Reagent, melee::CustomCombo, tool::Stats, + CharacterState, MeleeConstructor, StateUpdate, }, event::{ExplosionEvent, LocalEvent}, outcome::Outcome, @@ -38,7 +38,7 @@ pub struct Strike { /// Adjusts turning rate during the attack pub ori_modifier: f32, #[serde(default)] - pub additional_combo: i32, + pub custom_combo: Option, } impl Strike { @@ -51,7 +51,7 @@ impl Strike { recover_duration: Duration::from_secs_f32(self.recover_duration), movement: self.movement, ori_modifier: self.ori_modifier, - additional_combo: self.additional_combo, + custom_combo: self.custom_combo, } } @@ -65,7 +65,7 @@ impl Strike { recover_duration: self.recover_duration / stats.speed, movement: self.movement, ori_modifier: self.ori_modifier, - additional_combo: self.additional_combo, + custom_combo: self.custom_combo, } } } @@ -179,7 +179,7 @@ impl CharacterBehavior for Data { data.entity, strike_data .melee_constructor - .with_combo(1 + strike_data.additional_combo) + .custom_combo(strike_data.custom_combo) .create_melee(precision_mult, tool_stats), ); } else if self.timer < strike_data.swing_duration { diff --git a/common/src/states/dash_melee.rs b/common/src/states/dash_melee.rs index ac16b0386f..5aaf5a923d 100644 --- a/common/src/states/dash_melee.rs +++ b/common/src/states/dash_melee.rs @@ -278,7 +278,7 @@ fn create_test_melee(static_data: StaticData) -> Melee { multi_target: None, damage_effect: None, simultaneous_hits: 1, - combo_gain: 0, + custom_combo: None, }; melee.create_melee(0.0, tool::Stats::one()) } diff --git a/voxygen/anim/src/character/combomelee.rs b/voxygen/anim/src/character/combomelee.rs index af4dbcfbd8..de42458814 100644 --- a/voxygen/anim/src/character/combomelee.rs +++ b/voxygen/anim/src/character/combomelee.rs @@ -1,6 +1,6 @@ use super::{ super::{vek::*, Animation}, - CharacterSkeleton, SkeletonAttr, + hammer_start, twist_back, twist_forward, CharacterSkeleton, SkeletonAttr, }; use common::states::utils::{AbilityInfo, HandInfo, StageSection}; use core::f32::consts::{PI, TAU}; @@ -1208,6 +1208,28 @@ impl Animation for ComboAnimation { } } }, + Some("common.abilities.hammer.vigorous_bash") => { + 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; + + twist_forward(&mut next, move1, 1.4, 0.7, 0.5, 0.9); + next.control.orientation.rotate_y(move1 * 0.3); + next.control.orientation.rotate_z(move1 * -0.3); + next.control.position += Vec3::new(12.0, -3.0, 3.0) * move1; + + twist_back(&mut next, move2, 1.8, 0.9, 0.6, 1.1); + next.control.orientation.rotate_z(move2 * -2.1); + next.control.orientation.rotate_x(move2 * 0.6); + next.control.position += Vec3::new(-20.0, 8.0, 0.0) * move2; + }, _ => {}, } } diff --git a/voxygen/src/hud/img_ids.rs b/voxygen/src/hud/img_ids.rs index 4c0ec5f6a3..2e7f034c2c 100644 --- a/voxygen/src/hud/img_ids.rs +++ b/voxygen/src/hud/img_ids.rs @@ -319,6 +319,7 @@ image_ids! { 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", + hammer_vigorous_bash: "voxygen.element.skills.hammer.vigorous_bash", // 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 e1118643d5..1c43c48fc0 100644 --- a/voxygen/src/hud/util.rs +++ b/voxygen/src/hud/util.rs @@ -626,6 +626,7 @@ pub fn ability_image(imgs: &img_ids::Imgs, ability_id: &str) -> image::Id { "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, + "common.abilities.hammer.vigorous_bash" => imgs.hammer_vigorous_bash, // Bow "common.abilities.bow.charged" => imgs.bow_m1, "common.abilities.bow.repeater" => imgs.bow_m2,