mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added support for abilities being cheaper if activated from the correct stance
This commit is contained in:
parent
0ff06edcdc
commit
af39287331
@ -3,7 +3,7 @@
|
||||
({
|
||||
Tool(Sword): (
|
||||
primary: "common.abilities.sword.balancedstance",
|
||||
secondary: "common.abilities.sword.balancedstance",
|
||||
secondary: "common.abilities.sword.lunge",
|
||||
abilities: [],
|
||||
),
|
||||
Tool(Axe): (
|
||||
|
@ -54,5 +54,6 @@ ComboMelee2(
|
||||
forward_movement: 0.0,
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
]
|
||||
],
|
||||
meta: Some(Sword(Balanced)),
|
||||
)
|
18
assets/common/abilities/sword/lunge.ron
Normal file
18
assets/common/abilities/sword/lunge.ron
Normal file
@ -0,0 +1,18 @@
|
||||
// TODO: Make actual ability, just for testing right now
|
||||
BasicMelee(
|
||||
energy_cost: 50,
|
||||
buildup_duration: 0.3,
|
||||
swing_duration: 0.1,
|
||||
recover_duration: 0.2,
|
||||
melee_constructor: (
|
||||
kind: Stab(
|
||||
damage: 10,
|
||||
poise: 0,
|
||||
knockback: 0,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 5.0,
|
||||
angle: 10.0,
|
||||
),
|
||||
meta: Some(Sword(Balanced)),
|
||||
)
|
@ -419,6 +419,7 @@ pub enum CharacterAbility {
|
||||
recover_duration: f32,
|
||||
melee_constructor: MeleeConstructor,
|
||||
ori_modifier: f32,
|
||||
meta: Option<AbilityMeta>,
|
||||
},
|
||||
BasicRanged {
|
||||
energy_cost: f32,
|
||||
@ -430,6 +431,7 @@ pub enum CharacterAbility {
|
||||
projectile_speed: f32,
|
||||
num_projectiles: u32,
|
||||
projectile_spread: f32,
|
||||
meta: Option<AbilityMeta>,
|
||||
},
|
||||
RepeaterRanged {
|
||||
energy_cost: f32,
|
||||
@ -442,12 +444,14 @@ pub enum CharacterAbility {
|
||||
projectile_body: Body,
|
||||
projectile_light: Option<LightEmitter>,
|
||||
projectile_speed: f32,
|
||||
meta: Option<AbilityMeta>,
|
||||
},
|
||||
Boost {
|
||||
movement_duration: f32,
|
||||
only_up: bool,
|
||||
speed: f32,
|
||||
max_exit_velocity: f32,
|
||||
meta: Option<AbilityMeta>,
|
||||
},
|
||||
DashMelee {
|
||||
energy_cost: f32,
|
||||
@ -461,6 +465,7 @@ pub enum CharacterAbility {
|
||||
ori_modifier: f32,
|
||||
charge_through: bool,
|
||||
is_interruptible: bool,
|
||||
meta: Option<AbilityMeta>,
|
||||
},
|
||||
BasicBlock {
|
||||
buildup_duration: f32,
|
||||
@ -468,6 +473,7 @@ pub enum CharacterAbility {
|
||||
max_angle: f32,
|
||||
block_strength: f32,
|
||||
energy_cost: f32,
|
||||
meta: Option<AbilityMeta>,
|
||||
},
|
||||
Roll {
|
||||
energy_cost: f32,
|
||||
@ -476,6 +482,7 @@ pub enum CharacterAbility {
|
||||
recover_duration: f32,
|
||||
roll_strength: f32,
|
||||
immune_melee: bool,
|
||||
meta: Option<AbilityMeta>,
|
||||
},
|
||||
ComboMelee {
|
||||
stage_data: Vec<combo_melee::Stage<f32>>,
|
||||
@ -487,9 +494,11 @@ pub enum CharacterAbility {
|
||||
scales_from_combo: u32,
|
||||
is_interruptible: bool,
|
||||
ori_modifier: f32,
|
||||
meta: Option<AbilityMeta>,
|
||||
},
|
||||
ComboMelee2 {
|
||||
strikes: Vec<combo_melee2::Strike<f32>>,
|
||||
meta: Option<AbilityMeta>,
|
||||
},
|
||||
LeapMelee {
|
||||
energy_cost: f32,
|
||||
@ -500,6 +509,7 @@ pub enum CharacterAbility {
|
||||
melee_constructor: MeleeConstructor,
|
||||
forward_leap_strength: f32,
|
||||
vertical_leap_strength: f32,
|
||||
meta: Option<AbilityMeta>,
|
||||
},
|
||||
SpinMelee {
|
||||
buildup_duration: f32,
|
||||
@ -513,6 +523,7 @@ pub enum CharacterAbility {
|
||||
num_spins: u32,
|
||||
specifier: Option<spin_melee::FrontendSpecifier>,
|
||||
melee_constructor: MeleeConstructor,
|
||||
meta: Option<AbilityMeta>,
|
||||
},
|
||||
ChargedMelee {
|
||||
energy_cost: f32,
|
||||
@ -523,6 +534,7 @@ pub enum CharacterAbility {
|
||||
recover_duration: f32,
|
||||
melee_constructor: MeleeConstructor,
|
||||
specifier: Option<charged_melee::FrontendSpecifier>,
|
||||
meta: Option<AbilityMeta>,
|
||||
},
|
||||
ChargedRanged {
|
||||
energy_cost: f32,
|
||||
@ -541,6 +553,7 @@ pub enum CharacterAbility {
|
||||
initial_projectile_speed: f32,
|
||||
scaled_projectile_speed: f32,
|
||||
move_speed: f32,
|
||||
meta: Option<AbilityMeta>,
|
||||
},
|
||||
Shockwave {
|
||||
energy_cost: f32,
|
||||
@ -559,6 +572,7 @@ pub enum CharacterAbility {
|
||||
damage_kind: DamageKind,
|
||||
specifier: comp::shockwave::FrontendSpecifier,
|
||||
damage_effect: Option<CombatEffect>,
|
||||
meta: Option<AbilityMeta>,
|
||||
},
|
||||
BasicBeam {
|
||||
buildup_duration: f32,
|
||||
@ -573,6 +587,7 @@ pub enum CharacterAbility {
|
||||
energy_drain: f32,
|
||||
ori_rate: f32,
|
||||
specifier: beam::FrontendSpecifier,
|
||||
meta: Option<AbilityMeta>,
|
||||
},
|
||||
BasicAura {
|
||||
buildup_duration: f32,
|
||||
@ -585,11 +600,13 @@ pub enum CharacterAbility {
|
||||
energy_cost: f32,
|
||||
scales_with_combo: bool,
|
||||
specifier: Option<aura::Specifier>,
|
||||
meta: Option<AbilityMeta>,
|
||||
},
|
||||
Blink {
|
||||
buildup_duration: f32,
|
||||
recover_duration: f32,
|
||||
max_range: f32,
|
||||
meta: Option<AbilityMeta>,
|
||||
},
|
||||
BasicSummon {
|
||||
buildup_duration: f32,
|
||||
@ -599,6 +616,7 @@ pub enum CharacterAbility {
|
||||
summon_distance: (f32, f32),
|
||||
summon_info: basic_summon::SummonInfo,
|
||||
duration: Option<Duration>,
|
||||
meta: Option<AbilityMeta>,
|
||||
},
|
||||
SelfBuff {
|
||||
buildup_duration: f32,
|
||||
@ -608,6 +626,7 @@ pub enum CharacterAbility {
|
||||
buff_strength: f32,
|
||||
buff_duration: Option<f32>,
|
||||
energy_cost: f32,
|
||||
meta: Option<AbilityMeta>,
|
||||
},
|
||||
SpriteSummon {
|
||||
buildup_duration: f32,
|
||||
@ -616,6 +635,7 @@ pub enum CharacterAbility {
|
||||
sprite: SpriteKind,
|
||||
summon_distance: (f32, f32),
|
||||
sparseness: f64,
|
||||
meta: Option<AbilityMeta>,
|
||||
},
|
||||
Music {
|
||||
play_duration: f32,
|
||||
@ -643,6 +663,7 @@ impl Default for CharacterAbility {
|
||||
damage_effect: None,
|
||||
},
|
||||
ori_modifier: 1.0,
|
||||
meta: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -709,6 +730,7 @@ impl CharacterAbility {
|
||||
recover_duration: 0.125,
|
||||
roll_strength: 2.0,
|
||||
immune_melee: true,
|
||||
meta: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -719,6 +741,7 @@ impl CharacterAbility {
|
||||
max_angle: 60.0,
|
||||
block_strength: 0.5,
|
||||
energy_cost: 2.5,
|
||||
meta: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -733,6 +756,7 @@ impl CharacterAbility {
|
||||
ref mut recover_duration,
|
||||
ref mut melee_constructor,
|
||||
ori_modifier: _,
|
||||
meta: _,
|
||||
} => {
|
||||
*buildup_duration /= stats.speed;
|
||||
*swing_duration /= stats.speed;
|
||||
@ -750,6 +774,7 @@ impl CharacterAbility {
|
||||
ref mut projectile_speed,
|
||||
num_projectiles: _,
|
||||
projectile_spread: _,
|
||||
meta: _,
|
||||
} => {
|
||||
*buildup_duration /= stats.speed;
|
||||
*recover_duration /= stats.speed;
|
||||
@ -768,6 +793,7 @@ impl CharacterAbility {
|
||||
projectile_body: _,
|
||||
projectile_light: _,
|
||||
ref mut projectile_speed,
|
||||
meta: _,
|
||||
} => {
|
||||
*buildup_duration /= stats.speed;
|
||||
*shoot_duration /= stats.speed;
|
||||
@ -781,6 +807,7 @@ impl CharacterAbility {
|
||||
only_up: _,
|
||||
speed: ref mut boost_speed,
|
||||
max_exit_velocity: _,
|
||||
meta: _,
|
||||
} => {
|
||||
*movement_duration /= stats.speed;
|
||||
*boost_speed *= stats.power;
|
||||
@ -797,6 +824,7 @@ impl CharacterAbility {
|
||||
ori_modifier: _,
|
||||
charge_through: _,
|
||||
is_interruptible: _,
|
||||
meta: _,
|
||||
} => {
|
||||
*buildup_duration /= stats.speed;
|
||||
*swing_duration /= stats.speed;
|
||||
@ -813,6 +841,7 @@ impl CharacterAbility {
|
||||
// Block strength explicitly not modified by power, that will be a separate stat
|
||||
block_strength: _,
|
||||
ref mut energy_cost,
|
||||
meta: _,
|
||||
} => {
|
||||
*buildup_duration /= stats.speed;
|
||||
*recover_duration /= stats.speed;
|
||||
@ -825,6 +854,7 @@ impl CharacterAbility {
|
||||
ref mut recover_duration,
|
||||
roll_strength: _,
|
||||
immune_melee: _,
|
||||
meta: _,
|
||||
} => {
|
||||
*buildup_duration /= stats.speed;
|
||||
*movement_duration /= stats.speed;
|
||||
@ -841,13 +871,17 @@ impl CharacterAbility {
|
||||
scales_from_combo: _,
|
||||
is_interruptible: _,
|
||||
ori_modifier: _,
|
||||
meta: _,
|
||||
} => {
|
||||
*stage_data = stage_data
|
||||
.iter_mut()
|
||||
.map(|s| s.adjusted_by_stats(stats))
|
||||
.collect();
|
||||
},
|
||||
ComboMelee2 { ref mut strikes } => {
|
||||
ComboMelee2 {
|
||||
ref mut strikes,
|
||||
meta: _,
|
||||
} => {
|
||||
*strikes = strikes
|
||||
.iter_mut()
|
||||
.map(|s| s.adjusted_by_stats(stats))
|
||||
@ -862,6 +896,7 @@ impl CharacterAbility {
|
||||
ref mut melee_constructor,
|
||||
forward_leap_strength: _,
|
||||
vertical_leap_strength: _,
|
||||
meta: _,
|
||||
} => {
|
||||
*buildup_duration /= stats.speed;
|
||||
*swing_duration /= stats.speed;
|
||||
@ -881,6 +916,7 @@ impl CharacterAbility {
|
||||
forward_speed: _,
|
||||
num_spins: _,
|
||||
specifier: _,
|
||||
meta: _,
|
||||
} => {
|
||||
*buildup_duration /= stats.speed;
|
||||
*swing_duration /= stats.speed;
|
||||
@ -897,6 +933,7 @@ impl CharacterAbility {
|
||||
ref mut recover_duration,
|
||||
ref mut melee_constructor,
|
||||
specifier: _,
|
||||
meta: _,
|
||||
} => {
|
||||
*swing_duration /= stats.speed;
|
||||
*recover_duration /= stats.speed;
|
||||
@ -921,6 +958,7 @@ impl CharacterAbility {
|
||||
ref mut initial_projectile_speed,
|
||||
ref mut scaled_projectile_speed,
|
||||
move_speed: _,
|
||||
meta: _,
|
||||
} => {
|
||||
*initial_damage *= stats.power;
|
||||
*scaled_damage *= stats.power;
|
||||
@ -948,6 +986,7 @@ impl CharacterAbility {
|
||||
damage_kind: _,
|
||||
specifier: _,
|
||||
ref mut damage_effect,
|
||||
meta: _,
|
||||
} => {
|
||||
*buildup_duration /= stats.speed;
|
||||
*swing_duration /= stats.speed;
|
||||
@ -979,6 +1018,7 @@ impl CharacterAbility {
|
||||
ref mut energy_drain,
|
||||
ori_rate: _,
|
||||
specifier: _,
|
||||
meta: _,
|
||||
} => {
|
||||
*buildup_duration /= stats.speed;
|
||||
*recover_duration /= stats.speed;
|
||||
@ -1009,6 +1049,7 @@ impl CharacterAbility {
|
||||
ref mut energy_cost,
|
||||
scales_with_combo: _,
|
||||
specifier: _,
|
||||
meta: _,
|
||||
} => {
|
||||
*buildup_duration /= stats.speed;
|
||||
*cast_duration /= stats.speed;
|
||||
@ -1030,6 +1071,7 @@ impl CharacterAbility {
|
||||
ref mut buildup_duration,
|
||||
ref mut recover_duration,
|
||||
ref mut max_range,
|
||||
meta: _,
|
||||
} => {
|
||||
*buildup_duration /= stats.speed;
|
||||
*recover_duration /= stats.speed;
|
||||
@ -1043,6 +1085,7 @@ impl CharacterAbility {
|
||||
summon_distance: (ref mut inner_dist, ref mut outer_dist),
|
||||
summon_info: _,
|
||||
duration: _,
|
||||
meta: _,
|
||||
} => {
|
||||
// TODO: Figure out how/if power should affect this
|
||||
*buildup_duration /= stats.speed;
|
||||
@ -1059,6 +1102,7 @@ impl CharacterAbility {
|
||||
ref mut buff_strength,
|
||||
buff_duration: _,
|
||||
ref mut energy_cost,
|
||||
meta: _,
|
||||
} => {
|
||||
*buff_strength *= stats.diminished_buff_strength();
|
||||
*buildup_duration /= stats.speed;
|
||||
@ -1073,6 +1117,7 @@ impl CharacterAbility {
|
||||
sprite: _,
|
||||
summon_distance: (ref mut inner_dist, ref mut outer_dist),
|
||||
sparseness: _,
|
||||
meta: _,
|
||||
} => {
|
||||
// TODO: Figure out how/if power should affect this
|
||||
*buildup_duration /= stats.speed;
|
||||
@ -1124,6 +1169,53 @@ impl CharacterAbility {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Maybe consider making CharacterAbility a struct at some point?
|
||||
pub fn ability_meta(&self) -> Option<AbilityMeta> {
|
||||
use CharacterAbility::*;
|
||||
match self {
|
||||
BasicMelee { meta, .. }
|
||||
| BasicRanged { meta, .. }
|
||||
| RepeaterRanged { meta, .. }
|
||||
| DashMelee { meta, .. }
|
||||
| Roll { meta, .. }
|
||||
| LeapMelee { meta, .. }
|
||||
| SpinMelee { meta, .. }
|
||||
| ChargedMelee { meta, .. }
|
||||
| ChargedRanged { meta, .. }
|
||||
| Shockwave { meta, .. }
|
||||
| BasicAura { meta, .. }
|
||||
| BasicBlock { meta, .. }
|
||||
| SelfBuff { meta, .. }
|
||||
| BasicBeam { meta, .. }
|
||||
| Boost { meta, .. }
|
||||
| ComboMelee { meta, .. }
|
||||
| ComboMelee2 { meta, .. }
|
||||
| Blink { meta, .. }
|
||||
| BasicSummon { meta, .. }
|
||||
| SpriteSummon { meta, .. } => *meta,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn contextualize(mut self, data: &JoinData) -> Self {
|
||||
if let Some(ability_info) = data.character.ability_info() {
|
||||
if let Some(AbilityMeta::Sword(old_stance)) = ability_info.ability_meta {
|
||||
if matches!(self.ability_meta(), Some(AbilityMeta::Sword(new_stance)) if old_stance == new_stance)
|
||||
{
|
||||
const ENERGY_REDUCTION: f32 = 0.75;
|
||||
use CharacterAbility::*;
|
||||
match &mut self {
|
||||
BasicMelee { energy_cost, .. } => {
|
||||
*energy_cost *= ENERGY_REDUCTION;
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use = "method returns new ability and doesn't mutate the original value"]
|
||||
pub fn adjusted_by_skills(mut self, skillset: &SkillSet, tool: Option<ToolKind>) -> Self {
|
||||
match tool {
|
||||
@ -1649,6 +1741,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
melee_constructor,
|
||||
ori_modifier,
|
||||
energy_cost: _,
|
||||
meta: _,
|
||||
} => CharacterState::BasicMelee(basic_melee::Data {
|
||||
static_data: basic_melee::StaticData {
|
||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||
@ -1672,6 +1765,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
energy_cost: _,
|
||||
num_projectiles,
|
||||
projectile_spread,
|
||||
meta: _,
|
||||
} => CharacterState::BasicRanged(basic_ranged::Data {
|
||||
static_data: basic_ranged::StaticData {
|
||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||
@ -1693,6 +1787,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
only_up,
|
||||
speed,
|
||||
max_exit_velocity,
|
||||
meta: _,
|
||||
} => CharacterState::Boost(boost::Data {
|
||||
static_data: boost::StaticData {
|
||||
movement_duration: Duration::from_secs_f32(*movement_duration),
|
||||
@ -1715,6 +1810,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
ori_modifier,
|
||||
charge_through,
|
||||
is_interruptible,
|
||||
meta: _,
|
||||
} => CharacterState::DashMelee(dash_melee::Data {
|
||||
static_data: dash_melee::StaticData {
|
||||
energy_drain: *energy_drain,
|
||||
@ -1741,6 +1837,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
max_angle,
|
||||
block_strength,
|
||||
energy_cost,
|
||||
meta: _,
|
||||
} => CharacterState::BasicBlock(basic_block::Data {
|
||||
static_data: basic_block::StaticData {
|
||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||
@ -1760,6 +1857,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
recover_duration,
|
||||
roll_strength,
|
||||
immune_melee,
|
||||
meta: _,
|
||||
} => CharacterState::Roll(roll::Data {
|
||||
static_data: roll::StaticData {
|
||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||
@ -1785,6 +1883,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
scales_from_combo,
|
||||
is_interruptible,
|
||||
ori_modifier,
|
||||
meta: _,
|
||||
} => CharacterState::ComboMelee(combo_melee::Data {
|
||||
static_data: combo_melee::StaticData {
|
||||
num_stages: stage_data.len() as u32,
|
||||
@ -1804,7 +1903,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Buildup,
|
||||
}),
|
||||
CharacterAbility::ComboMelee2 { strikes } => {
|
||||
CharacterAbility::ComboMelee2 { strikes, meta: _ } => {
|
||||
CharacterState::ComboMelee2(combo_melee2::Data {
|
||||
static_data: combo_melee2::StaticData {
|
||||
strikes: strikes.iter().map(|s| s.to_duration()).collect(),
|
||||
@ -1813,7 +1912,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
exhausted: false,
|
||||
skip_recover: false,
|
||||
timer: Duration::default(),
|
||||
stage_section: None,
|
||||
stage_section: Some(StageSection::Buildup),
|
||||
completed_strikes: 0,
|
||||
})
|
||||
},
|
||||
@ -1826,6 +1925,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
melee_constructor,
|
||||
forward_leap_strength,
|
||||
vertical_leap_strength,
|
||||
meta: _,
|
||||
} => CharacterState::LeapMelee(leap_melee::Data {
|
||||
static_data: leap_melee::StaticData {
|
||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||
@ -1853,6 +1953,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
forward_speed,
|
||||
num_spins,
|
||||
specifier,
|
||||
meta: _,
|
||||
} => CharacterState::SpinMelee(spin_melee::Data {
|
||||
static_data: spin_melee::StaticData {
|
||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||
@ -1882,6 +1983,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
recover_duration,
|
||||
melee_constructor,
|
||||
specifier,
|
||||
meta: _,
|
||||
} => CharacterState::ChargedMelee(charged_melee::Data {
|
||||
static_data: charged_melee::StaticData {
|
||||
energy_cost: *energy_cost,
|
||||
@ -1916,6 +2018,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
initial_projectile_speed,
|
||||
scaled_projectile_speed,
|
||||
move_speed,
|
||||
meta: _,
|
||||
} => CharacterState::ChargedRanged(charged_ranged::Data {
|
||||
static_data: charged_ranged::StaticData {
|
||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||
@ -1950,6 +2053,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
projectile_body,
|
||||
projectile_light,
|
||||
projectile_speed,
|
||||
meta: _,
|
||||
} => CharacterState::RepeaterRanged(repeater_ranged::Data {
|
||||
static_data: repeater_ranged::StaticData {
|
||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||
@ -1987,6 +2091,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
damage_kind,
|
||||
specifier,
|
||||
damage_effect,
|
||||
meta: _,
|
||||
} => CharacterState::Shockwave(shockwave::Data {
|
||||
static_data: shockwave::StaticData {
|
||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||
@ -2022,6 +2127,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
energy_drain,
|
||||
ori_rate,
|
||||
specifier,
|
||||
meta: _,
|
||||
} => CharacterState::BasicBeam(basic_beam::Data {
|
||||
static_data: basic_beam::StaticData {
|
||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||
@ -2052,6 +2158,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
energy_cost: _,
|
||||
scales_with_combo,
|
||||
specifier,
|
||||
meta: _,
|
||||
} => CharacterState::BasicAura(basic_aura::Data {
|
||||
static_data: basic_aura::StaticData {
|
||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||
@ -2073,6 +2180,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
buildup_duration,
|
||||
recover_duration,
|
||||
max_range,
|
||||
meta: _,
|
||||
} => CharacterState::Blink(blink::Data {
|
||||
static_data: blink::StaticData {
|
||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||
@ -2091,6 +2199,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
summon_distance,
|
||||
summon_info,
|
||||
duration,
|
||||
meta: _,
|
||||
} => CharacterState::BasicSummon(basic_summon::Data {
|
||||
static_data: basic_summon::StaticData {
|
||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||
@ -2114,6 +2223,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
buff_strength,
|
||||
buff_duration,
|
||||
energy_cost: _,
|
||||
meta: _,
|
||||
} => CharacterState::SelfBuff(self_buff::Data {
|
||||
static_data: self_buff::StaticData {
|
||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||
@ -2134,6 +2244,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
sprite,
|
||||
summon_distance,
|
||||
sparseness,
|
||||
meta: _,
|
||||
} => CharacterState::SpriteSummon(sprite_summon::Data {
|
||||
static_data: sprite_summon::StaticData {
|
||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||
@ -2164,3 +2275,22 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum AbilityMeta {
|
||||
Sword(SwordStance),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum SwordStance {
|
||||
Balanced,
|
||||
Offensive,
|
||||
Crippling,
|
||||
Cleaving,
|
||||
Defensive,
|
||||
Parrying,
|
||||
Heavy,
|
||||
Mobility,
|
||||
Reaching,
|
||||
AirSlash,
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use crate::{
|
||||
states::{
|
||||
self,
|
||||
behavior::{CharacterBehavior, JoinData},
|
||||
utils::StageSection,
|
||||
utils::{AbilityInfo, StageSection},
|
||||
*,
|
||||
},
|
||||
};
|
||||
@ -413,6 +413,44 @@ impl CharacterState {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ability_info(&self) -> Option<AbilityInfo> {
|
||||
match &self {
|
||||
CharacterState::Idle(_) => None,
|
||||
CharacterState::Talk => None,
|
||||
CharacterState::Climb(_) => None,
|
||||
CharacterState::Wallrun(_) => None,
|
||||
CharacterState::Glide(_) => None,
|
||||
CharacterState::GlideWield(_) => None,
|
||||
CharacterState::Stunned(_) => None,
|
||||
CharacterState::Sit => None,
|
||||
CharacterState::Dance => None,
|
||||
CharacterState::BasicBlock(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::Roll(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::Wielding(_) => None,
|
||||
CharacterState::Equipping(_) => None,
|
||||
CharacterState::ComboMelee(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::ComboMelee2(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::BasicMelee(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::BasicRanged(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::Boost(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::DashMelee(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::LeapMelee(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::SpinMelee(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::ChargedMelee(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::ChargedRanged(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::RepeaterRanged(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::Shockwave(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::BasicBeam(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::BasicAura(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::Blink(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::BasicSummon(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::SelfBuff(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::SpriteSummon(data) => Some(data.static_data.ability_info),
|
||||
CharacterState::UseItem(_) => None,
|
||||
CharacterState::SpriteInteract(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for CharacterState {
|
||||
|
@ -97,7 +97,9 @@ impl CharacterBehavior for Data {
|
||||
|
||||
handle_orientation(data, &mut update, 1.0, None);
|
||||
handle_move(data, &mut update, 0.7);
|
||||
handle_jump(data, output_events, &mut update, 1.0);
|
||||
if !input_is_pressed(data, InputKind::Primary) {
|
||||
handle_dodge_input(data, &mut update);
|
||||
}
|
||||
|
||||
let strike_data =
|
||||
self.static_data.strikes[self.completed_strikes % self.static_data.strikes.len()];
|
||||
@ -106,41 +108,31 @@ impl CharacterBehavior for Data {
|
||||
Some(StageSection::Buildup) => {
|
||||
if self.timer < strike_data.buildup_duration {
|
||||
// Build up
|
||||
update.character = CharacterState::ComboMelee2(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: tick_attack_or_default(data, self.timer, None),
|
||||
..*self
|
||||
});
|
||||
if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
c.timer = tick_attack_or_default(data, self.timer, None);
|
||||
}
|
||||
} else {
|
||||
// Transitions to swing section of stage
|
||||
update.character = CharacterState::ComboMelee2(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: Duration::default(),
|
||||
stage_section: Some(StageSection::Action),
|
||||
..*self
|
||||
});
|
||||
if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
c.timer = Duration::default();
|
||||
c.stage_section = Some(StageSection::Action);
|
||||
}
|
||||
}
|
||||
},
|
||||
Some(StageSection::Action) => {
|
||||
if input_is_pressed(data, InputKind::Primary) {
|
||||
update.character = CharacterState::ComboMelee2(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
skip_recover: true,
|
||||
..*self
|
||||
});
|
||||
if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
c.skip_recover = true;
|
||||
}
|
||||
}
|
||||
if self.timer.as_secs_f32()
|
||||
> strike_data.hit_timing * strike_data.swing_duration.as_secs_f32()
|
||||
&& !self.exhausted
|
||||
{
|
||||
update.character = CharacterState::ComboMelee2(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: tick_attack_or_default(data, self.timer, None),
|
||||
exhausted: true,
|
||||
skip_recover: self.skip_recover
|
||||
|| input_is_pressed(data, InputKind::Primary),
|
||||
..*self
|
||||
});
|
||||
if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
c.timer = tick_attack_or_default(data, self.timer, None);
|
||||
c.exhausted = true;
|
||||
}
|
||||
|
||||
let crit_data = get_crit_data(data, self.static_data.ability_info);
|
||||
let buff_strength = get_buff_strength(data, self.static_data.ability_info);
|
||||
@ -153,41 +145,31 @@ impl CharacterBehavior for Data {
|
||||
);
|
||||
} else if self.timer < strike_data.swing_duration {
|
||||
// Swings
|
||||
update.character = CharacterState::ComboMelee2(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: tick_attack_or_default(data, self.timer, None),
|
||||
skip_recover: self.skip_recover
|
||||
|| input_is_pressed(data, InputKind::Primary),
|
||||
..*self
|
||||
});
|
||||
if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
c.timer = tick_attack_or_default(data, self.timer, None);
|
||||
}
|
||||
} else if self.skip_recover {
|
||||
next_strike(&mut update)
|
||||
} else {
|
||||
// Transitions to recover section of stage
|
||||
update.character = CharacterState::ComboMelee2(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: Duration::default(),
|
||||
stage_section: Some(StageSection::Recover),
|
||||
..*self
|
||||
});
|
||||
if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
c.timer = Duration::default();
|
||||
c.stage_section = Some(StageSection::Recover);
|
||||
}
|
||||
}
|
||||
},
|
||||
Some(StageSection::Recover) => {
|
||||
if self.timer < strike_data.recover_duration {
|
||||
// Recovery
|
||||
update.character = CharacterState::ComboMelee2(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: tick_attack_or_default(data, self.timer, None),
|
||||
..*self
|
||||
});
|
||||
if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
c.timer = tick_attack_or_default(data, self.timer, None);
|
||||
}
|
||||
} else {
|
||||
// Done
|
||||
update.character = CharacterState::ComboMelee2(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: Duration::default(),
|
||||
stage_section: None,
|
||||
..*self
|
||||
});
|
||||
if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
c.timer = Duration::default();
|
||||
c.stage_section = None;
|
||||
}
|
||||
}
|
||||
},
|
||||
Some(_) => {
|
||||
@ -198,11 +180,9 @@ impl CharacterBehavior for Data {
|
||||
},
|
||||
None => {
|
||||
if self.timer < STANCE_TIME {
|
||||
update.character = CharacterState::ComboMelee2(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: tick_attack_or_default(data, self.timer, None),
|
||||
..*self
|
||||
});
|
||||
if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
c.timer = tick_attack_or_default(data, self.timer, None);
|
||||
}
|
||||
} else {
|
||||
// Done
|
||||
update.character =
|
||||
@ -210,17 +190,18 @@ impl CharacterBehavior for Data {
|
||||
// Make sure melee component is removed
|
||||
data.updater.remove::<Melee>(data.entity);
|
||||
}
|
||||
|
||||
handle_climb(data, &mut update);
|
||||
handle_jump(data, output_events, &mut update, 1.0);
|
||||
|
||||
if input_is_pressed(data, InputKind::Primary) {
|
||||
next_strike(&mut update)
|
||||
} else {
|
||||
attempt_input(data, output_events, &mut update);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
if !input_is_pressed(data, InputKind::Primary) {
|
||||
handle_dodge_input(data, &mut update);
|
||||
}
|
||||
|
||||
update
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ use crate::{
|
||||
astar::Astar,
|
||||
combat,
|
||||
comp::{
|
||||
ability::AbilityMeta,
|
||||
arthropod, biped_large, biped_small,
|
||||
character_state::OutputEvents,
|
||||
inventory::slot::{ArmorSlot, EquipSlot, Slot},
|
||||
@ -952,28 +953,18 @@ fn handle_ability(data: &JoinData<'_>, update: &mut StateUpdate, input: InputKin
|
||||
Some(data.body),
|
||||
)
|
||||
})
|
||||
.map(|(ability, from_offhand)| (ability.contextualize(data), from_offhand))
|
||||
.filter(|(ability, _)| ability.requirements_paid(data, update))
|
||||
{
|
||||
update.character = CharacterState::from((
|
||||
&ability,
|
||||
AbilityInfo::from_input(data, from_offhand, input),
|
||||
AbilityInfo::from_input(data, from_offhand, input, ability.ability_meta()),
|
||||
data,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_ability_input(data: &JoinData<'_>, update: &mut StateUpdate) {
|
||||
if let Some(input) = data
|
||||
.controller
|
||||
.queued_inputs
|
||||
.keys()
|
||||
.find(|i| i.is_ability())
|
||||
{
|
||||
handle_ability(data, update, *input);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_input(
|
||||
data: &JoinData<'_>,
|
||||
output_events: &mut OutputEvents,
|
||||
@ -1016,7 +1007,7 @@ pub fn handle_block_input(data: &JoinData<'_>, update: &mut StateUpdate) {
|
||||
if ability.requirements_paid(data, update) {
|
||||
update.character = CharacterState::from((
|
||||
&ability,
|
||||
AbilityInfo::from_input(data, false, InputKind::Roll),
|
||||
AbilityInfo::from_input(data, false, InputKind::Block, None),
|
||||
data,
|
||||
));
|
||||
}
|
||||
@ -1031,7 +1022,7 @@ pub fn handle_dodge_input(data: &JoinData<'_>, update: &mut StateUpdate) {
|
||||
if ability.requirements_paid(data, update) {
|
||||
update.character = CharacterState::from((
|
||||
&ability,
|
||||
AbilityInfo::from_input(data, false, InputKind::Roll),
|
||||
AbilityInfo::from_input(data, false, InputKind::Roll, None),
|
||||
data,
|
||||
));
|
||||
if let CharacterState::Roll(roll) = &mut update.character {
|
||||
@ -1218,10 +1209,16 @@ pub struct AbilityInfo {
|
||||
pub hand: Option<HandInfo>,
|
||||
pub input: InputKind,
|
||||
pub input_attr: Option<InputAttr>,
|
||||
pub ability_meta: Option<AbilityMeta>,
|
||||
}
|
||||
|
||||
impl AbilityInfo {
|
||||
pub fn from_input(data: &JoinData<'_>, from_offhand: bool, input: InputKind) -> Self {
|
||||
pub fn from_input(
|
||||
data: &JoinData<'_>,
|
||||
from_offhand: bool,
|
||||
input: InputKind,
|
||||
ability_meta: Option<AbilityMeta>,
|
||||
) -> Self {
|
||||
let tool_data = if from_offhand {
|
||||
unwrap_tool_data(data, EquipSlot::ActiveOffhand)
|
||||
} else {
|
||||
@ -1239,6 +1236,7 @@ impl AbilityInfo {
|
||||
hand,
|
||||
input,
|
||||
input_attr: data.controller.queued_inputs.get(&input).copied(),
|
||||
ability_meta,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -241,5 +241,6 @@ fn empty_ability_info() -> states::utils::AbilityInfo {
|
||||
hand: None,
|
||||
input: InputKind::Primary,
|
||||
input_attr: None,
|
||||
ability_meta: None,
|
||||
}
|
||||
}
|
||||
|
@ -293,5 +293,6 @@ fn empty_ability_info() -> states::utils::AbilityInfo {
|
||||
hand: None,
|
||||
input: InputKind::Primary,
|
||||
input_attr: None,
|
||||
ability_meta: None,
|
||||
}
|
||||
}
|
||||
|
@ -1626,8 +1626,9 @@ impl FigureMgr {
|
||||
CharacterState::ComboMelee2(s) => {
|
||||
if let Some(stage_section) = s.stage_section {
|
||||
let timer = s.timer.as_secs_f32();
|
||||
let strike_data = s.static_data.strikes
|
||||
[s.completed_strikes % s.static_data.strikes.len()];
|
||||
let current_strike =
|
||||
s.completed_strikes % s.static_data.strikes.len();
|
||||
let strike_data = s.static_data.strikes[current_strike];
|
||||
let progress = match stage_section {
|
||||
StageSection::Buildup => {
|
||||
timer / strike_data.buildup_duration.as_secs_f32()
|
||||
@ -1640,8 +1641,6 @@ impl FigureMgr {
|
||||
},
|
||||
_ => 0.0,
|
||||
};
|
||||
let current_strike =
|
||||
s.completed_strikes % s.static_data.strikes.len();
|
||||
|
||||
anim::character::ComboAnimation::update_skeleton(
|
||||
&target_base,
|
||||
|
Loading…
Reference in New Issue
Block a user