From 3d42e2812d98c92b6dcfda4562da0fd8cd062c6e Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 29 Jan 2021 23:40:03 -0500 Subject: [PATCH] Attacks can now deal poise damage. --- common/src/combat.rs | 18 ++++++++++++++++++ common/src/comp/character_state.rs | 2 +- common/src/comp/poise.rs | 11 +++++++++++ common/src/states/basic_melee.rs | 8 ++++++-- common/src/states/charged_melee.rs | 23 ++++++++++++----------- common/src/states/combo_melee.rs | 13 +++++++------ common/src/states/dash_melee.rs | 23 ++++++++++++----------- common/src/states/leap_melee.rs | 14 +++++++++++--- common/src/states/spin_melee.rs | 15 ++++++++++----- 9 files changed, 88 insertions(+), 39 deletions(-) diff --git a/common/src/combat.rs b/common/src/combat.rs index 8c8bfdca3a..d2d59948e0 100644 --- a/common/src/combat.rs +++ b/common/src/combat.rs @@ -9,6 +9,7 @@ use crate::{ }, slot::EquipSlot, }, + poise::PoiseChange, skills::{SkillGroupKind, SkillSet}, Body, EnergyChange, EnergySource, Health, HealthChange, HealthSource, Inventory, Stats, }, @@ -139,6 +140,14 @@ impl Attack { change, }); }, + AttackEffect::Poise(p) => { + let change = PoiseChange::from_attack(*p, inventory); + server_events.push(ServerEvent::PoiseChange { + entity: target_entity, + change, + kb_dir: *dir, + }); + }, } } } @@ -194,6 +203,14 @@ impl Attack { change, }); }, + AttackEffect::Poise(p) => { + let change = PoiseChange::from_attack(p, inventory); + server_events.push(ServerEvent::PoiseChange { + entity: target_entity, + change, + kb_dir: *dir, + }); + }, } } } @@ -252,6 +269,7 @@ pub enum AttackEffect { Knockback(Knockback), EnergyReward(u32), Lifesteal(f32), + Poise(f32), } #[derive(Clone, Debug, Serialize, Deserialize)] diff --git a/common/src/comp/character_state.rs b/common/src/comp/character_state.rs index 5c6711edf4..d0fb1541d1 100644 --- a/common/src/comp/character_state.rs +++ b/common/src/comp/character_state.rs @@ -1,6 +1,6 @@ use crate::{ combat::Attack, - comp::{Energy, Ori, PoiseChange, Pos, Vel}, + comp::{Energy, Ori, Pos, Vel}, event::{LocalEvent, ServerEvent}, states::{behavior::JoinData, *}, }; diff --git a/common/src/comp/poise.rs b/common/src/comp/poise.rs index 73864e0ace..ab2ffb46f4 100644 --- a/common/src/comp/poise.rs +++ b/common/src/comp/poise.rs @@ -31,6 +31,17 @@ impl PoiseChange { source: self.source, } } + + /// Creates a poise change from an attack + pub fn from_attack(poise_damage: f32, inventory: Option<&Inventory>) -> Self { + let poise_damage_reduction = + inventory.map_or(0.0, |inv| Poise::compute_poise_damage_reduction(inv)); + let poise_change = -poise_damage * (1.0 - poise_damage_reduction); + Self { + amount: poise_change as i32, + source: PoiseSource::Attack, + } + } } /// Sources of poise change diff --git a/common/src/states/basic_melee.rs b/common/src/states/basic_melee.rs index a7aa3d8b84..5b1bd9b9c9 100644 --- a/common/src/states/basic_melee.rs +++ b/common/src/states/basic_melee.rs @@ -2,7 +2,7 @@ use crate::{ combat::{ Attack, AttackEffect, CombatBuff, CombatRequirement, DamageComponent, EffectComponent, }, - comp::{CharacterState, MeleeAttack, PoiseChange, PoiseSource, StateUpdate}, + comp::{CharacterState, MeleeAttack, StateUpdate}, states::{ behavior::{CharacterBehavior, JoinData}, utils::*, @@ -96,6 +96,9 @@ impl CharacterBehavior for Data { source: DamageSource::Melee, value: self.static_data.base_damage as f32, }; + let poise = AttackEffect::Poise(self.static_data.base_poise_damage as f32); + let poise = EffectComponent::new(Some(GroupTarget::OutOfGroup), poise) + .with_requirement(CombatRequirement::AnyDamage); let knockback = AttackEffect::Knockback(Knockback { strength: self.static_data.knockback, direction: KnockbackDir::Away, @@ -110,7 +113,8 @@ impl CharacterBehavior for Data { let attack = Attack::default() .with_damage(damage) .with_crit(0.5, 1.3) - .with_effect(energy); + .with_effect(energy) + .with_effect(poise); // Hit attempt data.updater.insert(data.entity, MeleeAttack { diff --git a/common/src/states/charged_melee.rs b/common/src/states/charged_melee.rs index 2a17c0bc9b..2558d133cb 100644 --- a/common/src/states/charged_melee.rs +++ b/common/src/states/charged_melee.rs @@ -1,9 +1,8 @@ use crate::{ - combat::{Attack, AttackEffect, CombatBuff, DamageComponent}, - comp::{ - CharacterState, EnergyChange, EnergySource, MeleeAttack, PoiseChange, PoiseSource, - StateUpdate, + combat::{ + Attack, AttackEffect, CombatBuff, CombatRequirement, DamageComponent, EffectComponent, }, + comp::{CharacterState, EnergyChange, EnergySource, MeleeAttack, StateUpdate}, states::{ behavior::{CharacterBehavior, JoinData}, utils::{StageSection, *}, @@ -161,12 +160,11 @@ impl CharacterBehavior for Data { value: self.static_data.initial_damage as f32 + self.charge_amount * self.static_data.scaled_damage as f32, }; - let poise_damage = PoiseChange { - amount: -(self.static_data.initial_poise_damage as f32 - + self.charge_amount * self.static_data.scaled_poise_damage as f32) - as i32, - source: PoiseSource::Attack, - }; + let poise = self.static_data.initial_poise_damage as f32 + + self.charge_amount * self.static_data.scaled_poise_damage as f32; + let poise = AttackEffect::Poise(poise); + let poise = EffectComponent::new(Some(GroupTarget::OutOfGroup), poise) + .with_requirement(CombatRequirement::AnyDamage); let knockback = self.static_data.initial_knockback + self.charge_amount * self.static_data.scaled_knockback; let knockback = AttackEffect::Knockback(Knockback { @@ -177,7 +175,10 @@ impl CharacterBehavior for Data { let damage = DamageComponent::new(damage, Some(GroupTarget::OutOfGroup)) .with_effect(knockback) .with_effect(buff); - let attack = Attack::default().with_damage(damage).with_crit(0.5, 1.3); + let attack = Attack::default() + .with_damage(damage) + .with_crit(0.5, 1.3) + .with_effect(poise); // Hit attempt data.updater.insert(data.entity, MeleeAttack { diff --git a/common/src/states/combo_melee.rs b/common/src/states/combo_melee.rs index c8fd627d8f..85763ff24b 100644 --- a/common/src/states/combo_melee.rs +++ b/common/src/states/combo_melee.rs @@ -2,10 +2,7 @@ use crate::{ combat::{ Attack, AttackEffect, CombatBuff, CombatRequirement, DamageComponent, EffectComponent, }, - comp::{ - CharacterState, EnergyChange, EnergySource, MeleeAttack, PoiseChange, PoiseSource, - StateUpdate, - }, + comp::{CharacterState, MeleeAttack, StateUpdate}, states::{ behavior::{CharacterBehavior, JoinData}, utils::*, @@ -178,12 +175,15 @@ impl CharacterBehavior for Data { .min(self.combo / self.static_data.num_stages) * self.static_data.stage_data[stage_index].damage_increase; - let poise_damage = self.static_data.stage_data[stage_index].base_poise_damage + let poise = self.static_data.stage_data[stage_index].base_poise_damage + self .static_data .scales_from_combo .min(self.combo / self.static_data.num_stages) * self.static_data.stage_data[stage_index].poise_damage_increase; + let poise = AttackEffect::Poise(poise as f32); + let poise = EffectComponent::new(Some(GroupTarget::OutOfGroup), poise) + .with_requirement(CombatRequirement::AnyDamage); let damage = Damage { source: DamageSource::Melee, @@ -207,7 +207,8 @@ impl CharacterBehavior for Data { let attack = Attack::default() .with_damage(damage) .with_crit(0.5, 1.3) - .with_effect(energy); + .with_effect(energy) + .with_effect(poise); data.updater.insert(data.entity, MeleeAttack { attack, diff --git a/common/src/states/dash_melee.rs b/common/src/states/dash_melee.rs index 53a023cd02..93e73ec006 100644 --- a/common/src/states/dash_melee.rs +++ b/common/src/states/dash_melee.rs @@ -1,9 +1,8 @@ use crate::{ - combat::{Attack, AttackEffect, CombatBuff, DamageComponent}, - comp::{ - CharacterState, EnergyChange, EnergySource, MeleeAttack, PoiseChange, PoiseSource, - StateUpdate, + combat::{ + Attack, AttackEffect, CombatBuff, CombatRequirement, DamageComponent, EffectComponent, }, + comp::{CharacterState, EnergyChange, EnergySource, MeleeAttack, StateUpdate}, states::{ behavior::{CharacterBehavior, JoinData}, utils::*, @@ -138,12 +137,11 @@ impl CharacterBehavior for Data { value: self.static_data.base_damage as f32 + charge_frac * self.static_data.scaled_damage as f32, }; - let poise_damage = PoiseChange { - amount: -(self.static_data.base_poise_damage as f32 - + charge_frac * self.static_data.scaled_poise_damage as f32) - as i32, - source: PoiseSource::Attack, - }; + let poise = self.static_data.base_poise_damage as f32 + + charge_frac * self.static_data.scaled_poise_damage as f32; + let poise = AttackEffect::Poise(poise); + let poise = EffectComponent::new(Some(GroupTarget::OutOfGroup), poise) + .with_requirement(CombatRequirement::AnyDamage); let knockback = self.static_data.base_knockback + charge_frac * self.static_data.scaled_knockback; let knockback = AttackEffect::Knockback(Knockback { @@ -155,7 +153,10 @@ impl CharacterBehavior for Data { DamageComponent::new(damage, Some(GroupTarget::OutOfGroup)) .with_effect(knockback) .with_effect(buff); - let attack = Attack::default().with_damage(damage).with_crit(0.5, 1.3); + let attack = Attack::default() + .with_damage(damage) + .with_crit(0.5, 1.3) + .with_effect(poise); data.updater.insert(data.entity, MeleeAttack { attack, diff --git a/common/src/states/leap_melee.rs b/common/src/states/leap_melee.rs index b6463d2e86..d6bb8a2e9b 100644 --- a/common/src/states/leap_melee.rs +++ b/common/src/states/leap_melee.rs @@ -1,6 +1,8 @@ use crate::{ - combat::{Attack, AttackEffect, CombatBuff, DamageComponent}, - comp::{CharacterState, MeleeAttack, PoiseChange, PoiseSource, StateUpdate}, + combat::{ + Attack, AttackEffect, CombatBuff, CombatRequirement, DamageComponent, EffectComponent, + }, + comp::{CharacterState, MeleeAttack, StateUpdate}, states::{ behavior::{CharacterBehavior, JoinData}, utils::{StageSection, *}, @@ -152,6 +154,9 @@ impl CharacterBehavior for Data { source: DamageSource::Melee, value: self.static_data.base_damage as f32, }; + let poise = AttackEffect::Poise(self.static_data.base_poise_damage as f32); + let poise = EffectComponent::new(Some(GroupTarget::OutOfGroup), poise) + .with_requirement(CombatRequirement::AnyDamage); let knockback = AttackEffect::Knockback(Knockback { strength: self.static_data.knockback, direction: KnockbackDir::Away, @@ -160,7 +165,10 @@ impl CharacterBehavior for Data { let damage = DamageComponent::new(damage, Some(GroupTarget::OutOfGroup)) .with_effect(knockback) .with_effect(buff); - let attack = Attack::default().with_damage(damage).with_crit(0.5, 1.3); + let attack = Attack::default() + .with_damage(damage) + .with_crit(0.5, 1.3) + .with_effect(poise); // Hit attempt, when animation plays data.updater.insert(data.entity, MeleeAttack { diff --git a/common/src/states/spin_melee.rs b/common/src/states/spin_melee.rs index 36b3a26c7d..dfd2aa677b 100644 --- a/common/src/states/spin_melee.rs +++ b/common/src/states/spin_melee.rs @@ -1,9 +1,8 @@ use crate::{ - combat::{Attack, AttackEffect, CombatBuff, DamageComponent}, - comp::{ - CharacterState, EnergyChange, EnergySource, MeleeAttack, PoiseChange, PoiseSource, - StateUpdate, + combat::{ + Attack, AttackEffect, CombatBuff, CombatRequirement, DamageComponent, EffectComponent, }, + comp::{CharacterState, EnergyChange, EnergySource, MeleeAttack, StateUpdate}, consts::GRAVITY, states::{ behavior::{CharacterBehavior, JoinData}, @@ -120,6 +119,9 @@ impl CharacterBehavior for Data { source: DamageSource::Melee, value: self.static_data.base_damage as f32, }; + let poise = AttackEffect::Poise(self.static_data.base_poise_damage as f32); + let poise = EffectComponent::new(Some(GroupTarget::OutOfGroup), poise) + .with_requirement(CombatRequirement::AnyDamage); let knockback = AttackEffect::Knockback(Knockback { strength: self.static_data.knockback, direction: KnockbackDir::Away, @@ -128,7 +130,10 @@ impl CharacterBehavior for Data { let damage = DamageComponent::new(damage, Some(GroupTarget::OutOfGroup)) .with_effect(knockback) .with_effect(buff); - let attack = Attack::default().with_damage(damage).with_crit(0.5, 1.3); + let attack = Attack::default() + .with_damage(damage) + .with_crit(0.5, 1.3) + .with_effect(poise); // Hit attempt data.updater.insert(data.entity, MeleeAttack {