mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Very basic functioning stun
This commit is contained in:
parent
df4c9eff49
commit
df124a1eef
@ -40,7 +40,6 @@ pub enum DamageSource {
|
|||||||
pub struct Damage {
|
pub struct Damage {
|
||||||
pub source: DamageSource,
|
pub source: DamageSource,
|
||||||
pub value: f32,
|
pub value: f32,
|
||||||
pub poise_damage: f32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Damage {
|
impl Damage {
|
||||||
@ -84,16 +83,13 @@ impl Damage {
|
|||||||
damage += critdamage;
|
damage += critdamage;
|
||||||
}
|
}
|
||||||
|
|
||||||
(
|
HealthChange {
|
||||||
HealthChange {
|
amount: -damage as i32,
|
||||||
amount: -damage as i32,
|
cause: HealthSource::Damage {
|
||||||
cause: HealthSource::Damage {
|
kind: self.source,
|
||||||
kind: self.source,
|
by: uid,
|
||||||
by: uid,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
-poise_damage as i32,
|
}
|
||||||
)
|
|
||||||
},
|
},
|
||||||
DamageSource::Projectile => {
|
DamageSource::Projectile => {
|
||||||
// Critical hit
|
// Critical hit
|
||||||
@ -103,82 +99,63 @@ impl Damage {
|
|||||||
// Armor
|
// Armor
|
||||||
damage *= 1.0 - damage_reduction;
|
damage *= 1.0 - damage_reduction;
|
||||||
|
|
||||||
(
|
HealthChange {
|
||||||
HealthChange {
|
amount: -damage as i32,
|
||||||
amount: -damage as i32,
|
cause: HealthSource::Damage {
|
||||||
cause: HealthSource::Damage {
|
kind: self.source,
|
||||||
kind: self.source,
|
by: uid,
|
||||||
by: uid,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
-poise_damage as i32,
|
}
|
||||||
)
|
|
||||||
},
|
},
|
||||||
DamageSource::Explosion => {
|
DamageSource::Explosion => {
|
||||||
// Armor
|
// Armor
|
||||||
damage *= 1.0 - damage_reduction;
|
damage *= 1.0 - damage_reduction;
|
||||||
|
|
||||||
(
|
HealthChange {
|
||||||
HealthChange {
|
amount: -damage as i32,
|
||||||
amount: -damage as i32,
|
cause: HealthSource::Damage {
|
||||||
cause: HealthSource::Damage {
|
kind: self.source,
|
||||||
kind: self.source,
|
by: uid,
|
||||||
by: uid,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
-poise_damage as i32,
|
}
|
||||||
)
|
|
||||||
},
|
},
|
||||||
DamageSource::Shockwave => {
|
DamageSource::Shockwave => {
|
||||||
// Armor
|
// Armor
|
||||||
damage *= 1.0 - damage_reduction;
|
damage *= 1.0 - damage_reduction;
|
||||||
|
|
||||||
(
|
HealthChange {
|
||||||
HealthChange {
|
amount: -damage as i32,
|
||||||
amount: -damage as i32,
|
cause: HealthSource::Damage {
|
||||||
cause: HealthSource::Damage {
|
kind: self.source,
|
||||||
kind: self.source,
|
by: uid,
|
||||||
by: uid,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
-poise_damage as i32,
|
}
|
||||||
)
|
|
||||||
},
|
},
|
||||||
DamageSource::Energy => {
|
DamageSource::Energy => {
|
||||||
// Armor
|
// Armor
|
||||||
damage *= 1.0 - damage_reduction;
|
damage *= 1.0 - damage_reduction;
|
||||||
|
|
||||||
(
|
|
||||||
HealthChange {
|
|
||||||
amount: -damage as i32,
|
|
||||||
cause: HealthSource::Damage {
|
|
||||||
kind: self.source,
|
|
||||||
by: uid,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
-poise_damage as i32,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
DamageSource::Healing => (
|
|
||||||
HealthChange {
|
HealthChange {
|
||||||
amount: damage as i32,
|
amount: -damage as i32,
|
||||||
cause: HealthSource::Heal { by: uid },
|
cause: HealthSource::Damage {
|
||||||
},
|
kind: self.source,
|
||||||
0,
|
by: uid,
|
||||||
),
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
DamageSource::Healing => HealthChange {
|
||||||
|
amount: damage as i32,
|
||||||
|
cause: HealthSource::Heal { by: uid },
|
||||||
|
},
|
||||||
DamageSource::Falling => {
|
DamageSource::Falling => {
|
||||||
// Armor
|
// Armor
|
||||||
if (damage_reduction - 1.0).abs() < f32::EPSILON {
|
if (damage_reduction - 1.0).abs() < f32::EPSILON {
|
||||||
damage = 0.0;
|
damage = 0.0;
|
||||||
poise_damage = 0.0;
|
|
||||||
}
|
}
|
||||||
(
|
HealthChange {
|
||||||
HealthChange {
|
amount: -damage as i32,
|
||||||
amount: -damage as i32,
|
cause: HealthSource::World,
|
||||||
cause: HealthSource::World,
|
},
|
||||||
},
|
|
||||||
-poise_damage as i32,
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
DamageSource::Buff(_) => HealthChange {
|
DamageSource::Buff(_) => HealthChange {
|
||||||
amount: -damage as i32,
|
amount: -damage as i32,
|
||||||
@ -193,8 +170,7 @@ impl Damage {
|
|||||||
kind: self.source,
|
kind: self.source,
|
||||||
by: uid,
|
by: uid,
|
||||||
},
|
},
|
||||||
-poise_damage as i32,
|
},
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
use crate::{uid::Uid, Damage, GroupTarget};
|
use crate::{
|
||||||
|
comp::{PoiseChange, PoiseSource},
|
||||||
|
uid::Uid,
|
||||||
|
Damage, GroupTarget,
|
||||||
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use specs::{Component, DerefFlaggedStorage};
|
use specs::{Component, DerefFlaggedStorage};
|
||||||
use specs_idvs::IdvStorage;
|
use specs_idvs::IdvStorage;
|
||||||
@ -8,7 +12,7 @@ use std::time::Duration;
|
|||||||
pub struct Properties {
|
pub struct Properties {
|
||||||
pub angle: f32,
|
pub angle: f32,
|
||||||
pub speed: f32,
|
pub speed: f32,
|
||||||
pub damages: Vec<(Option<GroupTarget>, Damage)>,
|
pub effects: Vec<(Option<GroupTarget>, Damage, PoiseChange)>,
|
||||||
pub lifesteal_eff: f32,
|
pub lifesteal_eff: f32,
|
||||||
pub energy_regen: u32,
|
pub energy_regen: u32,
|
||||||
pub energy_cost: u32,
|
pub energy_cost: u32,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{Energy, Ori, Pos, Vel},
|
comp::{Energy, Ori, PoiseChange, Pos, Vel},
|
||||||
event::{LocalEvent, ServerEvent},
|
event::{LocalEvent, ServerEvent},
|
||||||
states::{behavior::JoinData, *},
|
states::{behavior::JoinData, *},
|
||||||
Damage, GroupTarget, Knockback,
|
Damage, GroupTarget, Knockback,
|
||||||
@ -172,7 +172,7 @@ impl Component for CharacterState {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct Attacking {
|
pub struct Attacking {
|
||||||
pub damages: Vec<(Option<GroupTarget>, Damage)>,
|
pub effects: Vec<(Option<GroupTarget>, Damage, PoiseChange)>,
|
||||||
pub range: f32,
|
pub range: f32,
|
||||||
pub max_angle: f32,
|
pub max_angle: f32,
|
||||||
pub applied: bool,
|
pub applied: bool,
|
||||||
|
@ -66,7 +66,7 @@ pub use phys::{
|
|||||||
Sticky, Vel,
|
Sticky, Vel,
|
||||||
};
|
};
|
||||||
pub use player::Player;
|
pub use player::Player;
|
||||||
pub use poise::{Poise, PoiseState};
|
pub use poise::{Poise, PoiseChange, PoiseSource, PoiseState};
|
||||||
pub use projectile::{Projectile, ProjectileConstructor};
|
pub use projectile::{Projectile, ProjectileConstructor};
|
||||||
pub use shockwave::{Shockwave, ShockwaveHitEntities};
|
pub use shockwave::{Shockwave, ShockwaveHitEntities};
|
||||||
pub use skills::{Skill, SkillGroup, SkillGroupKind, SkillSet};
|
pub use skills::{Skill, SkillGroup, SkillGroupKind, SkillSet};
|
||||||
|
@ -1,8 +1,91 @@
|
|||||||
use crate::{comp::Body, sync::Uid, DamageSource};
|
use crate::{
|
||||||
|
comp::{Body, Loadout},
|
||||||
|
sync::Uid,
|
||||||
|
DamageSource,
|
||||||
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use specs::{Component, FlaggedStorage};
|
use specs::{Component, FlaggedStorage};
|
||||||
use specs_idvs::IdvStorage;
|
use specs_idvs::IdvStorage;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct PoiseChange {
|
||||||
|
pub amount: i32,
|
||||||
|
pub source: PoiseSource,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PoiseChange {
|
||||||
|
pub fn modify_poise_damage(self, loadout: Option<&Loadout>, uid: Option<Uid>) -> PoiseChange {
|
||||||
|
println!("Pre modified: {:?}", self.amount);
|
||||||
|
let mut poise_damage = -self.amount as f32;
|
||||||
|
match self.source {
|
||||||
|
PoiseSource::Melee => {
|
||||||
|
// Armor
|
||||||
|
let damage_reduction = loadout.map_or(0.0, |l| l.get_poise_damage_reduction());
|
||||||
|
poise_damage *= 1.0 - damage_reduction;
|
||||||
|
PoiseChange {
|
||||||
|
amount: -poise_damage as i32,
|
||||||
|
source: PoiseSource::Melee,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
PoiseSource::Projectile => {
|
||||||
|
// Armor
|
||||||
|
let damage_reduction = loadout.map_or(0.0, |l| l.get_poise_damage_reduction());
|
||||||
|
poise_damage *= 1.0 - damage_reduction;
|
||||||
|
PoiseChange {
|
||||||
|
amount: -poise_damage as i32,
|
||||||
|
source: PoiseSource::Projectile,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
PoiseSource::Shockwave => {
|
||||||
|
// Armor
|
||||||
|
let damage_reduction = loadout.map_or(0.0, |l| l.get_poise_damage_reduction());
|
||||||
|
poise_damage *= 1.0 - damage_reduction;
|
||||||
|
PoiseChange {
|
||||||
|
amount: -poise_damage as i32,
|
||||||
|
source: PoiseSource::Shockwave,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
PoiseSource::Explosion => {
|
||||||
|
// Armor
|
||||||
|
let damage_reduction = loadout.map_or(0.0, |l| l.get_poise_damage_reduction());
|
||||||
|
poise_damage *= 1.0 - damage_reduction;
|
||||||
|
PoiseChange {
|
||||||
|
amount: -poise_damage as i32,
|
||||||
|
source: PoiseSource::Explosion,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
PoiseSource::Falling => {
|
||||||
|
// Armor
|
||||||
|
let damage_reduction = loadout.map_or(0.0, |l| l.get_poise_damage_reduction());
|
||||||
|
if (damage_reduction - 1.0).abs() < f32::EPSILON {
|
||||||
|
poise_damage = 0.0;
|
||||||
|
}
|
||||||
|
PoiseChange {
|
||||||
|
amount: -poise_damage as i32,
|
||||||
|
source: PoiseSource::Falling,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => PoiseChange {
|
||||||
|
amount: self.amount,
|
||||||
|
source: PoiseSource::Other,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub enum PoiseSource {
|
||||||
|
LevelUp,
|
||||||
|
Melee,
|
||||||
|
Projectile,
|
||||||
|
Explosion,
|
||||||
|
Beam,
|
||||||
|
Shockwave,
|
||||||
|
Falling,
|
||||||
|
Revive,
|
||||||
|
Other,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||||
pub struct Poise {
|
pub struct Poise {
|
||||||
base_max: u32,
|
base_max: u32,
|
||||||
@ -69,8 +152,8 @@ impl Poise {
|
|||||||
self.current = amount;
|
self.current = amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn change_by(&mut self, change: i32) {
|
pub fn change_by(&mut self, change: PoiseChange) {
|
||||||
self.current = ((self.current as i32 + change).max(0) as u32).min(self.maximum);
|
self.current = ((self.current as i32 + change.amount).max(0) as u32).min(self.maximum);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset(&mut self) { self.current = self.maximum; }
|
pub fn reset(&mut self) { self.current = self.maximum; }
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::buff::{BuffCategory, BuffData, BuffKind},
|
comp::{
|
||||||
|
buff::{BuffCategory, BuffData, BuffKind},
|
||||||
|
PoiseChange, PoiseSource,
|
||||||
|
},
|
||||||
effect::{self, BuffEffect},
|
effect::{self, BuffEffect},
|
||||||
uid::Uid,
|
uid::Uid,
|
||||||
Damage, DamageSource, Explosion, GroupTarget, Knockback, RadiusEffect,
|
Damage, DamageSource, Explosion, GroupTarget, Knockback, RadiusEffect,
|
||||||
@ -11,7 +14,7 @@ use std::time::Duration;
|
|||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
pub enum Effect {
|
pub enum Effect {
|
||||||
Damage(Option<GroupTarget>, Damage),
|
Damage(Option<GroupTarget>, Damage, PoiseChange),
|
||||||
Knockback(Knockback),
|
Knockback(Knockback),
|
||||||
RewardEnergy(u32),
|
RewardEnergy(u32),
|
||||||
Explode(Explosion),
|
Explode(Explosion),
|
||||||
@ -85,11 +88,17 @@ impl ProjectileConstructor {
|
|||||||
Projectile {
|
Projectile {
|
||||||
hit_solid: vec![Effect::Stick],
|
hit_solid: vec![Effect::Stick],
|
||||||
hit_entity: vec![
|
hit_entity: vec![
|
||||||
Effect::Damage(Some(GroupTarget::OutOfGroup), Damage {
|
Effect::Damage(
|
||||||
source: DamageSource::Projectile,
|
Some(GroupTarget::OutOfGroup),
|
||||||
value: damage,
|
Damage {
|
||||||
poise_damage: 0.0,
|
source: DamageSource::Projectile,
|
||||||
}),
|
value: damage,
|
||||||
|
},
|
||||||
|
PoiseChange {
|
||||||
|
amount: 0,
|
||||||
|
source: PoiseSource::Projectile,
|
||||||
|
},
|
||||||
|
),
|
||||||
Effect::Knockback(Knockback::Away(knockback)),
|
Effect::Knockback(Knockback::Away(knockback)),
|
||||||
Effect::RewardEnergy(energy_regen),
|
Effect::RewardEnergy(energy_regen),
|
||||||
Effect::Vanish,
|
Effect::Vanish,
|
||||||
@ -111,14 +120,12 @@ impl ProjectileConstructor {
|
|||||||
hit_solid: vec![
|
hit_solid: vec![
|
||||||
Effect::Explode(Explosion {
|
Effect::Explode(Explosion {
|
||||||
effects: vec![
|
effects: vec![
|
||||||
RadiusEffect::Entity(
|
RadiusEffect::Entity(Some(GroupTarget::OutOfGroup), vec![
|
||||||
Some(GroupTarget::OutOfGroup),
|
|
||||||
effect::Effect::Damage(Damage {
|
effect::Effect::Damage(Damage {
|
||||||
source: DamageSource::Explosion,
|
source: DamageSource::Explosion,
|
||||||
value: damage,
|
value: damage,
|
||||||
poise_damage: 10.0,
|
|
||||||
}),
|
}),
|
||||||
),
|
]),
|
||||||
RadiusEffect::TerrainDestruction(2.0),
|
RadiusEffect::TerrainDestruction(2.0),
|
||||||
],
|
],
|
||||||
radius,
|
radius,
|
||||||
@ -128,14 +135,12 @@ impl ProjectileConstructor {
|
|||||||
],
|
],
|
||||||
hit_entity: vec![
|
hit_entity: vec![
|
||||||
Effect::Explode(Explosion {
|
Effect::Explode(Explosion {
|
||||||
effects: vec![RadiusEffect::Entity(
|
effects: vec![RadiusEffect::Entity(Some(GroupTarget::OutOfGroup), vec![
|
||||||
Some(GroupTarget::OutOfGroup),
|
|
||||||
effect::Effect::Damage(Damage {
|
effect::Effect::Damage(Damage {
|
||||||
source: DamageSource::Explosion,
|
source: DamageSource::Explosion,
|
||||||
value: damage,
|
value: damage,
|
||||||
poise_damage: 10.0,
|
|
||||||
}),
|
}),
|
||||||
)],
|
])],
|
||||||
radius,
|
radius,
|
||||||
energy_regen,
|
energy_regen,
|
||||||
}),
|
}),
|
||||||
@ -170,22 +175,18 @@ impl ProjectileConstructor {
|
|||||||
hit_solid: vec![
|
hit_solid: vec![
|
||||||
Effect::Explode(Explosion {
|
Effect::Explode(Explosion {
|
||||||
effects: vec![
|
effects: vec![
|
||||||
RadiusEffect::Entity(
|
RadiusEffect::Entity(Some(GroupTarget::OutOfGroup), vec![
|
||||||
Some(GroupTarget::OutOfGroup),
|
|
||||||
effect::Effect::Damage(Damage {
|
effect::Effect::Damage(Damage {
|
||||||
source: DamageSource::Explosion,
|
source: DamageSource::Explosion,
|
||||||
value: damage,
|
value: damage,
|
||||||
poise_damage: 0.0,
|
|
||||||
}),
|
}),
|
||||||
),
|
]),
|
||||||
RadiusEffect::Entity(
|
RadiusEffect::Entity(Some(GroupTarget::InGroup), vec![
|
||||||
Some(GroupTarget::InGroup),
|
|
||||||
effect::Effect::Damage(Damage {
|
effect::Effect::Damage(Damage {
|
||||||
source: DamageSource::Healing,
|
source: DamageSource::Healing,
|
||||||
value: heal,
|
value: heal,
|
||||||
poise_damage: 0.0,
|
|
||||||
}),
|
}),
|
||||||
),
|
]),
|
||||||
],
|
],
|
||||||
radius,
|
radius,
|
||||||
energy_regen: 0,
|
energy_regen: 0,
|
||||||
@ -195,22 +196,18 @@ impl ProjectileConstructor {
|
|||||||
hit_entity: vec![
|
hit_entity: vec![
|
||||||
Effect::Explode(Explosion {
|
Effect::Explode(Explosion {
|
||||||
effects: vec![
|
effects: vec![
|
||||||
RadiusEffect::Entity(
|
RadiusEffect::Entity(Some(GroupTarget::OutOfGroup), vec![
|
||||||
Some(GroupTarget::OutOfGroup),
|
|
||||||
effect::Effect::Damage(Damage {
|
effect::Effect::Damage(Damage {
|
||||||
source: DamageSource::Explosion,
|
source: DamageSource::Explosion,
|
||||||
value: damage,
|
value: damage,
|
||||||
poise_damage: 0.0,
|
|
||||||
}),
|
}),
|
||||||
),
|
]),
|
||||||
RadiusEffect::Entity(
|
RadiusEffect::Entity(Some(GroupTarget::InGroup), vec![
|
||||||
Some(GroupTarget::InGroup),
|
|
||||||
effect::Effect::Damage(Damage {
|
effect::Effect::Damage(Damage {
|
||||||
source: DamageSource::Healing,
|
source: DamageSource::Healing,
|
||||||
value: heal,
|
value: heal,
|
||||||
poise_damage: 0.0,
|
|
||||||
}),
|
}),
|
||||||
),
|
]),
|
||||||
],
|
],
|
||||||
radius,
|
radius,
|
||||||
energy_regen: 0,
|
energy_regen: 0,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{uid::Uid, Damage, GroupTarget, Knockback};
|
use crate::{comp::PoiseChange, uid::Uid, Damage, GroupTarget, Knockback};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use specs::{Component, DerefFlaggedStorage};
|
use specs::{Component, DerefFlaggedStorage};
|
||||||
use specs_idvs::IdvStorage;
|
use specs_idvs::IdvStorage;
|
||||||
@ -9,7 +9,7 @@ pub struct Properties {
|
|||||||
pub angle: f32,
|
pub angle: f32,
|
||||||
pub vertical_angle: f32,
|
pub vertical_angle: f32,
|
||||||
pub speed: f32,
|
pub speed: f32,
|
||||||
pub damages: Vec<(Option<GroupTarget>, Damage)>,
|
pub effects: Vec<(Option<GroupTarget>, Damage, PoiseChange)>,
|
||||||
pub knockback: Knockback,
|
pub knockback: Knockback,
|
||||||
pub requires_ground: bool,
|
pub requires_ground: bool,
|
||||||
pub duration: Duration,
|
pub duration: Duration,
|
||||||
|
@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
pub enum Effect {
|
pub enum Effect {
|
||||||
Health(comp::HealthChange),
|
Health(comp::HealthChange),
|
||||||
Poise(i32),
|
Poise(comp::PoiseChange),
|
||||||
Damage(combat::Damage),
|
Damage(combat::Damage),
|
||||||
Buff(BuffEffect),
|
Buff(BuffEffect),
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@ impl Effect {
|
|||||||
pub fn info(&self) -> String {
|
pub fn info(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
Effect::Health(c) => format!("{:+} health", c.amount),
|
Effect::Health(c) => format!("{:+} health", c.amount),
|
||||||
Effect::Poise(c) => format!("{:+} poise", c),
|
Effect::Poise(c) => format!("{:+} poise", c.amount),
|
||||||
Effect::Damage(d) => format!("{:+}", d.value),
|
Effect::Damage(d) => format!("{:+}", d.value),
|
||||||
Effect::Buff(e) => format!("{:?} buff", e),
|
Effect::Buff(e) => format!("{:?} buff", e),
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ impl Effect {
|
|||||||
change.amount = (change.amount as f32 * modifier) as i32;
|
change.amount = (change.amount as f32 * modifier) as i32;
|
||||||
},
|
},
|
||||||
Effect::Poise(change) => {
|
Effect::Poise(change) => {
|
||||||
*change = (*change as f32 * modifier) as i32;
|
change.amount = (change.amount as f32 * modifier) as i32;
|
||||||
},
|
},
|
||||||
Effect::Damage(damage) => {
|
Effect::Damage(damage) => {
|
||||||
damage.interpolate_damage(modifier, 0.0);
|
damage.interpolate_damage(modifier, 0.0);
|
||||||
|
@ -34,7 +34,11 @@ pub enum ServerEvent {
|
|||||||
},
|
},
|
||||||
Damage {
|
Damage {
|
||||||
entity: EcsEntity,
|
entity: EcsEntity,
|
||||||
change: (comp::HealthChange, i32),
|
change: comp::HealthChange,
|
||||||
|
},
|
||||||
|
PoiseChange {
|
||||||
|
entity: EcsEntity,
|
||||||
|
change: comp::PoiseChange,
|
||||||
},
|
},
|
||||||
Delete(EcsEntity),
|
Delete(EcsEntity),
|
||||||
Destroy {
|
Destroy {
|
||||||
|
@ -11,5 +11,5 @@ pub struct Explosion {
|
|||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
pub enum RadiusEffect {
|
pub enum RadiusEffect {
|
||||||
TerrainDestruction(f32),
|
TerrainDestruction(f32),
|
||||||
Entity(Option<GroupTarget>, Effect),
|
Entity(Option<GroupTarget>, Vec<Effect>),
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{beam, Body, CharacterState, EnergyChange, EnergySource, Ori, Pos, StateUpdate},
|
comp::{
|
||||||
|
beam, Body, CharacterState, EnergyChange, EnergySource, Ori, PoiseChange, PoiseSource, Pos,
|
||||||
|
StateUpdate,
|
||||||
|
},
|
||||||
event::ServerEvent,
|
event::ServerEvent,
|
||||||
states::{
|
states::{
|
||||||
behavior::{CharacterBehavior, JoinData},
|
behavior::{CharacterBehavior, JoinData},
|
||||||
@ -122,21 +125,27 @@ impl CharacterBehavior for Data {
|
|||||||
let damage = Damage {
|
let damage = Damage {
|
||||||
source: DamageSource::Energy,
|
source: DamageSource::Energy,
|
||||||
value: self.static_data.base_dps as f32 / self.static_data.tick_rate,
|
value: self.static_data.base_dps as f32 / self.static_data.tick_rate,
|
||||||
poise_damage: 0.0,
|
};
|
||||||
|
let poise_damage = PoiseChange {
|
||||||
|
amount: 0,
|
||||||
|
source: PoiseSource::Beam,
|
||||||
};
|
};
|
||||||
let heal = Damage {
|
let heal = Damage {
|
||||||
source: DamageSource::Healing,
|
source: DamageSource::Healing,
|
||||||
value: self.static_data.base_hps as f32 / self.static_data.tick_rate,
|
value: self.static_data.base_hps as f32 / self.static_data.tick_rate,
|
||||||
poise_damage: 0.0,
|
};
|
||||||
|
let reverse_poise = PoiseChange {
|
||||||
|
amount: 0,
|
||||||
|
source: PoiseSource::Beam,
|
||||||
};
|
};
|
||||||
let speed =
|
let speed =
|
||||||
self.static_data.range / self.static_data.beam_duration.as_secs_f32();
|
self.static_data.range / self.static_data.beam_duration.as_secs_f32();
|
||||||
let properties = beam::Properties {
|
let properties = beam::Properties {
|
||||||
angle: self.static_data.max_angle.to_radians(),
|
angle: self.static_data.max_angle.to_radians(),
|
||||||
speed,
|
speed,
|
||||||
damages: vec![
|
effects: vec![
|
||||||
(Some(GroupTarget::OutOfGroup), damage),
|
(Some(GroupTarget::OutOfGroup), damage, poise_damage),
|
||||||
(Some(GroupTarget::InGroup), heal),
|
(Some(GroupTarget::InGroup), heal, reverse_poise),
|
||||||
],
|
],
|
||||||
lifesteal_eff: self.static_data.lifesteal_eff,
|
lifesteal_eff: self.static_data.lifesteal_eff,
|
||||||
energy_regen: self.static_data.energy_regen,
|
energy_regen: self.static_data.energy_regen,
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{Attacking, CharacterState, EnergyChange, EnergySource, StateUpdate},
|
comp::{
|
||||||
|
Attacking, CharacterState, EnergyChange, EnergySource, PoiseChange, PoiseSource,
|
||||||
|
StateUpdate,
|
||||||
|
},
|
||||||
states::{
|
states::{
|
||||||
behavior::{CharacterBehavior, JoinData},
|
behavior::{CharacterBehavior, JoinData},
|
||||||
utils::*,
|
utils::*,
|
||||||
@ -91,11 +94,17 @@ impl CharacterBehavior for Data {
|
|||||||
|
|
||||||
// Hit attempt
|
// Hit attempt
|
||||||
data.updater.insert(data.entity, Attacking {
|
data.updater.insert(data.entity, Attacking {
|
||||||
damages: vec![(Some(GroupTarget::OutOfGroup), Damage {
|
effects: vec![(
|
||||||
source: DamageSource::Melee,
|
Some(GroupTarget::OutOfGroup),
|
||||||
value: self.static_data.base_damage as f32,
|
Damage {
|
||||||
poise_damage: self.static_data.base_poise_damage as f32,
|
source: DamageSource::Melee,
|
||||||
})],
|
value: self.static_data.base_damage as f32,
|
||||||
|
},
|
||||||
|
PoiseChange {
|
||||||
|
amount: -(self.static_data.base_poise_damage as i32),
|
||||||
|
source: PoiseSource::Melee,
|
||||||
|
},
|
||||||
|
)],
|
||||||
range: self.static_data.range,
|
range: self.static_data.range,
|
||||||
max_angle: 180_f32.to_radians(),
|
max_angle: 180_f32.to_radians(),
|
||||||
applied: false,
|
applied: false,
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{Attacking, CharacterState, EnergyChange, EnergySource, StateUpdate},
|
comp::{
|
||||||
|
Attacking, CharacterState, EnergyChange, EnergySource, PoiseChange, PoiseSource,
|
||||||
|
StateUpdate,
|
||||||
|
},
|
||||||
states::{
|
states::{
|
||||||
behavior::{CharacterBehavior, JoinData},
|
behavior::{CharacterBehavior, JoinData},
|
||||||
utils::{StageSection, *},
|
utils::{StageSection, *},
|
||||||
@ -154,14 +157,17 @@ impl CharacterBehavior for Data {
|
|||||||
source: DamageSource::Melee,
|
source: DamageSource::Melee,
|
||||||
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,
|
||||||
poise_damage: self.static_data.initial_poise_damage as f32,
|
};
|
||||||
|
let mut poise_damage = PoiseChange {
|
||||||
|
amount: -(self.static_data.initial_poise_damage as i32),
|
||||||
|
source: PoiseSource::Melee,
|
||||||
};
|
};
|
||||||
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;
|
||||||
|
|
||||||
// Hit attempt
|
// Hit attempt
|
||||||
data.updater.insert(data.entity, Attacking {
|
data.updater.insert(data.entity, Attacking {
|
||||||
damages: vec![(Some(GroupTarget::OutOfGroup), damage)],
|
effects: vec![(Some(GroupTarget::OutOfGroup), damage, poise_damage)],
|
||||||
range: self.static_data.range,
|
range: self.static_data.range,
|
||||||
max_angle: self.static_data.max_angle.to_radians(),
|
max_angle: self.static_data.max_angle.to_radians(),
|
||||||
applied: false,
|
applied: false,
|
||||||
|
@ -2,7 +2,7 @@ use crate::{
|
|||||||
comp::{
|
comp::{
|
||||||
buff::{BuffCategory, BuffData, BuffKind},
|
buff::{BuffCategory, BuffData, BuffKind},
|
||||||
projectile, Body, CharacterState, EnergyChange, EnergySource, Gravity, LightEmitter,
|
projectile, Body, CharacterState, EnergyChange, EnergySource, Gravity, LightEmitter,
|
||||||
Projectile, StateUpdate,
|
PoiseChange, PoiseSource, Projectile, StateUpdate,
|
||||||
},
|
},
|
||||||
effect::BuffEffect,
|
effect::BuffEffect,
|
||||||
event::ServerEvent,
|
event::ServerEvent,
|
||||||
@ -108,7 +108,10 @@ impl CharacterBehavior for Data {
|
|||||||
source: DamageSource::Projectile,
|
source: DamageSource::Projectile,
|
||||||
value: self.static_data.initial_damage as f32
|
value: self.static_data.initial_damage as f32
|
||||||
+ charge_frac * self.static_data.scaled_damage as f32,
|
+ charge_frac * self.static_data.scaled_damage as f32,
|
||||||
poise_damage: self.static_data.initial_poise_damage as f32,
|
};
|
||||||
|
let mut poise_damage = PoiseChange {
|
||||||
|
amount: -(self.static_data.initial_poise_damage as i32),
|
||||||
|
source: PoiseSource::Projectile,
|
||||||
};
|
};
|
||||||
let knockback = self.static_data.initial_knockback
|
let knockback = self.static_data.initial_knockback
|
||||||
+ charge_frac * self.static_data.scaled_knockback;
|
+ charge_frac * self.static_data.scaled_knockback;
|
||||||
@ -116,7 +119,11 @@ impl CharacterBehavior for Data {
|
|||||||
let projectile = Projectile {
|
let projectile = Projectile {
|
||||||
hit_solid: vec![projectile::Effect::Stick],
|
hit_solid: vec![projectile::Effect::Stick],
|
||||||
hit_entity: vec![
|
hit_entity: vec![
|
||||||
projectile::Effect::Damage(Some(GroupTarget::OutOfGroup), damage),
|
projectile::Effect::Damage(
|
||||||
|
Some(GroupTarget::OutOfGroup),
|
||||||
|
damage,
|
||||||
|
poise_damage,
|
||||||
|
),
|
||||||
projectile::Effect::Knockback(Knockback::Away(knockback)),
|
projectile::Effect::Knockback(Knockback::Away(knockback)),
|
||||||
projectile::Effect::Vanish,
|
projectile::Effect::Vanish,
|
||||||
projectile::Effect::Buff {
|
projectile::Effect::Buff {
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{Attacking, CharacterState, EnergyChange, EnergySource, StateUpdate},
|
comp::{
|
||||||
|
Attacking, CharacterState, EnergyChange, EnergySource, PoiseChange, PoiseSource,
|
||||||
|
StateUpdate,
|
||||||
|
},
|
||||||
states::{
|
states::{
|
||||||
behavior::{CharacterBehavior, JoinData},
|
behavior::{CharacterBehavior, JoinData},
|
||||||
utils::*,
|
utils::*,
|
||||||
@ -167,12 +170,19 @@ 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_damage = self.static_data.stage_data[stage_index].base_poise_damage;
|
||||||
|
println!("Combo melee poise damage: {:?}", poise_damage);
|
||||||
data.updater.insert(data.entity, Attacking {
|
data.updater.insert(data.entity, Attacking {
|
||||||
damages: vec![(Some(GroupTarget::OutOfGroup), Damage {
|
effects: vec![(
|
||||||
source: DamageSource::Melee,
|
Some(GroupTarget::OutOfGroup),
|
||||||
value: damage as f32,
|
Damage {
|
||||||
poise_damage: poise_damage as f32,
|
source: DamageSource::Melee,
|
||||||
})],
|
value: damage as f32,
|
||||||
|
},
|
||||||
|
PoiseChange {
|
||||||
|
amount: -(poise_damage as i32),
|
||||||
|
source: PoiseSource::Melee,
|
||||||
|
},
|
||||||
|
)],
|
||||||
range: self.static_data.stage_data[stage_index].range,
|
range: self.static_data.stage_data[stage_index].range,
|
||||||
max_angle: self.static_data.stage_data[stage_index].angle.to_radians(),
|
max_angle: self.static_data.stage_data[stage_index].angle.to_radians(),
|
||||||
applied: false,
|
applied: false,
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{Attacking, CharacterState, EnergyChange, EnergySource, StateUpdate},
|
comp::{
|
||||||
|
Attacking, CharacterState, EnergyChange, EnergySource, PoiseChange, PoiseSource,
|
||||||
|
StateUpdate,
|
||||||
|
},
|
||||||
states::{
|
states::{
|
||||||
behavior::{CharacterBehavior, JoinData},
|
behavior::{CharacterBehavior, JoinData},
|
||||||
utils::*,
|
utils::*,
|
||||||
@ -131,12 +134,19 @@ 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
|
||||||
+ charge_frac * self.static_data.scaled_damage as f32,
|
+ charge_frac * self.static_data.scaled_damage as f32,
|
||||||
poise_damage: self.static_data.base_poise_damage as f32,
|
};
|
||||||
|
let mut poise_damage = PoiseChange {
|
||||||
|
amount: -(self.static_data.base_poise_damage as i32),
|
||||||
|
source: PoiseSource::Melee,
|
||||||
};
|
};
|
||||||
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;
|
||||||
data.updater.insert(data.entity, Attacking {
|
data.updater.insert(data.entity, Attacking {
|
||||||
damages: vec![(Some(GroupTarget::OutOfGroup), damage)],
|
effects: vec![(
|
||||||
|
Some(GroupTarget::OutOfGroup),
|
||||||
|
damage,
|
||||||
|
poise_damage,
|
||||||
|
)],
|
||||||
range: self.static_data.range,
|
range: self.static_data.range,
|
||||||
max_angle: self.static_data.angle.to_radians(),
|
max_angle: self.static_data.angle.to_radians(),
|
||||||
applied: false,
|
applied: false,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{Attacking, CharacterState, StateUpdate},
|
comp::{Attacking, CharacterState, PoiseChange, PoiseSource, StateUpdate},
|
||||||
states::{
|
states::{
|
||||||
behavior::{CharacterBehavior, JoinData},
|
behavior::{CharacterBehavior, JoinData},
|
||||||
utils::{StageSection, *},
|
utils::{StageSection, *},
|
||||||
@ -149,11 +149,17 @@ impl CharacterBehavior for Data {
|
|||||||
if !self.exhausted {
|
if !self.exhausted {
|
||||||
// Hit attempt, when animation plays
|
// Hit attempt, when animation plays
|
||||||
data.updater.insert(data.entity, Attacking {
|
data.updater.insert(data.entity, Attacking {
|
||||||
damages: vec![(Some(GroupTarget::OutOfGroup), Damage {
|
effects: vec![(
|
||||||
source: DamageSource::Melee,
|
Some(GroupTarget::OutOfGroup),
|
||||||
value: self.static_data.base_damage as f32,
|
Damage {
|
||||||
poise_damage: self.static_data.base_poise_damage as f32,
|
source: DamageSource::Melee,
|
||||||
})],
|
value: self.static_data.base_damage as f32,
|
||||||
|
},
|
||||||
|
PoiseChange {
|
||||||
|
amount: -(self.static_data.base_poise_damage as i32),
|
||||||
|
source: PoiseSource::Melee,
|
||||||
|
},
|
||||||
|
)],
|
||||||
range: self.static_data.range,
|
range: self.static_data.range,
|
||||||
max_angle: self.static_data.max_angle.to_radians(),
|
max_angle: self.static_data.max_angle.to_radians(),
|
||||||
applied: false,
|
applied: false,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{shockwave, CharacterState, StateUpdate},
|
comp::{shockwave, CharacterState, PoiseChange, PoiseSource, StateUpdate},
|
||||||
event::ServerEvent,
|
event::ServerEvent,
|
||||||
states::{
|
states::{
|
||||||
behavior::{CharacterBehavior, JoinData},
|
behavior::{CharacterBehavior, JoinData},
|
||||||
@ -85,11 +85,17 @@ impl CharacterBehavior for Data {
|
|||||||
vertical_angle: self.static_data.shockwave_vertical_angle,
|
vertical_angle: self.static_data.shockwave_vertical_angle,
|
||||||
speed: self.static_data.shockwave_speed,
|
speed: self.static_data.shockwave_speed,
|
||||||
duration: self.static_data.shockwave_duration,
|
duration: self.static_data.shockwave_duration,
|
||||||
damages: vec![(Some(GroupTarget::OutOfGroup), Damage {
|
effects: vec![(
|
||||||
source: DamageSource::Shockwave,
|
Some(GroupTarget::OutOfGroup),
|
||||||
value: self.static_data.damage as f32,
|
Damage {
|
||||||
poise_damage: self.static_data.poise_damage as f32,
|
source: DamageSource::Shockwave,
|
||||||
})],
|
value: self.static_data.damage as f32,
|
||||||
|
},
|
||||||
|
PoiseChange {
|
||||||
|
amount: -(self.static_data.poise_damage as i32),
|
||||||
|
source: PoiseSource::Shockwave,
|
||||||
|
},
|
||||||
|
)],
|
||||||
knockback: self.static_data.knockback,
|
knockback: self.static_data.knockback,
|
||||||
requires_ground: self.static_data.requires_ground,
|
requires_ground: self.static_data.requires_ground,
|
||||||
owner: Some(*data.uid),
|
owner: Some(*data.uid),
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{Attacking, CharacterState, EnergyChange, EnergySource, StateUpdate},
|
comp::{
|
||||||
|
Attacking, CharacterState, EnergyChange, EnergySource, PoiseChange, PoiseSource,
|
||||||
|
StateUpdate,
|
||||||
|
},
|
||||||
consts::GRAVITY,
|
consts::GRAVITY,
|
||||||
states::{
|
states::{
|
||||||
behavior::{CharacterBehavior, JoinData},
|
behavior::{CharacterBehavior, JoinData},
|
||||||
@ -113,11 +116,17 @@ impl CharacterBehavior for Data {
|
|||||||
});
|
});
|
||||||
// Hit attempt
|
// Hit attempt
|
||||||
data.updater.insert(data.entity, Attacking {
|
data.updater.insert(data.entity, Attacking {
|
||||||
damages: vec![(Some(GroupTarget::OutOfGroup), Damage {
|
effects: vec![(
|
||||||
source: DamageSource::Melee,
|
Some(GroupTarget::OutOfGroup),
|
||||||
value: self.static_data.base_damage as f32,
|
Damage {
|
||||||
poise_damage: self.static_data.base_damage as f32,
|
source: DamageSource::Melee,
|
||||||
})],
|
value: self.static_data.base_damage as f32,
|
||||||
|
},
|
||||||
|
PoiseChange {
|
||||||
|
amount: -(self.static_data.base_poise_damage as i32),
|
||||||
|
source: PoiseSource::Melee,
|
||||||
|
},
|
||||||
|
)],
|
||||||
range: self.static_data.range,
|
range: self.static_data.range,
|
||||||
max_angle: 180_f32.to_radians(),
|
max_angle: 180_f32.to_radians(),
|
||||||
applied: false,
|
applied: false,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use common::{
|
use common::{
|
||||||
comp::{
|
comp::{
|
||||||
group, Beam, BeamSegment, Body, Energy, EnergyChange, EnergySource, Health, HealthChange,
|
group, Beam, BeamSegment, Body, Energy, EnergyChange, EnergySource, Health, HealthChange,
|
||||||
HealthSource, Inventory, Last, Ori, Pos, Scale,
|
HealthSource, Inventory, Last, Ori, PoiseChange, PoiseSource, Pos, Scale,
|
||||||
},
|
},
|
||||||
event::{EventBus, ServerEvent},
|
event::{EventBus, ServerEvent},
|
||||||
resources::{DeltaTime, Time},
|
resources::{DeltaTime, Time},
|
||||||
@ -158,7 +158,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (target, damage) in beam_segment.damages.iter() {
|
for (target, damage, poise_damage) in beam_segment.effects.iter() {
|
||||||
if let Some(target) = target {
|
if let Some(target) = target {
|
||||||
if *target != target_group {
|
if *target != target_group {
|
||||||
continue;
|
continue;
|
||||||
@ -167,6 +167,8 @@ impl<'a> System<'a> for Sys {
|
|||||||
|
|
||||||
// Modify damage
|
// Modify damage
|
||||||
let change = damage.modify_damage(inventories.get(b), beam_segment.owner);
|
let change = damage.modify_damage(inventories.get(b), beam_segment.owner);
|
||||||
|
let poise_change = poise_damage
|
||||||
|
.modify_poise_damage(inventories.get(b), beam_segment.owner);
|
||||||
|
|
||||||
match target {
|
match target {
|
||||||
Some(GroupTarget::OutOfGroup) => {
|
Some(GroupTarget::OutOfGroup) => {
|
||||||
@ -174,17 +176,18 @@ impl<'a> System<'a> for Sys {
|
|||||||
if let Some(entity) = beam_owner {
|
if let Some(entity) = beam_owner {
|
||||||
server_emitter.emit(ServerEvent::Damage {
|
server_emitter.emit(ServerEvent::Damage {
|
||||||
entity,
|
entity,
|
||||||
change: (
|
change: HealthChange {
|
||||||
HealthChange {
|
amount: (-change.amount as f32
|
||||||
amount: (-change.0.amount as f32
|
* beam_segment.lifesteal_eff)
|
||||||
* beam_segment.lifesteal_eff)
|
as i32,
|
||||||
as i32,
|
cause: HealthSource::Heal {
|
||||||
cause: HealthSource::Heal {
|
by: beam_segment.owner,
|
||||||
by: beam_segment.owner,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
0,
|
},
|
||||||
),
|
});
|
||||||
|
server_emitter.emit(ServerEvent::PoiseChange {
|
||||||
|
entity,
|
||||||
|
change: poise_change,
|
||||||
});
|
});
|
||||||
server_emitter.emit(ServerEvent::EnergyChange {
|
server_emitter.emit(ServerEvent::EnergyChange {
|
||||||
entity,
|
entity,
|
||||||
|
@ -114,7 +114,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
};
|
};
|
||||||
server_emitter.emit(ServerEvent::Damage {
|
server_emitter.emit(ServerEvent::Damage {
|
||||||
entity,
|
entity,
|
||||||
change: (HealthChange { amount, cause }, 0),
|
change: HealthChange { amount, cause },
|
||||||
});
|
});
|
||||||
*accumulated = 0.0;
|
*accumulated = 0.0;
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use common::{
|
use common::{
|
||||||
comp::{buff, group, Attacking, Body, CharacterState, Health, Inventory, Ori, Pos, Scale},
|
comp::{
|
||||||
|
buff, group, Attacking, Body, CharacterState, Health, Inventory, Ori, Poise, Pos, Scale,
|
||||||
|
},
|
||||||
event::{EventBus, LocalEvent, ServerEvent},
|
event::{EventBus, LocalEvent, ServerEvent},
|
||||||
metrics::SysMetrics,
|
metrics::SysMetrics,
|
||||||
span,
|
span,
|
||||||
@ -118,7 +120,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
GroupTarget::OutOfGroup
|
GroupTarget::OutOfGroup
|
||||||
};
|
};
|
||||||
|
|
||||||
for (target, damage) in attack.damages.iter() {
|
for (target, damage, poise_change) in attack.effects.iter() {
|
||||||
if let Some(target) = target {
|
if let Some(target) = target {
|
||||||
if *target != target_group
|
if *target != target_group
|
||||||
|| (!matches!(target, GroupTarget::InGroup) && is_dodge)
|
|| (!matches!(target, GroupTarget::InGroup) && is_dodge)
|
||||||
@ -128,18 +130,25 @@ impl<'a> System<'a> for Sys {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let change = damage.modify_damage(inventories.get(b), Some(*uid));
|
let change = damage.modify_damage(inventories.get(b), Some(*uid));
|
||||||
|
//let poise_change =
|
||||||
|
// poise_change.modify_poise_damage(loadouts.get(b), Some(*uid));
|
||||||
|
println!("poise_change in melee: {:?}", poise_change);
|
||||||
|
|
||||||
server_emitter.emit(ServerEvent::Damage { entity: b, change });
|
server_emitter.emit(ServerEvent::Damage { entity: b, change });
|
||||||
|
server_emitter.emit(ServerEvent::PoiseChange {
|
||||||
|
entity: b,
|
||||||
|
change: *poise_change,
|
||||||
|
});
|
||||||
// Apply bleeding buff on melee hits with 10% chance
|
// Apply bleeding buff on melee hits with 10% chance
|
||||||
// TODO: Don't have buff uniformly applied on all melee attacks
|
// TODO: Don't have buff uniformly applied on all melee attacks
|
||||||
if change.0.amount < 0 && thread_rng().gen::<f32>() < 0.1 {
|
if change.amount < 0 && thread_rng().gen::<f32>() < 0.1 {
|
||||||
use buff::*;
|
use buff::*;
|
||||||
server_emitter.emit(ServerEvent::Buff {
|
server_emitter.emit(ServerEvent::Buff {
|
||||||
entity: b,
|
entity: b,
|
||||||
buff_change: BuffChange::Add(Buff::new(
|
buff_change: BuffChange::Add(Buff::new(
|
||||||
BuffKind::Bleeding,
|
BuffKind::Bleeding,
|
||||||
BuffData {
|
BuffData {
|
||||||
strength: -change.0.amount as f32 / 10.0,
|
strength: -change.amount as f32 / 10.0,
|
||||||
duration: Some(Duration::from_secs(10)),
|
duration: Some(Duration::from_secs(10)),
|
||||||
},
|
},
|
||||||
vec![BuffCategory::Physical],
|
vec![BuffCategory::Physical],
|
||||||
|
@ -102,7 +102,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
let projectile = &mut *projectile;
|
let projectile = &mut *projectile;
|
||||||
for effect in projectile.hit_entity.drain(..) {
|
for effect in projectile.hit_entity.drain(..) {
|
||||||
match effect {
|
match effect {
|
||||||
projectile::Effect::Damage(target, damage) => {
|
projectile::Effect::Damage(target, damage, poise_damage) => {
|
||||||
if Some(other) == projectile.owner {
|
if Some(other) == projectile.owner {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -119,10 +119,16 @@ impl<'a> System<'a> for Sys {
|
|||||||
let other_entity_inventory = inventories.get(other_entity);
|
let other_entity_inventory = inventories.get(other_entity);
|
||||||
let change =
|
let change =
|
||||||
damage.modify_damage(other_entity_inventory, projectile.owner);
|
damage.modify_damage(other_entity_inventory, projectile.owner);
|
||||||
|
let poise_change = poise_damage
|
||||||
|
.modify_poise_damage(other_entity_inventory, projectile.owner);
|
||||||
server_emitter.emit(ServerEvent::Damage {
|
server_emitter.emit(ServerEvent::Damage {
|
||||||
entity: other_entity,
|
entity: other_entity,
|
||||||
change,
|
change,
|
||||||
});
|
});
|
||||||
|
server_emitter.emit(ServerEvent::PoiseChange {
|
||||||
|
entity: other_entity,
|
||||||
|
change: poise_change,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
projectile::Effect::Knockback(knockback) => {
|
projectile::Effect::Knockback(knockback) => {
|
||||||
|
@ -191,7 +191,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
&& (!shockwave.requires_ground || physics_state_b.on_ground);
|
&& (!shockwave.requires_ground || physics_state_b.on_ground);
|
||||||
|
|
||||||
if hit {
|
if hit {
|
||||||
for (target, damage) in shockwave.damages.iter() {
|
for (target, damage, poise_damage) in shockwave.effects.iter() {
|
||||||
if let Some(target) = target {
|
if let Some(target) = target {
|
||||||
if *target != target_group {
|
if *target != target_group {
|
||||||
continue;
|
continue;
|
||||||
@ -200,8 +200,14 @@ impl<'a> System<'a> for Sys {
|
|||||||
|
|
||||||
let owner_uid = shockwave.owner.unwrap_or(*uid);
|
let owner_uid = shockwave.owner.unwrap_or(*uid);
|
||||||
let change = damage.modify_damage(inventories.get(b), Some(owner_uid));
|
let change = damage.modify_damage(inventories.get(b), Some(owner_uid));
|
||||||
|
let poise_change =
|
||||||
|
poise_damage.modify_poise_damage(inventories.get(b), Some(owner_uid));
|
||||||
|
|
||||||
server_emitter.emit(ServerEvent::Damage { entity: b, change });
|
server_emitter.emit(ServerEvent::Damage { entity: b, change });
|
||||||
|
server_emitter.emit(ServerEvent::PoiseChange {
|
||||||
|
entity: b,
|
||||||
|
change: poise_change,
|
||||||
|
});
|
||||||
shockwave_hit_list.hit_entities.push(*uid_b);
|
shockwave_hit_list.hit_entities.push(*uid_b);
|
||||||
|
|
||||||
let kb_dir = Dir::new((pos_b.0 - pos.0).try_normalized().unwrap_or(*ori.0));
|
let kb_dir = Dir::new((pos_b.0 - pos.0).try_normalized().unwrap_or(*ori.0));
|
||||||
|
@ -1360,14 +1360,10 @@ fn handle_explosion(
|
|||||||
pos: pos.0,
|
pos: pos.0,
|
||||||
explosion: Explosion {
|
explosion: Explosion {
|
||||||
effects: vec![
|
effects: vec![
|
||||||
RadiusEffect::Entity(
|
RadiusEffect::Entity(None, vec![Effect::Damage(Damage {
|
||||||
None,
|
source: DamageSource::Explosion,
|
||||||
Effect::Damage(Damage {
|
value: 100.0 * power,
|
||||||
source: DamageSource::Explosion,
|
})]),
|
||||||
value: 100.0 * power,
|
|
||||||
poise_damage: 100.0,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
RadiusEffect::TerrainDestruction(power),
|
RadiusEffect::TerrainDestruction(power),
|
||||||
],
|
],
|
||||||
radius: 3.0 * power,
|
radius: 3.0 * power,
|
||||||
|
@ -13,8 +13,9 @@ use common::{
|
|||||||
comp::{
|
comp::{
|
||||||
self, aura, buff,
|
self, aura, buff,
|
||||||
chat::{KillSource, KillType},
|
chat::{KillSource, KillType},
|
||||||
object, Alignment, Body, Energy, EnergyChange, Group, Health, HealthChange, HealthSource,
|
object, poise, Alignment, Body, Energy, EnergyChange, Group, Health, HealthChange,
|
||||||
Inventory, Item, Player, Poise, PoiseState, Pos, Stats,
|
HealthSource, Inventory, Item, Player, Poise, PoiseChange, PoiseSource, PoiseState, Pos,
|
||||||
|
Stats,
|
||||||
},
|
},
|
||||||
effect::Effect,
|
effect::Effect,
|
||||||
lottery::Lottery,
|
lottery::Lottery,
|
||||||
@ -35,12 +36,11 @@ use std::time::Duration;
|
|||||||
use tracing::error;
|
use tracing::error;
|
||||||
use vek::Vec3;
|
use vek::Vec3;
|
||||||
|
|
||||||
pub fn handle_damage(server: &Server, entity: EcsEntity, change: (HealthChange, i32)) {
|
pub fn handle_poise(server: &Server, entity: EcsEntity, change: PoiseChange) {
|
||||||
let ecs = &server.state.ecs();
|
let ecs = &server.state.ecs();
|
||||||
if let Some(mut health) = ecs.write_storage::<Health>().get_mut(entity) {
|
|
||||||
health.change_by(change);
|
|
||||||
if let Some(poise) = ecs.write_storage::<Poise>().get_mut(entity) {
|
if let Some(poise) = ecs.write_storage::<Poise>().get_mut(entity) {
|
||||||
poise.change_by(change.1);
|
poise.change_by(change);
|
||||||
|
println!("poise: {:?}", change);
|
||||||
let was_wielded =
|
let was_wielded =
|
||||||
if let Some(character_state) = ecs.read_storage::<comp::CharacterState>().get(entity) {
|
if let Some(character_state) = ecs.read_storage::<comp::CharacterState>().get(entity) {
|
||||||
character_state.is_wield()
|
character_state.is_wield()
|
||||||
@ -116,6 +116,12 @@ pub fn handle_damage(server: &Server, entity: EcsEntity, change: (HealthChange,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn handle_damage(server: &Server, entity: EcsEntity, change: HealthChange) {
|
||||||
|
let ecs = &server.state.ecs();
|
||||||
|
if let Some(health) = ecs.write_storage::<Health>().get_mut(entity) {
|
||||||
|
health.change_by(change);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn handle_knockback(server: &Server, entity: EcsEntity, impulse: Vec3<f32>) {
|
pub fn handle_knockback(server: &Server, entity: EcsEntity, impulse: Vec3<f32>) {
|
||||||
let ecs = &server.state.ecs();
|
let ecs = &server.state.ecs();
|
||||||
@ -559,15 +565,22 @@ pub fn handle_land_on_ground(server: &Server, entity: EcsEntity, vel: Vec3<f32>)
|
|||||||
let state = &server.state;
|
let state = &server.state;
|
||||||
if vel.z <= -30.0 {
|
if vel.z <= -30.0 {
|
||||||
if let Some(mut health) = state.ecs().write_storage::<comp::Health>().get_mut(entity) {
|
if let Some(mut health) = state.ecs().write_storage::<comp::Health>().get_mut(entity) {
|
||||||
let falldmg = (vel.z.powi(2) / 20.0 - 40.0) * 10.0;
|
if let Some(poise) = state.ecs().write_storage::<comp::Poise>().get_mut(entity) {
|
||||||
let damage = Damage {
|
let falldmg = (vel.z.powi(2) / 20.0 - 40.0) * 10.0;
|
||||||
source: DamageSource::Falling,
|
let damage = Damage {
|
||||||
value: falldmg,
|
source: DamageSource::Falling,
|
||||||
poise_damage: 70.0,
|
value: falldmg,
|
||||||
};
|
};
|
||||||
let inventories = state.ecs().read_storage::<Inventory>();
|
let poise_damage = PoiseChange {
|
||||||
let change = damage.modify_damage(inventories.get(entity), None);
|
amount: -(falldmg / 2.0) as i32,
|
||||||
health.change_by(change);
|
source: PoiseSource::Falling,
|
||||||
|
};
|
||||||
|
let inventories = state.ecs().read_storage::<Inventory>();
|
||||||
|
let change = damage.modify_damage(inventories.get(entity), None);
|
||||||
|
let poise_change = poise_damage.modify_poise_damage(inventories.get(entity), None);
|
||||||
|
health.change_by(change);
|
||||||
|
poise.change_by(poise_change);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -641,15 +654,29 @@ pub fn handle_explosion(
|
|||||||
} else {
|
} else {
|
||||||
1.0
|
1.0
|
||||||
};
|
};
|
||||||
|
|
||||||
ecs.write_resource::<Vec<Outcome>>()
|
ecs.write_resource::<Vec<Outcome>>()
|
||||||
.push(Outcome::Explosion {
|
.push(Outcome::Explosion {
|
||||||
pos,
|
pos,
|
||||||
power: outcome_power,
|
power: outcome_power,
|
||||||
radius: explosion.radius,
|
radius: explosion.radius,
|
||||||
is_attack: explosion
|
is_attack: true, //explosion
|
||||||
.effects
|
//.effects
|
||||||
.iter()
|
//.iter()
|
||||||
.any(|e| matches!(e, RadiusEffect::Entity(_, Effect::Damage(_)))),
|
////.any(|e| matches!(e, RadiusEffect::Entity(_, Effect::Damage(_)))),
|
||||||
|
//.any(|e| match e {
|
||||||
|
// RadiusEffect::Entity(_, effect_vec) => {
|
||||||
|
// effect_vec.iter().any(|f| {
|
||||||
|
// matches!(
|
||||||
|
// f,
|
||||||
|
// Effect::Damage(Damage {
|
||||||
|
// source: DamageSource::Healing,
|
||||||
|
// ..
|
||||||
|
// })
|
||||||
|
// )
|
||||||
|
// })
|
||||||
|
// },
|
||||||
|
//}),
|
||||||
reagent,
|
reagent,
|
||||||
});
|
});
|
||||||
let owner_entity = owner.and_then(|uid| {
|
let owner_entity = owner.and_then(|uid| {
|
||||||
@ -733,7 +760,7 @@ pub fn handle_explosion(
|
|||||||
.cast();
|
.cast();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
RadiusEffect::Entity(target, mut effect) => {
|
RadiusEffect::Entity(target, mut effects) => {
|
||||||
for (entity_b, pos_b) in (&ecs.entities(), &ecs.read_storage::<comp::Pos>()).join()
|
for (entity_b, pos_b) in (&ecs.entities(), &ecs.read_storage::<comp::Pos>()).join()
|
||||||
{
|
{
|
||||||
// See if entities are in the same group
|
// See if entities are in the same group
|
||||||
@ -767,17 +794,19 @@ pub fn handle_explosion(
|
|||||||
.map_or(false, |h| !h.is_dead);
|
.map_or(false, |h| !h.is_dead);
|
||||||
|
|
||||||
if is_alive {
|
if is_alive {
|
||||||
effect.modify_strength(strength);
|
for effect in effects.iter_mut() {
|
||||||
server.state().apply_effect(entity_b, effect.clone(), owner);
|
effect.modify_strength(strength);
|
||||||
// Apply energy change
|
server.state().apply_effect(entity_b, effect.clone(), owner);
|
||||||
if let Some(owner) = owner_entity {
|
// Apply energy change
|
||||||
if let Some(mut energy) =
|
if let Some(owner) = owner_entity {
|
||||||
ecs.write_storage::<comp::Energy>().get_mut(owner)
|
if let Some(mut energy) =
|
||||||
{
|
ecs.write_storage::<comp::Energy>().get_mut(owner)
|
||||||
energy.change_by(EnergyChange {
|
{
|
||||||
amount: explosion.energy_regen as i32,
|
energy.change_by(EnergyChange {
|
||||||
source: comp::EnergySource::HitEnemy,
|
amount: explosion.energy_regen as i32,
|
||||||
});
|
source: comp::EnergySource::HitEnemy,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ use entity_creation::{
|
|||||||
};
|
};
|
||||||
use entity_manipulation::{
|
use entity_manipulation::{
|
||||||
handle_aura, handle_buff, handle_damage, handle_delete, handle_destroy, handle_energy_change,
|
handle_aura, handle_buff, handle_damage, handle_delete, handle_destroy, handle_energy_change,
|
||||||
handle_explosion, handle_knockback, handle_land_on_ground, handle_respawn,
|
handle_explosion, handle_knockback, handle_land_on_ground, handle_poise, handle_respawn,
|
||||||
};
|
};
|
||||||
use group_manip::handle_group;
|
use group_manip::handle_group;
|
||||||
use interaction::{handle_lantern, handle_mount, handle_possess, handle_unmount};
|
use interaction::{handle_lantern, handle_mount, handle_possess, handle_unmount};
|
||||||
@ -83,6 +83,7 @@ impl Server {
|
|||||||
handle_knockback(&self, entity, impulse)
|
handle_knockback(&self, entity, impulse)
|
||||||
},
|
},
|
||||||
ServerEvent::Damage { entity, change } => handle_damage(&self, entity, change),
|
ServerEvent::Damage { entity, change } => handle_damage(&self, entity, change),
|
||||||
|
ServerEvent::PoiseChange { entity, change } => handle_poise(&self, entity, change),
|
||||||
ServerEvent::Delete(entity) => handle_delete(self, entity),
|
ServerEvent::Delete(entity) => handle_delete(self, entity),
|
||||||
ServerEvent::Destroy { entity, cause } => handle_destroy(self, entity, cause),
|
ServerEvent::Destroy { entity, cause } => handle_destroy(self, entity, cause),
|
||||||
ServerEvent::InventoryManip(entity, manip) => handle_inventory(self, entity, manip),
|
ServerEvent::InventoryManip(entity, manip) => handle_inventory(self, entity, manip),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use common::{
|
use common::{
|
||||||
comp::{HealthSource, Object, PhysicsState, Pos, Vel},
|
comp::{HealthSource, Object, PhysicsState, PoiseChange, PoiseSource, Pos, Vel},
|
||||||
effect::Effect,
|
effect::Effect,
|
||||||
event::{EventBus, ServerEvent},
|
event::{EventBus, ServerEvent},
|
||||||
resources::DeltaTime,
|
resources::DeltaTime,
|
||||||
@ -49,14 +49,16 @@ impl<'a> System<'a> for Sys {
|
|||||||
pos: pos.0,
|
pos: pos.0,
|
||||||
explosion: Explosion {
|
explosion: Explosion {
|
||||||
effects: vec![
|
effects: vec![
|
||||||
RadiusEffect::Entity(
|
RadiusEffect::Entity(None, vec![
|
||||||
None,
|
|
||||||
Effect::Damage(Damage {
|
Effect::Damage(Damage {
|
||||||
source: DamageSource::Explosion,
|
source: DamageSource::Explosion,
|
||||||
value: 500.0,
|
value: 500.0,
|
||||||
poise_damage: 60.0,
|
|
||||||
}),
|
}),
|
||||||
),
|
Effect::Poise(PoiseChange {
|
||||||
|
amount: -60,
|
||||||
|
source: PoiseSource::Explosion,
|
||||||
|
}),
|
||||||
|
]),
|
||||||
RadiusEffect::TerrainDestruction(4.0),
|
RadiusEffect::TerrainDestruction(4.0),
|
||||||
],
|
],
|
||||||
radius: 12.0,
|
radius: 12.0,
|
||||||
@ -77,14 +79,16 @@ impl<'a> System<'a> for Sys {
|
|||||||
pos: pos.0,
|
pos: pos.0,
|
||||||
explosion: Explosion {
|
explosion: Explosion {
|
||||||
effects: vec![
|
effects: vec![
|
||||||
RadiusEffect::Entity(
|
RadiusEffect::Entity(None, vec![
|
||||||
None,
|
|
||||||
Effect::Damage(Damage {
|
Effect::Damage(Damage {
|
||||||
source: DamageSource::Explosion,
|
source: DamageSource::Explosion,
|
||||||
value: 50.0,
|
value: 50.0,
|
||||||
poise_damage: 10.0,
|
|
||||||
}),
|
}),
|
||||||
),
|
Effect::Poise(PoiseChange {
|
||||||
|
amount: -30,
|
||||||
|
source: PoiseSource::Explosion,
|
||||||
|
}),
|
||||||
|
]),
|
||||||
RadiusEffect::TerrainDestruction(4.0),
|
RadiusEffect::TerrainDestruction(4.0),
|
||||||
],
|
],
|
||||||
radius: 12.0,
|
radius: 12.0,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user