mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Crippling strike now functional. Crippled debuff added.
This commit is contained in:
parent
3e5d9932e9
commit
c79c929e9f
@ -208,10 +208,10 @@
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
Custom("Minotaur"): (
|
Custom("Minotaur"): (
|
||||||
primary: "common.abilities.custom.minotaur.charge",
|
primary: "common.abilities.custom.minotaur.cleave",
|
||||||
secondary: "common.abilities.custom.minotaur.cripplingstrike",
|
secondary: "common.abilities.custom.minotaur.cripplingstrike",
|
||||||
abilities: [
|
abilities: [
|
||||||
(None, "common.abilities.custom.minotaur.cleave"),
|
(None, "common.abilities.custom.minotaur.charge"),
|
||||||
(None, "common.abilities.custom.minotaur.frenzy"),
|
(None, "common.abilities.custom.minotaur.frenzy"),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -8,4 +8,5 @@ BasicMelee(
|
|||||||
base_poise_damage: 40,
|
base_poise_damage: 40,
|
||||||
range: 5.0,
|
range: 5.0,
|
||||||
max_angle: 120.0,
|
max_angle: 120.0,
|
||||||
|
damage_effect: None,
|
||||||
)
|
)
|
||||||
|
@ -1,19 +1,17 @@
|
|||||||
DashMelee(
|
BasicMelee(
|
||||||
energy_cost: 0,
|
energy_cost: 0,
|
||||||
base_damage: 300,
|
buildup_duration: 0.3,
|
||||||
scaled_damage: 1200,
|
swing_duration: 0.2,
|
||||||
base_poise_damage: 25,
|
recover_duration: 0.6,
|
||||||
scaled_poise_damage: 100,
|
base_damage: 250.0,
|
||||||
base_knockback: 10.0,
|
base_poise_damage: 60.0,
|
||||||
scaled_knockback: 30.0,
|
knockback: 25.0,
|
||||||
range: 7.5,
|
range: 5.0,
|
||||||
angle: 90.0,
|
max_angle: 90.0,
|
||||||
energy_drain: 0,
|
damage_effect: Some(Buff((
|
||||||
forward_speed: 5.0,
|
kind: Crippled,
|
||||||
buildup_duration: 0.4,
|
dur_secs: 15.0,
|
||||||
charge_duration: 4.0,
|
strength: Value(0.5),
|
||||||
swing_duration: 0.1,
|
chance: 1.0,
|
||||||
recover_duration: 0.5,
|
))),
|
||||||
infinite_charge: false,
|
|
||||||
is_interruptible: false,
|
|
||||||
)
|
)
|
@ -8,4 +8,5 @@ BasicMelee(
|
|||||||
knockback: 25.0,
|
knockback: 25.0,
|
||||||
range: 1.2,
|
range: 1.2,
|
||||||
max_angle: 50.0,
|
max_angle: 50.0,
|
||||||
|
damage_effect: None,
|
||||||
)
|
)
|
||||||
|
@ -8,4 +8,5 @@ BasicMelee(
|
|||||||
knockback: 0.0,
|
knockback: 0.0,
|
||||||
range: 3.5,
|
range: 3.5,
|
||||||
max_angle: 20.0,
|
max_angle: 20.0,
|
||||||
|
damage_effect: None,
|
||||||
)
|
)
|
||||||
|
@ -8,4 +8,5 @@ BasicMelee(
|
|||||||
knockback: 0.0,
|
knockback: 0.0,
|
||||||
range: 3.5,
|
range: 3.5,
|
||||||
max_angle: 15.0,
|
max_angle: 15.0,
|
||||||
|
damage_effect: None,
|
||||||
)
|
)
|
||||||
|
@ -8,4 +8,5 @@ BasicMelee(
|
|||||||
knockback: 0.0,
|
knockback: 0.0,
|
||||||
range: 3.5,
|
range: 3.5,
|
||||||
max_angle: 20.0,
|
max_angle: 20.0,
|
||||||
|
damage_effect: None,
|
||||||
)
|
)
|
||||||
|
@ -8,4 +8,5 @@ BasicMelee(
|
|||||||
knockback: 0.0,
|
knockback: 0.0,
|
||||||
range: 3.5,
|
range: 3.5,
|
||||||
max_angle: 20.0,
|
max_angle: 20.0,
|
||||||
|
damage_effect: None,
|
||||||
)
|
)
|
||||||
|
@ -8,4 +8,5 @@ BasicMelee(
|
|||||||
knockback: 0.0,
|
knockback: 0.0,
|
||||||
range: 3.0,
|
range: 3.0,
|
||||||
max_angle: 120.0,
|
max_angle: 120.0,
|
||||||
|
damage_effect: None,
|
||||||
)
|
)
|
||||||
|
@ -66,6 +66,7 @@ pub enum CharacterAbility {
|
|||||||
knockback: f32,
|
knockback: f32,
|
||||||
range: f32,
|
range: f32,
|
||||||
max_angle: f32,
|
max_angle: f32,
|
||||||
|
damage_effect: Option<CombatEffect>,
|
||||||
},
|
},
|
||||||
BasicRanged {
|
BasicRanged {
|
||||||
energy_cost: f32,
|
energy_cost: f32,
|
||||||
@ -282,6 +283,7 @@ impl Default for CharacterAbility {
|
|||||||
knockback: 0.0,
|
knockback: 0.0,
|
||||||
range: 3.5,
|
range: 3.5,
|
||||||
max_angle: 15.0,
|
max_angle: 15.0,
|
||||||
|
damage_effect: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1164,6 +1166,7 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
|
|||||||
knockback,
|
knockback,
|
||||||
range,
|
range,
|
||||||
max_angle,
|
max_angle,
|
||||||
|
damage_effect,
|
||||||
energy_cost: _,
|
energy_cost: _,
|
||||||
} => CharacterState::BasicMelee(basic_melee::Data {
|
} => CharacterState::BasicMelee(basic_melee::Data {
|
||||||
static_data: basic_melee::StaticData {
|
static_data: basic_melee::StaticData {
|
||||||
@ -1175,6 +1178,7 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
|
|||||||
knockback: *knockback,
|
knockback: *knockback,
|
||||||
range: *range,
|
range: *range,
|
||||||
max_angle: *max_angle,
|
max_angle: *max_angle,
|
||||||
|
damage_effect: *damage_effect,
|
||||||
ability_info,
|
ability_info,
|
||||||
},
|
},
|
||||||
timer: Duration::default(),
|
timer: Duration::default(),
|
||||||
|
@ -36,6 +36,8 @@ pub enum BuffKind {
|
|||||||
Invulnerability,
|
Invulnerability,
|
||||||
/// Reduces incoming damage
|
/// Reduces incoming damage
|
||||||
ProtectingWard,
|
ProtectingWard,
|
||||||
|
/// Reduces movement speed and causes bleeding damage
|
||||||
|
Crippled,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
@ -54,6 +56,7 @@ impl BuffKind {
|
|||||||
BuffKind::Invulnerability => true,
|
BuffKind::Invulnerability => true,
|
||||||
BuffKind::ProtectingWard => true,
|
BuffKind::ProtectingWard => true,
|
||||||
BuffKind::Burning => false,
|
BuffKind::Burning => false,
|
||||||
|
BuffKind::Crippled => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,6 +121,8 @@ pub enum BuffEffect {
|
|||||||
kind: ModifierKind,
|
kind: ModifierKind,
|
||||||
target_fraction: f32,
|
target_fraction: f32,
|
||||||
},
|
},
|
||||||
|
/// Modifies move speed of target
|
||||||
|
MovementSpeed(f32),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Actual de/buff.
|
/// Actual de/buff.
|
||||||
@ -174,6 +179,8 @@ impl Buff {
|
|||||||
cat_ids: Vec<BuffCategory>,
|
cat_ids: Vec<BuffCategory>,
|
||||||
source: BuffSource,
|
source: BuffSource,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
// Normalized nonlinear scaling
|
||||||
|
let nn_scaling = |a| a / (a + 0.5);
|
||||||
let (effects, time) = match kind {
|
let (effects, time) = match kind {
|
||||||
BuffKind::Bleeding => (
|
BuffKind::Bleeding => (
|
||||||
vec![BuffEffect::HealthChangeOverTime {
|
vec![BuffEffect::HealthChangeOverTime {
|
||||||
@ -235,7 +242,7 @@ impl Buff {
|
|||||||
// Causes non-linearity in effect strength, but necessary to allow for tool
|
// Causes non-linearity in effect strength, but necessary to allow for tool
|
||||||
// power and other things to affect the strength. 0.5 also still provides 50%
|
// power and other things to affect the strength. 0.5 also still provides 50%
|
||||||
// damage reduction.
|
// damage reduction.
|
||||||
data.strength / (0.5 + data.strength),
|
nn_scaling(data.strength),
|
||||||
)],
|
)],
|
||||||
data.duration,
|
data.duration,
|
||||||
),
|
),
|
||||||
@ -247,6 +254,17 @@ impl Buff {
|
|||||||
}],
|
}],
|
||||||
data.duration,
|
data.duration,
|
||||||
),
|
),
|
||||||
|
BuffKind::Crippled => (
|
||||||
|
vec![
|
||||||
|
BuffEffect::MovementSpeed(1.0 - nn_scaling(data.strength)),
|
||||||
|
BuffEffect::HealthChangeOverTime {
|
||||||
|
rate: -data.strength * 100.0,
|
||||||
|
accumulated: 0.0,
|
||||||
|
kind: ModifierKind::Additive,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
data.duration,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
Buff {
|
Buff {
|
||||||
kind,
|
kind,
|
||||||
|
@ -25,6 +25,7 @@ pub struct Stats {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
pub damage_reduction: f32,
|
pub damage_reduction: f32,
|
||||||
pub max_health_modifier: f32,
|
pub max_health_modifier: f32,
|
||||||
|
pub move_speed_modifier: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stats {
|
impl Stats {
|
||||||
@ -33,6 +34,7 @@ impl Stats {
|
|||||||
name,
|
name,
|
||||||
damage_reduction: 0.0,
|
damage_reduction: 0.0,
|
||||||
max_health_modifier: 1.0,
|
max_health_modifier: 1.0,
|
||||||
|
move_speed_modifier: 1.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +45,7 @@ impl Stats {
|
|||||||
name: "".to_owned(),
|
name: "".to_owned(),
|
||||||
damage_reduction: 0.0,
|
damage_reduction: 0.0,
|
||||||
max_health_modifier: 1.0,
|
max_health_modifier: 1.0,
|
||||||
|
move_speed_modifier: 1.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,6 +53,7 @@ impl Stats {
|
|||||||
pub fn reset_temp_modifiers(&mut self) {
|
pub fn reset_temp_modifiers(&mut self) {
|
||||||
self.damage_reduction = 0.0;
|
self.damage_reduction = 0.0;
|
||||||
self.max_health_modifier = 1.0;
|
self.max_health_modifier = 1.0;
|
||||||
|
self.move_speed_modifier = 1.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,8 @@ pub struct StaticData {
|
|||||||
pub range: f32,
|
pub range: f32,
|
||||||
/// Max angle (45.0 will give you a 90.0 angle window)
|
/// Max angle (45.0 will give you a 90.0 angle window)
|
||||||
pub max_angle: f32,
|
pub max_angle: f32,
|
||||||
|
/// Adds an effect onto the main damage of the attack
|
||||||
|
pub damage_effect: Option<CombatEffect>,
|
||||||
/// What key is used to press ability
|
/// What key is used to press ability
|
||||||
pub ability_info: AbilityInfo,
|
pub ability_info: AbilityInfo,
|
||||||
}
|
}
|
||||||
@ -97,15 +99,20 @@ impl CharacterBehavior for Data {
|
|||||||
.with_requirement(CombatRequirement::AnyDamage);
|
.with_requirement(CombatRequirement::AnyDamage);
|
||||||
let energy = AttackEffect::new(None, CombatEffect::EnergyReward(50.0))
|
let energy = AttackEffect::new(None, CombatEffect::EnergyReward(50.0))
|
||||||
.with_requirement(CombatRequirement::AnyDamage);
|
.with_requirement(CombatRequirement::AnyDamage);
|
||||||
let buff = CombatEffect::Buff(CombatBuff::default_physical());
|
let mut damage = AttackDamage::new(
|
||||||
let damage = AttackDamage::new(
|
|
||||||
Damage {
|
Damage {
|
||||||
source: DamageSource::Melee,
|
source: DamageSource::Melee,
|
||||||
value: self.static_data.base_damage as f32,
|
value: self.static_data.base_damage as f32,
|
||||||
},
|
},
|
||||||
Some(GroupTarget::OutOfGroup),
|
Some(GroupTarget::OutOfGroup),
|
||||||
)
|
);
|
||||||
.with_effect(buff);
|
match self.static_data.damage_effect {
|
||||||
|
Some(effect) => damage = damage.with_effect(effect),
|
||||||
|
None => {
|
||||||
|
let buff = CombatEffect::Buff(CombatBuff::default_physical());
|
||||||
|
damage = damage.with_effect(buff);
|
||||||
|
},
|
||||||
|
}
|
||||||
let (crit_chance, crit_mult) =
|
let (crit_chance, crit_mult) =
|
||||||
get_crit_data(data, self.static_data.ability_info);
|
get_crit_data(data, self.static_data.ability_info);
|
||||||
let attack = Attack::default()
|
let attack = Attack::default()
|
||||||
|
@ -71,7 +71,6 @@ impl CharacterBehavior for Data {
|
|||||||
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
||||||
let mut update = StateUpdate::from(data);
|
let mut update = StateUpdate::from(data);
|
||||||
|
|
||||||
handle_orientation(data, &mut update, 1.0);
|
|
||||||
handle_move(data, &mut update, 0.1);
|
handle_move(data, &mut update, 0.1);
|
||||||
|
|
||||||
match self.stage_section {
|
match self.stage_section {
|
||||||
|
@ -175,7 +175,6 @@ impl CharacterBehavior for Data {
|
|||||||
},
|
},
|
||||||
0.1,
|
0.1,
|
||||||
);
|
);
|
||||||
handle_orientation(data, &mut update, 1.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Swings
|
// Swings
|
||||||
|
@ -243,6 +243,8 @@ pub fn handle_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32) {
|
|||||||
/// Updates components to move player as if theyre on ground or in air
|
/// Updates components to move player as if theyre on ground or in air
|
||||||
#[allow(clippy::assign_op_pattern)] // TODO: Pending review in #587
|
#[allow(clippy::assign_op_pattern)] // TODO: Pending review in #587
|
||||||
fn basic_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32) {
|
fn basic_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32) {
|
||||||
|
let efficiency = efficiency * data.stats.move_speed_modifier;
|
||||||
|
|
||||||
let accel = if data.physics.on_ground {
|
let accel = if data.physics.on_ground {
|
||||||
data.body.base_accel()
|
data.body.base_accel()
|
||||||
} else {
|
} else {
|
||||||
@ -267,6 +269,8 @@ pub fn handle_forced_movement(
|
|||||||
movement: ForcedMovement,
|
movement: ForcedMovement,
|
||||||
efficiency: f32,
|
efficiency: f32,
|
||||||
) {
|
) {
|
||||||
|
let efficiency = efficiency * data.stats.move_speed_modifier;
|
||||||
|
|
||||||
match movement {
|
match movement {
|
||||||
ForcedMovement::Forward { strength } => {
|
ForcedMovement::Forward { strength } => {
|
||||||
if let Some(accel) = data.physics.on_ground.then_some(data.body.base_accel()) {
|
if let Some(accel) = data.physics.on_ground.then_some(data.body.base_accel()) {
|
||||||
@ -324,6 +328,7 @@ pub fn handle_orientation(data: &JoinData, update: &mut StateUpdate, efficiency:
|
|||||||
|
|
||||||
/// Updates components to move player as if theyre swimming
|
/// Updates components to move player as if theyre swimming
|
||||||
fn swim_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32, submersion: f32) -> bool {
|
fn swim_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32, submersion: f32) -> bool {
|
||||||
|
let efficiency = efficiency * data.stats.move_speed_modifier;
|
||||||
if let Some(force) = data.body.swim_thrust() {
|
if let Some(force) = data.body.swim_thrust() {
|
||||||
let force = efficiency * force;
|
let force = efficiency * force;
|
||||||
let mut water_accel = force / data.mass.0;
|
let mut water_accel = force / data.mass.0;
|
||||||
@ -361,6 +366,8 @@ fn swim_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32, submers
|
|||||||
|
|
||||||
/// Updates components to move entity as if it's flying
|
/// Updates components to move entity as if it's flying
|
||||||
pub fn fly_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32) -> bool {
|
pub fn fly_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32) -> bool {
|
||||||
|
let efficiency = efficiency * data.stats.move_speed_modifier;
|
||||||
|
|
||||||
let glider = match data.character {
|
let glider = match data.character {
|
||||||
CharacterState::Glide(data) => Some(data),
|
CharacterState::Glide(data) => Some(data),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -189,6 +189,9 @@ impl<'a> System<'a> for Sys {
|
|||||||
stat.max_health_modifier *= current_fraction;
|
stat.max_health_modifier *= current_fraction;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
BuffEffect::MovementSpeed(ms) => {
|
||||||
|
stat.move_speed_modifier *= *ms;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3626,6 +3626,8 @@ pub fn get_buff_image(buff: BuffKind, imgs: &Imgs) -> conrod_core::image::Id {
|
|||||||
BuffKind::Bleeding { .. } => imgs.debuff_bleed_0,
|
BuffKind::Bleeding { .. } => imgs.debuff_bleed_0,
|
||||||
BuffKind::Cursed { .. } => imgs.debuff_skull_0,
|
BuffKind::Cursed { .. } => imgs.debuff_skull_0,
|
||||||
BuffKind::Burning { .. } => imgs.debuff_burning_0,
|
BuffKind::Burning { .. } => imgs.debuff_burning_0,
|
||||||
|
// TODO: Get buff icon
|
||||||
|
BuffKind::Crippled { .. } => imgs.debuff_bleed_0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3644,6 +3646,7 @@ pub fn get_buff_title(buff: BuffKind, localized_strings: &Localization) -> &str
|
|||||||
BuffKind::Bleeding { .. } => localized_strings.get("buff.title.bleed"),
|
BuffKind::Bleeding { .. } => localized_strings.get("buff.title.bleed"),
|
||||||
BuffKind::Cursed { .. } => localized_strings.get("buff.title.cursed"),
|
BuffKind::Cursed { .. } => localized_strings.get("buff.title.cursed"),
|
||||||
BuffKind::Burning { .. } => localized_strings.get("buff.title.burn"),
|
BuffKind::Burning { .. } => localized_strings.get("buff.title.burn"),
|
||||||
|
BuffKind::Crippled { .. } => localized_strings.get("buff.title.crippled"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3674,6 +3677,7 @@ pub fn get_buff_desc(buff: BuffKind, data: BuffData, localized_strings: &Localiz
|
|||||||
BuffKind::Bleeding { .. } => Cow::Borrowed(localized_strings.get("buff.desc.bleed")),
|
BuffKind::Bleeding { .. } => Cow::Borrowed(localized_strings.get("buff.desc.bleed")),
|
||||||
BuffKind::Cursed { .. } => Cow::Borrowed(localized_strings.get("buff.desc.cursed")),
|
BuffKind::Cursed { .. } => Cow::Borrowed(localized_strings.get("buff.desc.cursed")),
|
||||||
BuffKind::Burning { .. } => Cow::Borrowed(localized_strings.get("buff.desc.burn")),
|
BuffKind::Burning { .. } => Cow::Borrowed(localized_strings.get("buff.desc.burn")),
|
||||||
|
BuffKind::Crippled { .. } => Cow::Borrowed(localized_strings.get("buff.desc.crippled")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,8 @@ pub fn consumable_desc(effects: &[Effect], i18n: &Localization) -> String {
|
|||||||
| BuffKind::Burning
|
| BuffKind::Burning
|
||||||
| BuffKind::CampfireHeal
|
| BuffKind::CampfireHeal
|
||||||
| BuffKind::Cursed
|
| BuffKind::Cursed
|
||||||
| BuffKind::ProtectingWard => continue,
|
| BuffKind::ProtectingWard
|
||||||
|
| BuffKind::Crippled => continue,
|
||||||
};
|
};
|
||||||
|
|
||||||
write!(&mut description, "{}", buff_desc).unwrap();
|
write!(&mut description, "{}", buff_desc).unwrap();
|
||||||
@ -138,7 +139,8 @@ pub fn consumable_desc(effects: &[Effect], i18n: &Localization) -> String {
|
|||||||
| BuffKind::Potion
|
| BuffKind::Potion
|
||||||
| BuffKind::CampfireHeal
|
| BuffKind::CampfireHeal
|
||||||
| BuffKind::Cursed
|
| BuffKind::Cursed
|
||||||
| BuffKind::ProtectingWard => continue,
|
| BuffKind::ProtectingWard
|
||||||
|
| BuffKind::Crippled => continue,
|
||||||
}
|
}
|
||||||
} else if let BuffKind::Saturation | BuffKind::Regeneration = buff.kind {
|
} else if let BuffKind::Saturation | BuffKind::Regeneration = buff.kind {
|
||||||
i18n.get("buff.text.every_second").to_string()
|
i18n.get("buff.text.every_second").to_string()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user