Attacks can now deal poise damage.

This commit is contained in:
Sam
2021-01-29 23:40:03 -05:00
parent fcd89a5d41
commit edcfcc31f6
9 changed files with 88 additions and 39 deletions

View File

@ -9,6 +9,7 @@ use crate::{
}, },
slot::EquipSlot, slot::EquipSlot,
}, },
poise::PoiseChange,
skills::{SkillGroupKind, SkillSet}, skills::{SkillGroupKind, SkillSet},
Body, EnergyChange, EnergySource, Health, HealthChange, HealthSource, Inventory, Stats, Body, EnergyChange, EnergySource, Health, HealthChange, HealthSource, Inventory, Stats,
}, },
@ -139,6 +140,14 @@ impl Attack {
change, 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, 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), Knockback(Knockback),
EnergyReward(u32), EnergyReward(u32),
Lifesteal(f32), Lifesteal(f32),
Poise(f32),
} }
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]

View File

@ -1,6 +1,6 @@
use crate::{ use crate::{
combat::Attack, combat::Attack,
comp::{Energy, Ori, PoiseChange, Pos, Vel}, comp::{Energy, Ori, Pos, Vel},
event::{LocalEvent, ServerEvent}, event::{LocalEvent, ServerEvent},
states::{behavior::JoinData, *}, states::{behavior::JoinData, *},
}; };

View File

@ -31,6 +31,17 @@ impl PoiseChange {
source: self.source, 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 /// Sources of poise change

View File

@ -2,7 +2,7 @@ use crate::{
combat::{ combat::{
Attack, AttackEffect, CombatBuff, CombatRequirement, DamageComponent, EffectComponent, Attack, AttackEffect, CombatBuff, CombatRequirement, DamageComponent, EffectComponent,
}, },
comp::{CharacterState, MeleeAttack, PoiseChange, PoiseSource, StateUpdate}, comp::{CharacterState, MeleeAttack, StateUpdate},
states::{ states::{
behavior::{CharacterBehavior, JoinData}, behavior::{CharacterBehavior, JoinData},
utils::*, utils::*,
@ -96,6 +96,9 @@ impl CharacterBehavior for Data {
source: DamageSource::Melee, source: DamageSource::Melee,
value: self.static_data.base_damage as f32, 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 { let knockback = AttackEffect::Knockback(Knockback {
strength: self.static_data.knockback, strength: self.static_data.knockback,
direction: KnockbackDir::Away, direction: KnockbackDir::Away,
@ -110,7 +113,8 @@ impl CharacterBehavior for Data {
let attack = Attack::default() let attack = Attack::default()
.with_damage(damage) .with_damage(damage)
.with_crit(0.5, 1.3) .with_crit(0.5, 1.3)
.with_effect(energy); .with_effect(energy)
.with_effect(poise);
// Hit attempt // Hit attempt
data.updater.insert(data.entity, MeleeAttack { data.updater.insert(data.entity, MeleeAttack {

View File

@ -1,9 +1,8 @@
use crate::{ use crate::{
combat::{Attack, AttackEffect, CombatBuff, DamageComponent}, combat::{
comp::{ Attack, AttackEffect, CombatBuff, CombatRequirement, DamageComponent, EffectComponent,
CharacterState, EnergyChange, EnergySource, MeleeAttack, PoiseChange, PoiseSource,
StateUpdate,
}, },
comp::{CharacterState, EnergyChange, EnergySource, MeleeAttack, StateUpdate},
states::{ states::{
behavior::{CharacterBehavior, JoinData}, behavior::{CharacterBehavior, JoinData},
utils::{StageSection, *}, utils::{StageSection, *},
@ -161,12 +160,11 @@ impl CharacterBehavior for Data {
value: self.static_data.initial_damage as f32 value: self.static_data.initial_damage as f32
+ self.charge_amount * self.static_data.scaled_damage as f32, + self.charge_amount * self.static_data.scaled_damage as f32,
}; };
let poise_damage = PoiseChange { let poise = self.static_data.initial_poise_damage as f32
amount: -(self.static_data.initial_poise_damage as f32 + self.charge_amount * self.static_data.scaled_poise_damage as f32;
+ self.charge_amount * self.static_data.scaled_poise_damage as f32) let poise = AttackEffect::Poise(poise);
as i32, let poise = EffectComponent::new(Some(GroupTarget::OutOfGroup), poise)
source: PoiseSource::Attack, .with_requirement(CombatRequirement::AnyDamage);
};
let knockback = self.static_data.initial_knockback let knockback = self.static_data.initial_knockback
+ self.charge_amount * self.static_data.scaled_knockback; + self.charge_amount * self.static_data.scaled_knockback;
let knockback = AttackEffect::Knockback(Knockback { let knockback = AttackEffect::Knockback(Knockback {
@ -177,7 +175,10 @@ impl CharacterBehavior for Data {
let damage = DamageComponent::new(damage, Some(GroupTarget::OutOfGroup)) let damage = DamageComponent::new(damage, Some(GroupTarget::OutOfGroup))
.with_effect(knockback) .with_effect(knockback)
.with_effect(buff); .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 // Hit attempt
data.updater.insert(data.entity, MeleeAttack { data.updater.insert(data.entity, MeleeAttack {

View File

@ -2,10 +2,7 @@ use crate::{
combat::{ combat::{
Attack, AttackEffect, CombatBuff, CombatRequirement, DamageComponent, EffectComponent, Attack, AttackEffect, CombatBuff, CombatRequirement, DamageComponent, EffectComponent,
}, },
comp::{ comp::{CharacterState, MeleeAttack, StateUpdate},
CharacterState, EnergyChange, EnergySource, MeleeAttack, PoiseChange, PoiseSource,
StateUpdate,
},
states::{ states::{
behavior::{CharacterBehavior, JoinData}, behavior::{CharacterBehavior, JoinData},
utils::*, utils::*,
@ -178,12 +175,15 @@ impl CharacterBehavior for Data {
.min(self.combo / self.static_data.num_stages) .min(self.combo / self.static_data.num_stages)
* self.static_data.stage_data[stage_index].damage_increase; * 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 + self
.static_data .static_data
.scales_from_combo .scales_from_combo
.min(self.combo / self.static_data.num_stages) .min(self.combo / self.static_data.num_stages)
* self.static_data.stage_data[stage_index].poise_damage_increase; * 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 { let damage = Damage {
source: DamageSource::Melee, source: DamageSource::Melee,
@ -207,7 +207,8 @@ impl CharacterBehavior for Data {
let attack = Attack::default() let attack = Attack::default()
.with_damage(damage) .with_damage(damage)
.with_crit(0.5, 1.3) .with_crit(0.5, 1.3)
.with_effect(energy); .with_effect(energy)
.with_effect(poise);
data.updater.insert(data.entity, MeleeAttack { data.updater.insert(data.entity, MeleeAttack {
attack, attack,

View File

@ -1,9 +1,8 @@
use crate::{ use crate::{
combat::{Attack, AttackEffect, CombatBuff, DamageComponent}, combat::{
comp::{ Attack, AttackEffect, CombatBuff, CombatRequirement, DamageComponent, EffectComponent,
CharacterState, EnergyChange, EnergySource, MeleeAttack, PoiseChange, PoiseSource,
StateUpdate,
}, },
comp::{CharacterState, EnergyChange, EnergySource, MeleeAttack, StateUpdate},
states::{ states::{
behavior::{CharacterBehavior, JoinData}, behavior::{CharacterBehavior, JoinData},
utils::*, utils::*,
@ -138,12 +137,11 @@ impl CharacterBehavior for Data {
value: self.static_data.base_damage as f32 value: self.static_data.base_damage as f32
+ charge_frac * self.static_data.scaled_damage as f32, + charge_frac * self.static_data.scaled_damage as f32,
}; };
let poise_damage = PoiseChange { let poise = self.static_data.base_poise_damage as f32
amount: -(self.static_data.base_poise_damage as f32 + charge_frac * self.static_data.scaled_poise_damage as f32;
+ charge_frac * self.static_data.scaled_poise_damage as f32) let poise = AttackEffect::Poise(poise);
as i32, let poise = EffectComponent::new(Some(GroupTarget::OutOfGroup), poise)
source: PoiseSource::Attack, .with_requirement(CombatRequirement::AnyDamage);
};
let knockback = self.static_data.base_knockback let knockback = self.static_data.base_knockback
+ charge_frac * self.static_data.scaled_knockback; + charge_frac * self.static_data.scaled_knockback;
let knockback = AttackEffect::Knockback(Knockback { let knockback = AttackEffect::Knockback(Knockback {
@ -155,7 +153,10 @@ impl CharacterBehavior for Data {
DamageComponent::new(damage, Some(GroupTarget::OutOfGroup)) DamageComponent::new(damage, Some(GroupTarget::OutOfGroup))
.with_effect(knockback) .with_effect(knockback)
.with_effect(buff); .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 { data.updater.insert(data.entity, MeleeAttack {
attack, attack,

View File

@ -1,6 +1,8 @@
use crate::{ use crate::{
combat::{Attack, AttackEffect, CombatBuff, DamageComponent}, combat::{
comp::{CharacterState, MeleeAttack, PoiseChange, PoiseSource, StateUpdate}, Attack, AttackEffect, CombatBuff, CombatRequirement, DamageComponent, EffectComponent,
},
comp::{CharacterState, MeleeAttack, StateUpdate},
states::{ states::{
behavior::{CharacterBehavior, JoinData}, behavior::{CharacterBehavior, JoinData},
utils::{StageSection, *}, utils::{StageSection, *},
@ -152,6 +154,9 @@ impl CharacterBehavior for Data {
source: DamageSource::Melee, source: DamageSource::Melee,
value: self.static_data.base_damage as f32, 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 { let knockback = AttackEffect::Knockback(Knockback {
strength: self.static_data.knockback, strength: self.static_data.knockback,
direction: KnockbackDir::Away, direction: KnockbackDir::Away,
@ -160,7 +165,10 @@ impl CharacterBehavior for Data {
let damage = DamageComponent::new(damage, Some(GroupTarget::OutOfGroup)) let damage = DamageComponent::new(damage, Some(GroupTarget::OutOfGroup))
.with_effect(knockback) .with_effect(knockback)
.with_effect(buff); .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 // Hit attempt, when animation plays
data.updater.insert(data.entity, MeleeAttack { data.updater.insert(data.entity, MeleeAttack {

View File

@ -1,9 +1,8 @@
use crate::{ use crate::{
combat::{Attack, AttackEffect, CombatBuff, DamageComponent}, combat::{
comp::{ Attack, AttackEffect, CombatBuff, CombatRequirement, DamageComponent, EffectComponent,
CharacterState, EnergyChange, EnergySource, MeleeAttack, PoiseChange, PoiseSource,
StateUpdate,
}, },
comp::{CharacterState, EnergyChange, EnergySource, MeleeAttack, StateUpdate},
consts::GRAVITY, consts::GRAVITY,
states::{ states::{
behavior::{CharacterBehavior, JoinData}, behavior::{CharacterBehavior, JoinData},
@ -120,6 +119,9 @@ impl CharacterBehavior for Data {
source: DamageSource::Melee, source: DamageSource::Melee,
value: self.static_data.base_damage as f32, 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 { let knockback = AttackEffect::Knockback(Knockback {
strength: self.static_data.knockback, strength: self.static_data.knockback,
direction: KnockbackDir::Away, direction: KnockbackDir::Away,
@ -128,7 +130,10 @@ impl CharacterBehavior for Data {
let damage = DamageComponent::new(damage, Some(GroupTarget::OutOfGroup)) let damage = DamageComponent::new(damage, Some(GroupTarget::OutOfGroup))
.with_effect(knockback) .with_effect(knockback)
.with_effect(buff); .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 // Hit attempt
data.updater.insert(data.entity, MeleeAttack { data.updater.insert(data.entity, MeleeAttack {