Vigorous bash

This commit is contained in:
Sam 2024-02-19 14:41:22 -05:00
parent 89048e9530
commit 909363d33c
17 changed files with 127 additions and 42 deletions

View File

@ -198,7 +198,7 @@
abilities: [ abilities: [
Simple(Hammer(ScornfulSwipe), "common.abilities.hammer.scornful_swipe"), 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(VigorousBash), "common.abilities.hammer.vigorous_bash"),
// Simple(Hammer(Retaliate), "common.abilities.hammer.retaliate"), // Simple(Hammer(Retaliate), "common.abilities.hammer.retaliate"),
// Simple(Hammer(SpineCracker), "common.abilities.hammer.spine_cracker"), // Simple(Hammer(SpineCracker), "common.abilities.hammer.spine_cracker"),
// Simple(Hammer(Breach), "common.abilities.hammer.breach"), // Simple(Hammer(Breach), "common.abilities.hammer.breach"),

View File

@ -22,5 +22,5 @@ ChargedMelee(
swing_duration: 0.1, swing_duration: 0.1,
hit_timing: 0.2, hit_timing: 0.2,
recover_duration: 0.2, recover_duration: 0.2,
additional_combo: 4, custom_combo: Some((additional: 4)),
) )

View File

@ -20,7 +20,7 @@ ComboMelee2(
swing: Some(Forward(0.7)), swing: Some(Forward(0.7)),
), ),
ori_modifier: 0.6, ori_modifier: 0.6,
additional_combo: 4, custom_combo: Some((additional: 4)),
), ),
], ],
energy_cost_per_strike: 10, energy_cost_per_strike: 10,

View File

@ -16,7 +16,7 @@ ComboMelee2(
hit_timing: 0.5, hit_timing: 0.5,
recover_duration: 0.3, recover_duration: 0.3,
ori_modifier: 0.6, ori_modifier: 0.6,
additional_combo: 4, custom_combo: Some((additional: 4)),
), ),
], ],
energy_cost_per_strike: 10, energy_cost_per_strike: 10,

View File

@ -1,5 +1,5 @@
Shockwave( Shockwave(
energy_cost: 0, energy_cost: 20,
buildup_duration: 0.4, buildup_duration: 0.4,
swing_duration: 0.3, swing_duration: 0.3,
recover_duration: 0.3, recover_duration: 0.3,

View File

@ -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,
)

BIN
assets/voxygen/element/skills/hammer/vigorous_bash.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -384,8 +384,11 @@ common-abilities-hammer-wide_wallop = Wide Wallop
.desc = .desc =
Pull back and send them flying Pull back and send them flying
common-abilities-hammer-scornful_swipe = Scornful Swipe 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. 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 common-abilities-hammer-tremor = Tremor
.desc = .desc =
Strike the earth with enough force that the ground beneath your foes trembles. 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.

View File

@ -136,13 +136,17 @@ impl Attack {
} }
#[must_use] #[must_use]
pub fn with_combo(self, combo: i32) -> Self { pub fn with_combo_requirement(self, combo: i32, requirement: CombatRequirement) -> Self {
self.with_effect( self.with_effect(
AttackEffect::new(None, CombatEffect::Combo(combo)) AttackEffect::new(None, CombatEffect::Combo(combo)).with_requirement(requirement),
.with_requirement(CombatRequirement::AnyDamage),
) )
} }
#[must_use]
pub fn with_combo(self, combo: i32) -> Self {
self.with_combo_requirement(combo, CombatRequirement::AnyDamage)
}
#[must_use] #[must_use]
pub fn with_combo_increment(self) -> Self { self.with_combo(1) } pub fn with_combo_increment(self) -> Self { self.with_combo(1) }
@ -648,6 +652,9 @@ impl Attack {
CombatRequirement::TargetHasBuff(buff) => { CombatRequirement::TargetHasBuff(buff) => {
target.buffs.map_or(false, |buffs| buffs.contains(*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 { if requirements_met {
is_applied = true; 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 { pub enum CombatRequirement {
AnyDamage, AnyDamage,
Energy(f32), Energy(f32),
Combo(u32), Combo(u32),
TargetHasBuff(BuffKind), TargetHasBuff(BuffKind),
TargetPoised,
} }
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]

View File

@ -14,7 +14,7 @@ use crate::{
slot::EquipSlot, slot::EquipSlot,
Inventory, Inventory,
}, },
melee::{MeleeConstructor, MeleeConstructorKind}, melee::{CustomCombo, MeleeConstructor, MeleeConstructorKind},
projectile::ProjectileConstructor, projectile::ProjectileConstructor,
skillset::{ skillset::{
skills::{self, Skill, SKILL_MODIFIERS}, skills::{self, Skill, SKILL_MODIFIERS},
@ -889,8 +889,7 @@ pub enum CharacterAbility {
melee_constructor: MeleeConstructor, melee_constructor: MeleeConstructor,
specifier: Option<charged_melee::FrontendSpecifier>, specifier: Option<charged_melee::FrontendSpecifier>,
damage_effect: Option<CombatEffect>, damage_effect: Option<CombatEffect>,
#[serde(default)] custom_combo: Option<CustomCombo>,
additional_combo: i32,
#[serde(default)] #[serde(default)]
meta: AbilityMeta, meta: AbilityMeta,
}, },
@ -1112,7 +1111,7 @@ impl Default for CharacterAbility {
multi_target: None, multi_target: None,
damage_effect: None, damage_effect: None,
simultaneous_hits: 1, simultaneous_hits: 1,
combo_gain: 1, custom_combo: None,
}, },
ori_modifier: 1.0, ori_modifier: 1.0,
frontend_specifier: None, frontend_specifier: None,
@ -1466,7 +1465,7 @@ impl CharacterAbility {
specifier: _, specifier: _,
ref mut damage_effect, ref mut damage_effect,
meta: _, meta: _,
additional_combo: _, custom_combo: _,
} => { } => {
*swing_duration /= stats.speed; *swing_duration /= stats.speed;
*buildup_strike = buildup_strike *buildup_strike = buildup_strike
@ -2450,7 +2449,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
melee_constructor, melee_constructor,
specifier, specifier,
damage_effect, damage_effect,
additional_combo, custom_combo,
meta: _, meta: _,
} => CharacterState::ChargedMelee(charged_melee::Data { } => CharacterState::ChargedMelee(charged_melee::Data {
static_data: charged_melee::StaticData { static_data: charged_melee::StaticData {
@ -2466,7 +2465,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
ability_info, ability_info,
specifier: *specifier, specifier: *specifier,
damage_effect: *damage_effect, damage_effect: *damage_effect,
additional_combo: *additional_combo, custom_combo: *custom_combo,
}, },
stage_section: if buildup_strike.is_some() { stage_section: if buildup_strike.is_some() {
StageSection::Buildup StageSection::Buildup

View File

@ -51,7 +51,6 @@ impl Component for Melee {
} }
fn default_simultaneous_hits() -> u32 { 1 } fn default_simultaneous_hits() -> u32 { 1 }
fn default_combo_gain() -> i32 { 1 }
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Scaled { pub struct Scaled {
@ -76,8 +75,13 @@ pub struct MeleeConstructor {
pub damage_effect: Option<CombatEffect>, pub damage_effect: Option<CombatEffect>,
#[serde(default = "default_simultaneous_hits")] #[serde(default = "default_simultaneous_hits")]
pub simultaneous_hits: u32, pub simultaneous_hits: u32,
#[serde(default = "default_combo_gain")] pub custom_combo: Option<CustomCombo>,
pub combo_gain: i32, }
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct CustomCombo {
pub additional: i32,
pub requirement: Option<CombatRequirement>,
} }
impl MeleeConstructor { impl MeleeConstructor {
@ -140,7 +144,6 @@ impl MeleeConstructor {
.with_effect(energy) .with_effect(energy)
.with_effect(poise) .with_effect(poise)
.with_effect(knockback) .with_effect(knockback)
.with_combo(self.combo_gain)
}, },
Stab { Stab {
damage, damage,
@ -191,7 +194,6 @@ impl MeleeConstructor {
.with_effect(energy) .with_effect(energy)
.with_effect(poise) .with_effect(poise)
.with_effect(knockback) .with_effect(knockback)
.with_combo(self.combo_gain)
}, },
Bash { Bash {
damage, damage,
@ -234,7 +236,6 @@ impl MeleeConstructor {
.with_effect(energy) .with_effect(energy)
.with_effect(poise) .with_effect(poise)
.with_effect(knockback) .with_effect(knockback)
.with_combo(self.combo_gain)
}, },
Hook { Hook {
damage, damage,
@ -281,7 +282,6 @@ impl MeleeConstructor {
.with_precision(precision_mult) .with_precision(precision_mult)
.with_effect(poise) .with_effect(poise)
.with_effect(knockback) .with_effect(knockback)
.with_combo(self.combo_gain)
}, },
NecroticVortex { NecroticVortex {
damage, damage,
@ -319,7 +319,6 @@ impl MeleeConstructor {
.with_damage(damage) .with_damage(damage)
.with_precision(precision_mult) .with_precision(precision_mult)
.with_effect(knockback) .with_effect(knockback)
.with_combo(self.combo_gain)
}, },
SonicWave { SonicWave {
damage, damage,
@ -358,10 +357,23 @@ impl MeleeConstructor {
.with_precision(precision_mult) .with_precision(precision_mult)
.with_effect(poise) .with_effect(poise)
.with_effect(knockback) .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 { Melee {
attack, attack,
range: self.range, range: self.range,
@ -517,8 +529,8 @@ impl MeleeConstructor {
} }
#[must_use] #[must_use]
pub fn with_combo(mut self, combo: i32) -> Self { pub fn custom_combo(mut self, custom: Option<CustomCombo>) -> Self {
self.combo_gain = combo; self.custom_combo = custom;
self self
} }
} }

View File

@ -1,6 +1,9 @@
use crate::{ use crate::{
combat::{self, CombatEffect}, combat::{self, CombatEffect},
comp::{character_state::OutputEvents, CharacterState, MeleeConstructor, StateUpdate}, comp::{
character_state::OutputEvents, melee::CustomCombo, CharacterState, MeleeConstructor,
StateUpdate,
},
event::LocalEvent, event::LocalEvent,
outcome::Outcome, outcome::Outcome,
states::{ states::{
@ -38,7 +41,7 @@ pub struct StaticData {
/// Adds an effect onto the main damage of the attack /// Adds an effect onto the main damage of the attack
pub damage_effect: Option<CombatEffect>, pub damage_effect: Option<CombatEffect>,
/// The actual additional combo is modified by duration of charge /// The actual additional combo is modified by duration of charge
pub additional_combo: i32, pub custom_combo: Option<CustomCombo>,
} }
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[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 precision_mult = combat::compute_precision_mult(data.inventory, data.msm);
let tool_stats = get_tool_stats(data, self.static_data.ability_info); let tool_stats = get_tool_stats(data, self.static_data.ability_info);
let additional_combo = let custom_combo = self.static_data.custom_combo.map(|c| {
(self.charge_amount * self.static_data.additional_combo as f32 + 0.5) let additional =
.floor() as i32; (self.charge_amount * c.additional as f32 + 0.5).floor() as i32;
CustomCombo {
additional,
requirement: c.requirement,
}
});
data.updater.insert( data.updater.insert(
data.entity, data.entity,
self.static_data self.static_data
.melee_constructor .melee_constructor
.with_combo(1 + additional_combo) .custom_combo(custom_combo)
.handle_scaling(self.charge_amount) .handle_scaling(self.charge_amount)
.create_melee(precision_mult, tool_stats), .create_melee(precision_mult, tool_stats),
); );

View File

@ -2,8 +2,8 @@ use crate::{
combat, combat,
combat::{Attack, AttackDamage, Damage, DamageKind::Crushing, DamageSource, GroupTarget}, combat::{Attack, AttackDamage, Damage, DamageKind::Crushing, DamageSource, GroupTarget},
comp::{ comp::{
character_state::OutputEvents, item::Reagent, tool::Stats, CharacterState, character_state::OutputEvents, item::Reagent, melee::CustomCombo, tool::Stats,
MeleeConstructor, StateUpdate, CharacterState, MeleeConstructor, StateUpdate,
}, },
event::{ExplosionEvent, LocalEvent}, event::{ExplosionEvent, LocalEvent},
outcome::Outcome, outcome::Outcome,
@ -38,7 +38,7 @@ pub struct Strike<T> {
/// Adjusts turning rate during the attack /// Adjusts turning rate during the attack
pub ori_modifier: f32, pub ori_modifier: f32,
#[serde(default)] #[serde(default)]
pub additional_combo: i32, pub custom_combo: Option<CustomCombo>,
} }
impl Strike<f32> { impl Strike<f32> {
@ -51,7 +51,7 @@ impl Strike<f32> {
recover_duration: Duration::from_secs_f32(self.recover_duration), recover_duration: Duration::from_secs_f32(self.recover_duration),
movement: self.movement, movement: self.movement,
ori_modifier: self.ori_modifier, ori_modifier: self.ori_modifier,
additional_combo: self.additional_combo, custom_combo: self.custom_combo,
} }
} }
@ -65,7 +65,7 @@ impl Strike<f32> {
recover_duration: self.recover_duration / stats.speed, recover_duration: self.recover_duration / stats.speed,
movement: self.movement, movement: self.movement,
ori_modifier: self.ori_modifier, 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, data.entity,
strike_data strike_data
.melee_constructor .melee_constructor
.with_combo(1 + strike_data.additional_combo) .custom_combo(strike_data.custom_combo)
.create_melee(precision_mult, tool_stats), .create_melee(precision_mult, tool_stats),
); );
} else if self.timer < strike_data.swing_duration { } else if self.timer < strike_data.swing_duration {

View File

@ -278,7 +278,7 @@ fn create_test_melee(static_data: StaticData) -> Melee {
multi_target: None, multi_target: None,
damage_effect: None, damage_effect: None,
simultaneous_hits: 1, simultaneous_hits: 1,
combo_gain: 0, custom_combo: None,
}; };
melee.create_melee(0.0, tool::Stats::one()) melee.create_melee(0.0, tool::Stats::one())
} }

View File

@ -1,6 +1,6 @@
use super::{ use super::{
super::{vek::*, Animation}, super::{vek::*, Animation},
CharacterSkeleton, SkeletonAttr, hammer_start, twist_back, twist_forward, CharacterSkeleton, SkeletonAttr,
}; };
use common::states::utils::{AbilityInfo, HandInfo, StageSection}; use common::states::utils::{AbilityInfo, HandInfo, StageSection};
use core::f32::consts::{PI, TAU}; 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;
},
_ => {}, _ => {},
} }
} }

View File

@ -319,6 +319,7 @@ image_ids! {
hammer_wide_wallop: "voxygen.element.skills.hammer.wide_wallop", hammer_wide_wallop: "voxygen.element.skills.hammer.wide_wallop",
hammer_scornful_swipe: "voxygen.element.skills.hammer.scornful_swipe", hammer_scornful_swipe: "voxygen.element.skills.hammer.scornful_swipe",
hammer_tremor: "voxygen.element.skills.hammer.tremor", hammer_tremor: "voxygen.element.skills.hammer.tremor",
hammer_vigorous_bash: "voxygen.element.skills.hammer.vigorous_bash",
// Skilltree Icons // Skilltree Icons
health_plus_skill: "voxygen.element.skills.skilltree.health_plus", health_plus_skill: "voxygen.element.skills.skilltree.health_plus",
energy_plus_skill: "voxygen.element.skills.skilltree.energy_plus", energy_plus_skill: "voxygen.element.skills.skilltree.energy_plus",

View File

@ -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.wide_wallop" => imgs.hammer_wide_wallop,
"common.abilities.hammer.scornful_swipe" => imgs.hammer_scornful_swipe, "common.abilities.hammer.scornful_swipe" => imgs.hammer_scornful_swipe,
"common.abilities.hammer.tremor" => imgs.hammer_tremor, "common.abilities.hammer.tremor" => imgs.hammer_tremor,
"common.abilities.hammer.vigorous_bash" => imgs.hammer_vigorous_bash,
// Bow // Bow
"common.abilities.bow.charged" => imgs.bow_m1, "common.abilities.bow.charged" => imgs.bow_m1,
"common.abilities.bow.repeater" => imgs.bow_m2, "common.abilities.bow.repeater" => imgs.bow_m2,