mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Transitioned damage and healing from u32/i32s to enums.
This commit is contained in:
parent
844e6f2b60
commit
a7e3e55a12
161
common/src/combat.rs
Normal file
161
common/src/combat.rs
Normal file
@ -0,0 +1,161 @@
|
||||
use crate::{
|
||||
comp::{HealthChange, HealthSource, Loadout},
|
||||
sync::Uid,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub const BLOCK_EFFICIENCY: f32 = 0.9;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Damages {
|
||||
pub enemy: Option<Damage>,
|
||||
pub group: Option<Damage>,
|
||||
}
|
||||
|
||||
impl Damages {
|
||||
pub fn new(enemy: Option<Damage>, group: Option<Damage>) -> Self { Damages { enemy, group } }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum Damage {
|
||||
Melee(f32),
|
||||
Healing(f32),
|
||||
Projectile(f32),
|
||||
Explosion(f32),
|
||||
Falling(f32),
|
||||
Shockwave(f32),
|
||||
Energy(f32),
|
||||
}
|
||||
|
||||
impl Damage {
|
||||
pub fn modify_damage(
|
||||
self,
|
||||
block: bool,
|
||||
loadout: Option<&Loadout>,
|
||||
uid: Option<Uid>,
|
||||
) -> HealthChange {
|
||||
match self {
|
||||
Damage::Melee(damage) => {
|
||||
let mut damage = damage;
|
||||
// Critical hit
|
||||
let mut critdamage = 0.0;
|
||||
if rand::random() {
|
||||
critdamage = damage * 0.3;
|
||||
}
|
||||
// Block
|
||||
if block {
|
||||
damage *= 1.0 - BLOCK_EFFICIENCY
|
||||
}
|
||||
// Armor
|
||||
let damage_reduction = if let Some(loadout) = loadout {
|
||||
loadout.get_damage_reduction()
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
damage *= 1.0 - damage_reduction;
|
||||
|
||||
// Critical damage applies after armor for melee
|
||||
if (damage_reduction - 1.0).abs() > f32::EPSILON {
|
||||
damage += critdamage;
|
||||
}
|
||||
|
||||
HealthChange {
|
||||
amount: -damage as i32,
|
||||
cause: HealthSource::Attack { by: uid.unwrap() },
|
||||
}
|
||||
},
|
||||
Damage::Projectile(damage) => {
|
||||
let mut damage = damage;
|
||||
// Critical hit
|
||||
if rand::random() {
|
||||
damage *= 1.2;
|
||||
}
|
||||
// Block
|
||||
if block {
|
||||
damage *= 1.0 - BLOCK_EFFICIENCY
|
||||
}
|
||||
// Armor
|
||||
let damage_reduction = if let Some(loadout) = loadout {
|
||||
loadout.get_damage_reduction()
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
damage *= 1.0 - damage_reduction;
|
||||
|
||||
HealthChange {
|
||||
amount: -damage as i32,
|
||||
cause: HealthSource::Projectile { owner: uid },
|
||||
}
|
||||
},
|
||||
Damage::Explosion(damage) => {
|
||||
let mut damage = damage;
|
||||
// Block
|
||||
if block {
|
||||
damage *= 1.0 - BLOCK_EFFICIENCY
|
||||
}
|
||||
// Armor
|
||||
let damage_reduction = if let Some(loadout) = loadout {
|
||||
loadout.get_damage_reduction()
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
damage *= 1.0 - damage_reduction;
|
||||
|
||||
HealthChange {
|
||||
amount: -damage as i32,
|
||||
cause: HealthSource::Explosion { owner: uid },
|
||||
}
|
||||
},
|
||||
Damage::Shockwave(damage) => {
|
||||
let mut damage = damage;
|
||||
// Armor
|
||||
let damage_reduction = if let Some(loadout) = loadout {
|
||||
loadout.get_damage_reduction()
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
damage *= 1.0 - damage_reduction;
|
||||
|
||||
HealthChange {
|
||||
amount: -damage as i32,
|
||||
cause: HealthSource::Attack { by: uid.unwrap() },
|
||||
}
|
||||
},
|
||||
Damage::Energy(damage) => {
|
||||
let mut damage = damage;
|
||||
// Armor
|
||||
let damage_reduction = if let Some(loadout) = loadout {
|
||||
loadout.get_damage_reduction()
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
damage *= 1.0 - damage_reduction;
|
||||
|
||||
HealthChange {
|
||||
amount: -damage as i32,
|
||||
cause: HealthSource::Energy { owner: uid },
|
||||
}
|
||||
},
|
||||
Damage::Healing(heal) => HealthChange {
|
||||
amount: heal as i32,
|
||||
cause: HealthSource::Healing { by: uid },
|
||||
},
|
||||
Damage::Falling(damage) => {
|
||||
let mut damage = damage;
|
||||
// Armor
|
||||
let damage_reduction = if let Some(loadout) = loadout {
|
||||
loadout.get_damage_reduction()
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
if (damage_reduction - 1.0).abs() < f32::EPSILON {
|
||||
damage = 0.0;
|
||||
}
|
||||
HealthChange {
|
||||
amount: -damage as i32,
|
||||
cause: HealthSource::World,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
use crate::sync::Uid;
|
||||
use crate::{sync::Uid, Damages};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specs::{Component, FlaggedStorage};
|
||||
use specs_idvs::IdvStorage;
|
||||
@ -8,8 +8,7 @@ use std::time::Duration;
|
||||
pub struct Properties {
|
||||
pub angle: f32,
|
||||
pub speed: f32,
|
||||
pub damage: u32,
|
||||
pub heal: u32,
|
||||
pub damages: Damages,
|
||||
pub lifesteal_eff: f32,
|
||||
pub energy_regen: u32,
|
||||
pub energy_cost: u32,
|
||||
|
@ -3,6 +3,7 @@ use crate::{
|
||||
event::{LocalEvent, ServerEvent},
|
||||
states::*,
|
||||
sys::character_behavior::JoinData,
|
||||
Damages,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specs::{Component, FlaggedStorage, VecStorage};
|
||||
@ -152,8 +153,7 @@ impl Component for CharacterState {
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Attacking {
|
||||
pub base_damage: u32,
|
||||
pub base_heal: u32,
|
||||
pub damages: Damages,
|
||||
pub range: f32,
|
||||
pub max_angle: f32,
|
||||
pub applied: bool,
|
||||
|
@ -1,79 +0,0 @@
|
||||
use crate::comp::Loadout;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub const BLOCK_EFFICIENCY: f32 = 0.9;
|
||||
|
||||
pub struct Damage {
|
||||
pub healthchange: f32,
|
||||
pub source: DamageSource,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum DamageSource {
|
||||
Melee,
|
||||
Healing,
|
||||
Projectile,
|
||||
Explosion,
|
||||
Falling,
|
||||
Shockwave,
|
||||
Energy,
|
||||
}
|
||||
|
||||
impl Damage {
|
||||
pub fn modify_damage(&mut self, block: bool, loadout: &Loadout) {
|
||||
match self.source {
|
||||
DamageSource::Melee => {
|
||||
// Critical hit
|
||||
let mut critdamage = 0.0;
|
||||
if rand::random() {
|
||||
critdamage = self.healthchange * 0.3;
|
||||
}
|
||||
// Block
|
||||
if block {
|
||||
self.healthchange *= 1.0 - BLOCK_EFFICIENCY
|
||||
}
|
||||
// Armor
|
||||
let damage_reduction = loadout.get_damage_reduction();
|
||||
self.healthchange *= 1.0 - damage_reduction;
|
||||
|
||||
// Critical damage applies after armor for melee
|
||||
if (damage_reduction - 1.0).abs() > f32::EPSILON {
|
||||
self.healthchange += critdamage;
|
||||
}
|
||||
},
|
||||
DamageSource::Projectile => {
|
||||
// Critical hit
|
||||
if rand::random() {
|
||||
self.healthchange *= 1.2;
|
||||
}
|
||||
// Block
|
||||
if block {
|
||||
self.healthchange *= 1.0 - BLOCK_EFFICIENCY
|
||||
}
|
||||
// Armor
|
||||
let damage_reduction = loadout.get_damage_reduction();
|
||||
self.healthchange *= 1.0 - damage_reduction;
|
||||
},
|
||||
DamageSource::Explosion => {
|
||||
// Block
|
||||
if block {
|
||||
self.healthchange *= 1.0 - BLOCK_EFFICIENCY
|
||||
}
|
||||
// Armor
|
||||
let damage_reduction = loadout.get_damage_reduction();
|
||||
self.healthchange *= 1.0 - damage_reduction;
|
||||
},
|
||||
DamageSource::Shockwave => {
|
||||
// Armor
|
||||
let damage_reduction = loadout.get_damage_reduction();
|
||||
self.healthchange *= 1.0 - damage_reduction;
|
||||
},
|
||||
DamageSource::Energy => {
|
||||
// Armor
|
||||
let damage_reduction = loadout.get_damage_reduction();
|
||||
self.healthchange *= 1.0 - damage_reduction;
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
use crate::{
|
||||
comp::{body::object, projectile, Body, CharacterAbility, Gravity, LightEmitter, Projectile},
|
||||
states::combo_melee,
|
||||
Explosion,
|
||||
Damage, Damages, Explosion,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
@ -298,7 +298,10 @@ impl Tool {
|
||||
projectile: Projectile {
|
||||
hit_solid: vec![projectile::Effect::Stick],
|
||||
hit_entity: vec![
|
||||
projectile::Effect::Damage((-40.0 * self.base_power()) as i32),
|
||||
projectile::Effect::Damages(Damages::new(
|
||||
Some(Damage::Projectile(40.0 * self.base_power())),
|
||||
None,
|
||||
)),
|
||||
projectile::Effect::Knockback(10.0),
|
||||
projectile::Effect::RewardEnergy(50),
|
||||
projectile::Effect::Vanish,
|
||||
@ -338,7 +341,10 @@ impl Tool {
|
||||
projectile: Projectile {
|
||||
hit_solid: vec![projectile::Effect::Stick],
|
||||
hit_entity: vec![
|
||||
projectile::Effect::Damage((-40.0 * self.base_power()) as i32),
|
||||
projectile::Effect::Damages(Damages::new(
|
||||
Some(Damage::Projectile(40.0 * self.base_power())),
|
||||
None,
|
||||
)),
|
||||
projectile::Effect::Knockback(10.0),
|
||||
projectile::Effect::RewardEnergy(50),
|
||||
projectile::Effect::Vanish,
|
||||
|
@ -7,7 +7,6 @@ pub mod buff;
|
||||
mod character_state;
|
||||
pub mod chat;
|
||||
mod controller;
|
||||
mod damage;
|
||||
mod energy;
|
||||
pub mod group;
|
||||
mod inputs;
|
||||
@ -44,7 +43,6 @@ pub use controller::{
|
||||
Climb, ControlAction, ControlEvent, Controller, ControllerInputs, GroupManip, Input,
|
||||
InventoryManip, MountState, Mounting,
|
||||
};
|
||||
pub use damage::{Damage, DamageSource};
|
||||
pub use energy::{Energy, EnergySource};
|
||||
pub use group::Group;
|
||||
pub use inputs::CanBuild;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{sync::Uid, Explosion};
|
||||
use crate::{sync::Uid, Damages, Explosion};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specs::{Component, FlaggedStorage};
|
||||
use specs_idvs::IdvStorage;
|
||||
@ -6,7 +6,7 @@ use std::time::Duration;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum Effect {
|
||||
Damage(i32),
|
||||
Damages(Damages),
|
||||
Knockback(f32),
|
||||
RewardEnergy(u32),
|
||||
Explode(Explosion),
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::sync::Uid;
|
||||
use crate::{sync::Uid, Damages};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specs::{Component, FlaggedStorage};
|
||||
use specs_idvs::IdvStorage;
|
||||
@ -9,7 +9,7 @@ pub struct Properties {
|
||||
pub angle: f32,
|
||||
pub vertical_angle: f32,
|
||||
pub speed: f32,
|
||||
pub damage: u32,
|
||||
pub damages: Damages,
|
||||
pub knockback: f32,
|
||||
pub requires_ground: bool,
|
||||
pub duration: Duration,
|
||||
|
@ -22,6 +22,7 @@ pub mod astar;
|
||||
pub mod character;
|
||||
pub mod clock;
|
||||
pub mod cmd;
|
||||
pub mod combat;
|
||||
pub mod comp;
|
||||
pub mod effect;
|
||||
pub mod event;
|
||||
@ -51,5 +52,6 @@ pub mod util;
|
||||
pub mod vol;
|
||||
pub mod volumes;
|
||||
|
||||
pub use combat::{Damage, Damages};
|
||||
pub use explosion::Explosion;
|
||||
pub use loadout_builder::LoadoutBuilder;
|
||||
|
@ -9,5 +9,5 @@ pub struct SysMetrics {
|
||||
pub stats_ns: AtomicI64,
|
||||
pub phys_ns: AtomicI64,
|
||||
pub projectile_ns: AtomicI64,
|
||||
pub combat_ns: AtomicI64,
|
||||
pub melee_ns: AtomicI64,
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ use crate::{
|
||||
states::utils::*,
|
||||
sync::Uid,
|
||||
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||
Damage, Damages,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
@ -108,10 +109,12 @@ impl CharacterBehavior for Data {
|
||||
if ability_key_is_pressed(data, self.static_data.ability_key)
|
||||
&& (self.static_data.energy_drain == 0 || update.energy.current() > 0)
|
||||
{
|
||||
let damage =
|
||||
(self.static_data.base_dps as f32 / self.static_data.tick_rate) as u32;
|
||||
let heal =
|
||||
(self.static_data.base_hps as f32 / self.static_data.tick_rate) as u32;
|
||||
let damage = Damage::Energy(
|
||||
self.static_data.base_dps as f32 / self.static_data.tick_rate,
|
||||
);
|
||||
let heal = Damage::Healing(
|
||||
self.static_data.base_hps as f32 / self.static_data.tick_rate,
|
||||
);
|
||||
let energy_regen =
|
||||
(self.static_data.energy_regen as f32 / self.static_data.tick_rate) as u32;
|
||||
let energy_cost =
|
||||
@ -121,8 +124,7 @@ impl CharacterBehavior for Data {
|
||||
let properties = beam::Properties {
|
||||
angle: self.static_data.max_angle.to_radians(),
|
||||
speed,
|
||||
damage,
|
||||
heal,
|
||||
damages: Damages::new(Some(damage), Some(heal)),
|
||||
lifesteal_eff: self.static_data.lifesteal_eff,
|
||||
energy_regen,
|
||||
energy_cost,
|
||||
|
@ -2,6 +2,7 @@ use crate::{
|
||||
comp::{Attacking, CharacterState, EnergySource, StateUpdate},
|
||||
states::utils::*,
|
||||
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||
Damage, Damages,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
@ -79,8 +80,10 @@ impl CharacterBehavior for Data {
|
||||
|
||||
// Hit attempt
|
||||
data.updater.insert(data.entity, Attacking {
|
||||
base_damage: self.static_data.base_damage,
|
||||
base_heal: 0,
|
||||
damages: Damages::new(
|
||||
Some(Damage::Melee(self.static_data.base_damage as f32)),
|
||||
None,
|
||||
),
|
||||
range: self.static_data.range,
|
||||
max_angle: 180_f32.to_radians(),
|
||||
applied: false,
|
||||
|
@ -2,6 +2,7 @@ use crate::{
|
||||
comp::{Attacking, CharacterState, EnergySource, StateUpdate},
|
||||
states::utils::{StageSection, *},
|
||||
sys::character_behavior::*,
|
||||
Damage, Damages,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
@ -115,17 +116,16 @@ impl CharacterBehavior for Data {
|
||||
},
|
||||
StageSection::Swing => {
|
||||
if !self.exhausted {
|
||||
let damage = self.static_data.initial_damage
|
||||
+ ((self.static_data.max_damage - self.static_data.initial_damage) as f32
|
||||
* self.charge_amount) as u32;
|
||||
let damage = self.static_data.initial_damage as f32
|
||||
+ (self.static_data.max_damage - self.static_data.initial_damage) as f32
|
||||
* self.charge_amount;
|
||||
let knockback = self.static_data.initial_knockback
|
||||
+ (self.static_data.max_knockback - self.static_data.initial_knockback)
|
||||
* self.charge_amount;
|
||||
|
||||
// Hit attempt
|
||||
data.updater.insert(data.entity, Attacking {
|
||||
base_damage: damage as u32,
|
||||
base_heal: 0,
|
||||
damages: Damages::new(Some(Damage::Melee(damage)), None),
|
||||
range: self.static_data.range,
|
||||
max_angle: self.static_data.max_angle.to_radians(),
|
||||
applied: false,
|
||||
|
@ -6,6 +6,7 @@ use crate::{
|
||||
event::ServerEvent,
|
||||
states::utils::*,
|
||||
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||
Damage, Damages,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
@ -97,7 +98,10 @@ impl CharacterBehavior for Data {
|
||||
let mut projectile = Projectile {
|
||||
hit_solid: vec![projectile::Effect::Stick],
|
||||
hit_entity: vec![
|
||||
projectile::Effect::Damage(-damage as i32),
|
||||
projectile::Effect::Damages(Damages::new(
|
||||
Some(Damage::Projectile(damage)),
|
||||
None,
|
||||
)),
|
||||
projectile::Effect::Knockback(knockback),
|
||||
projectile::Effect::Vanish,
|
||||
],
|
||||
|
@ -2,6 +2,7 @@ use crate::{
|
||||
comp::{Attacking, CharacterState, EnergySource, StateUpdate},
|
||||
states::utils::*,
|
||||
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||
Damage, Damages,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
@ -125,13 +126,13 @@ impl CharacterBehavior for Data {
|
||||
});
|
||||
|
||||
// Hit attempt
|
||||
let damage = self.static_data.stage_data[stage_index].max_damage.min(
|
||||
self.static_data.stage_data[stage_index].base_damage
|
||||
+ self.combo / self.static_data.num_stages
|
||||
* self.static_data.stage_data[stage_index].damage_increase,
|
||||
);
|
||||
data.updater.insert(data.entity, Attacking {
|
||||
base_damage: self.static_data.stage_data[stage_index].max_damage.min(
|
||||
self.static_data.stage_data[stage_index].base_damage
|
||||
+ self.combo / self.static_data.num_stages
|
||||
* self.static_data.stage_data[stage_index].damage_increase,
|
||||
),
|
||||
base_heal: 0,
|
||||
damages: Damages::new(Some(Damage::Melee(damage as f32)), None),
|
||||
range: self.static_data.stage_data[stage_index].range,
|
||||
max_angle: self.static_data.stage_data[stage_index].angle.to_radians(),
|
||||
applied: false,
|
||||
|
@ -2,6 +2,7 @@ use crate::{
|
||||
comp::{Attacking, CharacterState, EnergySource, StateUpdate},
|
||||
states::utils::*,
|
||||
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||
Damage, Damages,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
@ -121,8 +122,7 @@ impl CharacterBehavior for Data {
|
||||
* charge_frac
|
||||
+ self.static_data.base_knockback;
|
||||
data.updater.insert(data.entity, Attacking {
|
||||
base_damage: damage as u32,
|
||||
base_heal: 0,
|
||||
damages: Damages::new(Some(Damage::Melee(damage)), None),
|
||||
range: self.static_data.range,
|
||||
max_angle: self.static_data.angle.to_radians(),
|
||||
applied: false,
|
||||
|
@ -2,6 +2,7 @@ use crate::{
|
||||
comp::{Attacking, CharacterState, StateUpdate},
|
||||
states::utils::{StageSection, *},
|
||||
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||
Damage, Damages,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
@ -141,8 +142,10 @@ impl CharacterBehavior for Data {
|
||||
if !self.exhausted {
|
||||
// Hit attempt, when animation plays
|
||||
data.updater.insert(data.entity, Attacking {
|
||||
base_damage: self.static_data.base_damage,
|
||||
base_heal: 0,
|
||||
damages: Damages::new(
|
||||
Some(Damage::Melee(self.static_data.base_damage as f32)),
|
||||
None,
|
||||
),
|
||||
range: self.static_data.range,
|
||||
max_angle: self.static_data.max_angle.to_radians(),
|
||||
applied: false,
|
||||
|
@ -3,6 +3,7 @@ use crate::{
|
||||
event::ServerEvent,
|
||||
states::utils::*,
|
||||
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||
Damage, Damages,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
@ -70,7 +71,10 @@ impl CharacterBehavior for Data {
|
||||
vertical_angle: self.static_data.shockwave_vertical_angle,
|
||||
speed: self.static_data.shockwave_speed,
|
||||
duration: self.static_data.shockwave_duration,
|
||||
damage: self.static_data.damage,
|
||||
damages: Damages::new(
|
||||
Some(Damage::Shockwave(self.static_data.damage as f32)),
|
||||
None,
|
||||
),
|
||||
knockback: self.static_data.knockback,
|
||||
requires_ground: self.static_data.requires_ground,
|
||||
owner: Some(*data.uid),
|
||||
|
@ -5,6 +5,7 @@ use crate::{
|
||||
character_behavior::{CharacterBehavior, JoinData},
|
||||
phys::GRAVITY,
|
||||
},
|
||||
Damage, Damages,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
@ -110,8 +111,10 @@ impl CharacterBehavior for Data {
|
||||
});
|
||||
// Hit attempt
|
||||
data.updater.insert(data.entity, Attacking {
|
||||
base_damage: self.static_data.base_damage,
|
||||
base_heal: 0,
|
||||
damages: Damages::new(
|
||||
Some(Damage::Melee(self.static_data.base_damage as f32)),
|
||||
None,
|
||||
),
|
||||
range: self.static_data.range,
|
||||
max_angle: 180_f32.to_radians(),
|
||||
applied: false,
|
||||
|
@ -1,11 +1,12 @@
|
||||
use crate::{
|
||||
comp::{
|
||||
group, Beam, BeamSegment, Body, CharacterState, Damage, DamageSource, Energy, EnergySource,
|
||||
HealthChange, HealthSource, Last, Loadout, Ori, Pos, Scale, Stats,
|
||||
group, Beam, BeamSegment, Body, CharacterState, Energy, EnergySource, HealthChange,
|
||||
HealthSource, Last, Loadout, Ori, Pos, Scale, Stats,
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
state::{DeltaTime, Time},
|
||||
sync::{Uid, UidAllocator},
|
||||
Damage,
|
||||
};
|
||||
use specs::{saveload::MarkerAllocator, Entities, Join, Read, ReadStorage, System, WriteStorage};
|
||||
use std::time::Duration;
|
||||
@ -166,54 +167,31 @@ impl<'a> System<'a> for Sys {
|
||||
if Some(*uid_b) == beam_segment.owner {
|
||||
continue;
|
||||
}
|
||||
// Don't heal if outside group
|
||||
// Don't damage in the same group
|
||||
let is_damage = !same_group && (beam_segment.damage > 0);
|
||||
let is_heal = same_group && (beam_segment.heal > 0);
|
||||
if !is_heal && !is_damage {
|
||||
|
||||
let damage = if !same_group && beam_segment.damages.enemy.is_some() {
|
||||
beam_segment.damages.enemy.unwrap()
|
||||
} else if same_group && beam_segment.damages.group.is_some() {
|
||||
beam_segment.damages.group.unwrap()
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Weapon gives base damage
|
||||
let source = if is_heal {
|
||||
DamageSource::Healing
|
||||
} else {
|
||||
DamageSource::Energy
|
||||
};
|
||||
let healthchange = if is_heal {
|
||||
beam_segment.heal as f32
|
||||
} else {
|
||||
-(beam_segment.damage as f32)
|
||||
};
|
||||
|
||||
let mut damage = Damage {
|
||||
healthchange,
|
||||
source,
|
||||
};
|
||||
|
||||
let block = character_b.map(|c_b| c_b.is_block()).unwrap_or(false)
|
||||
// TODO: investigate whether this calculation is proper for beams
|
||||
&& ori_b.0.angle_between(pos.0 - pos_b.0) < BLOCK_ANGLE.to_radians() / 2.0;
|
||||
|
||||
if let Some(loadout) = loadouts.get(b) {
|
||||
damage.modify_damage(block, loadout);
|
||||
}
|
||||
let change = damage.modify_damage(block, loadouts.get(b), beam_segment.owner);
|
||||
|
||||
if is_damage {
|
||||
if let Damage::Energy(_) = damage {
|
||||
server_emitter.emit(ServerEvent::Damage {
|
||||
uid: *uid_b,
|
||||
change: HealthChange {
|
||||
amount: damage.healthchange as i32,
|
||||
cause: HealthSource::Energy {
|
||||
owner: beam_segment.owner,
|
||||
},
|
||||
},
|
||||
change,
|
||||
});
|
||||
if beam_segment.lifesteal_eff > 0.0 {
|
||||
server_emitter.emit(ServerEvent::Damage {
|
||||
uid: beam_segment.owner.unwrap_or(*uid),
|
||||
change: HealthChange {
|
||||
amount: (-damage.healthchange * beam_segment.lifesteal_eff)
|
||||
amount: (-change.amount as f32 * beam_segment.lifesteal_eff)
|
||||
as i32,
|
||||
cause: HealthSource::Healing {
|
||||
by: beam_segment.owner,
|
||||
@ -228,7 +206,7 @@ impl<'a> System<'a> for Sys {
|
||||
);
|
||||
}
|
||||
}
|
||||
if is_heal {
|
||||
if let Damage::Healing(_) = damage {
|
||||
if let Some(energy_mut) = beam_owner.and_then(|o| energies.get_mut(o)) {
|
||||
if energy_mut
|
||||
.try_change_by(
|
||||
@ -239,12 +217,7 @@ impl<'a> System<'a> for Sys {
|
||||
{
|
||||
server_emitter.emit(ServerEvent::Damage {
|
||||
uid: *uid_b,
|
||||
change: HealthChange {
|
||||
amount: damage.healthchange as i32,
|
||||
cause: HealthSource::Healing {
|
||||
by: beam_segment.owner,
|
||||
},
|
||||
},
|
||||
change,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,5 @@
|
||||
use crate::{
|
||||
comp::{
|
||||
buff, group, Attacking, Body, CharacterState, Damage, DamageSource, HealthChange,
|
||||
HealthSource, Loadout, Ori, Pos, Scale, Stats,
|
||||
},
|
||||
comp::{buff, group, Attacking, Body, CharacterState, Loadout, Ori, Pos, Scale, Stats},
|
||||
event::{EventBus, LocalEvent, ServerEvent},
|
||||
metrics::SysMetrics,
|
||||
span,
|
||||
@ -59,7 +56,7 @@ impl<'a> System<'a> for Sys {
|
||||
): Self::SystemData,
|
||||
) {
|
||||
let start_time = std::time::Instant::now();
|
||||
span!(_guard, "run", "combat::Sys::run");
|
||||
span!(_guard, "run", "melee::Sys::run");
|
||||
let mut server_emitter = server_bus.emitter();
|
||||
let mut _local_emitter = local_bus.emitter();
|
||||
// Attacks
|
||||
@ -113,56 +110,36 @@ impl<'a> System<'a> for Sys {
|
||||
.get(entity)
|
||||
.map(|group_a| Some(group_a) == groups.get(b))
|
||||
.unwrap_or(false);
|
||||
// Don't heal if outside group
|
||||
// Don't damage in the same group
|
||||
let is_damage = !same_group && (attack.base_damage > 0);
|
||||
let is_heal = same_group && (attack.base_heal > 0);
|
||||
if !is_heal && !is_damage {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Weapon gives base damage
|
||||
let (source, healthchange) = if is_heal {
|
||||
(DamageSource::Healing, attack.base_heal as f32)
|
||||
let damage = if !same_group && attack.damages.enemy.is_some() {
|
||||
attack.damages.enemy.unwrap()
|
||||
} else if same_group && attack.damages.group.is_some() {
|
||||
attack.damages.group.unwrap()
|
||||
} else {
|
||||
(DamageSource::Melee, -(attack.base_damage as f32))
|
||||
};
|
||||
let mut damage = Damage {
|
||||
healthchange,
|
||||
source,
|
||||
continue;
|
||||
};
|
||||
|
||||
let block = character_b.map(|c_b| c_b.is_block()).unwrap_or(false)
|
||||
&& ori_b.0.angle_between(pos.0 - pos_b.0) < BLOCK_ANGLE.to_radians() / 2.0;
|
||||
|
||||
if let Some(loadout) = loadouts.get(b) {
|
||||
damage.modify_damage(block, loadout);
|
||||
}
|
||||
let change = damage.modify_damage(block, loadouts.get(b), Some(*uid));
|
||||
|
||||
if damage.healthchange != 0.0 {
|
||||
let cause = if is_heal {
|
||||
HealthSource::Healing { by: Some(*uid) }
|
||||
} else {
|
||||
HealthSource::Attack { by: *uid }
|
||||
};
|
||||
if change.amount != 0 {
|
||||
server_emitter.emit(ServerEvent::Damage {
|
||||
uid: *uid_b,
|
||||
change: HealthChange {
|
||||
amount: damage.healthchange as i32,
|
||||
cause,
|
||||
},
|
||||
change,
|
||||
});
|
||||
|
||||
// Apply bleeding buff on melee hits with 10% chance
|
||||
// TODO: Don't have buff uniformly applied on all melee attacks
|
||||
if thread_rng().gen::<f32>() < 0.1 {
|
||||
if change.amount < 0 && thread_rng().gen::<f32>() < 0.1 {
|
||||
use buff::*;
|
||||
server_emitter.emit(ServerEvent::Buff {
|
||||
entity: b,
|
||||
buff_change: BuffChange::Add(Buff::new(
|
||||
BuffKind::Bleeding,
|
||||
BuffData {
|
||||
strength: attack.base_damage as f32 / 10.0,
|
||||
strength: -change.amount as f32 / 10.0,
|
||||
duration: Some(Duration::from_secs(10)),
|
||||
},
|
||||
vec![BuffCategory::Physical],
|
||||
@ -172,7 +149,8 @@ impl<'a> System<'a> for Sys {
|
||||
}
|
||||
attack.hit_count += 1;
|
||||
}
|
||||
if attack.knockback != 0.0 && damage.healthchange != 0.0 {
|
||||
|
||||
if attack.knockback != 0.0 && change.amount != 0 {
|
||||
let kb_dir = Dir::new((pos_b.0 - pos.0).try_normalized().unwrap_or(*ori.0));
|
||||
server_emitter.emit(ServerEvent::Knockback {
|
||||
entity: b,
|
||||
@ -183,7 +161,7 @@ impl<'a> System<'a> for Sys {
|
||||
}
|
||||
}
|
||||
}
|
||||
sys_metrics.combat_ns.store(
|
||||
sys_metrics.melee_ns.store(
|
||||
start_time.elapsed().as_nanos() as i64,
|
||||
std::sync::atomic::Ordering::Relaxed,
|
||||
);
|
@ -2,8 +2,8 @@ pub mod agent;
|
||||
mod beam;
|
||||
mod buff;
|
||||
pub mod character_behavior;
|
||||
pub mod combat;
|
||||
pub mod controller;
|
||||
pub mod melee;
|
||||
mod mount;
|
||||
pub mod phys;
|
||||
mod projectile;
|
||||
@ -15,7 +15,7 @@ use specs::DispatcherBuilder;
|
||||
|
||||
// System names
|
||||
pub const CHARACTER_BEHAVIOR_SYS: &str = "character_behavior_sys";
|
||||
pub const COMBAT_SYS: &str = "combat_sys";
|
||||
pub const MELEE_SYS: &str = "melee_sys";
|
||||
pub const AGENT_SYS: &str = "agent_sys";
|
||||
pub const BEAM_SYS: &str = "beam_sys";
|
||||
pub const CONTROLLER_SYS: &str = "controller_sys";
|
||||
@ -39,5 +39,5 @@ pub fn add_local_systems(dispatch_builder: &mut DispatcherBuilder) {
|
||||
dispatch_builder.add(projectile::Sys, PROJECTILE_SYS, &[PHYS_SYS]);
|
||||
dispatch_builder.add(shockwave::Sys, SHOCKWAVE_SYS, &[PHYS_SYS]);
|
||||
dispatch_builder.add(beam::Sys, BEAM_SYS, &[PHYS_SYS]);
|
||||
dispatch_builder.add(combat::Sys, COMBAT_SYS, &[PROJECTILE_SYS]);
|
||||
dispatch_builder.add(melee::Sys, MELEE_SYS, &[PROJECTILE_SYS]);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
comp::{
|
||||
projectile, Damage, DamageSource, Energy, EnergySource, Group, HealthChange, HealthSource,
|
||||
Loadout, Ori, PhysicsState, Pos, Projectile, Vel,
|
||||
projectile, Energy, EnergySource, Group, HealthSource, Loadout, Ori, PhysicsState, Pos,
|
||||
Projectile, Vel,
|
||||
},
|
||||
event::{EventBus, LocalEvent, ServerEvent},
|
||||
metrics::SysMetrics,
|
||||
@ -73,20 +73,21 @@ impl<'a> System<'a> for Sys {
|
||||
{
|
||||
// Hit entity
|
||||
for other in physics.touch_entities.iter().copied() {
|
||||
let same_group = projectile
|
||||
.owner
|
||||
// Note: somewhat inefficient since we do the lookup for every touching
|
||||
// entity, but if we pull this out of the loop we would want to do it only
|
||||
// if there is at least one touching entity
|
||||
.and_then(|uid| uid_allocator.retrieve_entity_internal(uid.into()))
|
||||
.and_then(|e| groups.get(e))
|
||||
.map_or(false, |owner_group|
|
||||
Some(owner_group) == uid_allocator
|
||||
.retrieve_entity_internal(other.into())
|
||||
.and_then(|e| groups.get(e))
|
||||
);
|
||||
if projectile.ignore_group
|
||||
// Skip if in the same group
|
||||
&& projectile
|
||||
.owner
|
||||
// Note: somewhat inefficient since we do the lookup for every touching
|
||||
// entity, but if we pull this out of the loop we would want to do it only
|
||||
// if there is at least one touching entity
|
||||
.and_then(|uid| uid_allocator.retrieve_entity_internal(uid.into()))
|
||||
.and_then(|e| groups.get(e))
|
||||
.map_or(false, |owner_group|
|
||||
Some(owner_group) == uid_allocator
|
||||
.retrieve_entity_internal(other.into())
|
||||
.and_then(|e| groups.get(e))
|
||||
)
|
||||
&& same_group
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -97,40 +98,25 @@ impl<'a> System<'a> for Sys {
|
||||
|
||||
for effect in projectile.hit_entity.drain(..) {
|
||||
match effect {
|
||||
projectile::Effect::Damage(healthchange) => {
|
||||
let owner_uid = projectile.owner.unwrap();
|
||||
let mut damage = Damage {
|
||||
healthchange: healthchange as f32,
|
||||
source: DamageSource::Projectile,
|
||||
};
|
||||
|
||||
let other_entity = uid_allocator.retrieve_entity_internal(other.into());
|
||||
if let Some(loadout) = other_entity.and_then(|e| loadouts.get(e)) {
|
||||
damage.modify_damage(false, loadout);
|
||||
projectile::Effect::Damages(damages) => {
|
||||
if Some(other) == projectile.owner {
|
||||
continue;
|
||||
}
|
||||
let damage = if !same_group && damages.enemy.is_some() {
|
||||
damages.enemy.unwrap()
|
||||
} else if same_group && damages.group.is_some() {
|
||||
damages.group.unwrap()
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
let other_entity_loadout = uid_allocator
|
||||
.retrieve_entity_internal(other.into())
|
||||
.and_then(|e| loadouts.get(e));
|
||||
let change =
|
||||
damage.modify_damage(false, other_entity_loadout, projectile.owner);
|
||||
|
||||
if other != owner_uid {
|
||||
if damage.healthchange < 0.0 {
|
||||
server_emitter.emit(ServerEvent::Damage {
|
||||
uid: other,
|
||||
change: HealthChange {
|
||||
amount: damage.healthchange as i32,
|
||||
cause: HealthSource::Projectile {
|
||||
owner: Some(owner_uid),
|
||||
},
|
||||
},
|
||||
});
|
||||
} else if damage.healthchange > 0.0 {
|
||||
server_emitter.emit(ServerEvent::Damage {
|
||||
uid: other,
|
||||
change: HealthChange {
|
||||
amount: damage.healthchange as i32,
|
||||
cause: HealthSource::Healing {
|
||||
by: Some(owner_uid),
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
if change.amount != 0 {
|
||||
server_emitter.emit(ServerEvent::Damage { uid: other, change });
|
||||
}
|
||||
},
|
||||
projectile::Effect::Knockback(knockback) => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
comp::{
|
||||
group, Body, CharacterState, Damage, DamageSource, HealthChange, HealthSource, Last,
|
||||
Loadout, Ori, PhysicsState, Pos, Scale, Shockwave, ShockwaveHitEntities, Stats,
|
||||
group, Body, CharacterState, HealthSource, Last, Loadout, Ori, PhysicsState, Pos, Scale,
|
||||
Shockwave, ShockwaveHitEntities, Stats,
|
||||
},
|
||||
event::{EventBus, LocalEvent, ServerEvent},
|
||||
state::{DeltaTime, Time},
|
||||
@ -189,42 +189,31 @@ impl<'a> System<'a> for Sys {
|
||||
})
|
||||
}
|
||||
&& (pos_b_ground - pos.0).angle_between(pos_b.0 - pos.0) < max_angle
|
||||
&& (!shockwave.requires_ground || physics_state_b.on_ground)
|
||||
&& !same_group;
|
||||
&& (!shockwave.requires_ground || physics_state_b.on_ground);
|
||||
|
||||
if hit {
|
||||
let mut damage = Damage {
|
||||
healthchange: -(shockwave.damage as f32),
|
||||
source: DamageSource::Shockwave,
|
||||
let damage = if !same_group && shockwave.damages.enemy.is_some() {
|
||||
shockwave.damages.enemy.unwrap()
|
||||
} else if same_group && shockwave.damages.group.is_some() {
|
||||
shockwave.damages.group.unwrap()
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let block = character_b.map(|c_b| c_b.is_block()).unwrap_or(false)
|
||||
&& ori_b.0.angle_between(pos.0 - pos_b.0) < BLOCK_ANGLE.to_radians() / 2.0;
|
||||
|
||||
if let Some(loadout) = loadouts.get(b) {
|
||||
damage.modify_damage(block, loadout);
|
||||
}
|
||||
let owner_uid = shockwave.owner.unwrap_or(*uid);
|
||||
let change = damage.modify_damage(block, loadouts.get(b), Some(owner_uid));
|
||||
|
||||
if damage.healthchange != 0.0 {
|
||||
let cause = if damage.healthchange < 0.0 {
|
||||
HealthSource::Attack {
|
||||
by: shockwave.owner.unwrap_or(*uid),
|
||||
}
|
||||
} else {
|
||||
HealthSource::Healing {
|
||||
by: Some(shockwave.owner.unwrap_or(*uid)),
|
||||
}
|
||||
};
|
||||
if change.amount != 0 {
|
||||
server_emitter.emit(ServerEvent::Damage {
|
||||
uid: *uid_b,
|
||||
change: HealthChange {
|
||||
amount: damage.healthchange as i32,
|
||||
cause,
|
||||
},
|
||||
change,
|
||||
});
|
||||
shockwave_hit_list.hit_entities.push(*uid_b);
|
||||
}
|
||||
if shockwave.knockback != 0.0 && damage.healthchange != 0.0 {
|
||||
if shockwave.knockback != 0.0 {
|
||||
let kb_dir = Dir::new((pos_b.0 - pos.0).try_normalized().unwrap_or(*ori.0));
|
||||
let impulse = if shockwave.knockback < 0.0 {
|
||||
shockwave.knockback
|
||||
|
@ -8,18 +8,17 @@ use common::{
|
||||
comp::{
|
||||
self, buff,
|
||||
chat::{KillSource, KillType},
|
||||
object, Alignment, Body, Damage, DamageSource, Group, HealthChange, HealthSource, Item,
|
||||
Player, Pos, Stats,
|
||||
object, Alignment, Body, Group, HealthChange, HealthSource, Item, Player, Pos, Stats,
|
||||
},
|
||||
lottery::Lottery,
|
||||
msg::{PlayerListUpdate, ServerGeneral},
|
||||
outcome::Outcome,
|
||||
state::BlockChange,
|
||||
sync::{Uid, UidAllocator, WorldSyncExt},
|
||||
sys::combat::BLOCK_ANGLE,
|
||||
sys::melee::BLOCK_ANGLE,
|
||||
terrain::{Block, TerrainGrid},
|
||||
vol::ReadVol,
|
||||
Explosion,
|
||||
Damage, Explosion,
|
||||
};
|
||||
use comp::item::Reagent;
|
||||
use rand::prelude::*;
|
||||
@ -456,17 +455,10 @@ pub fn handle_land_on_ground(server: &Server, entity: EcsEntity, vel: Vec3<f32>)
|
||||
if vel.z <= -30.0 {
|
||||
if let Some(stats) = state.ecs().write_storage::<comp::Stats>().get_mut(entity) {
|
||||
let falldmg = (vel.z.powi(2) / 20.0 - 40.0) * 10.0;
|
||||
let mut damage = Damage {
|
||||
healthchange: -falldmg,
|
||||
source: DamageSource::Falling,
|
||||
};
|
||||
if let Some(loadout) = state.ecs().read_storage::<comp::Loadout>().get(entity) {
|
||||
damage.modify_damage(false, loadout);
|
||||
}
|
||||
stats.health.change_by(comp::HealthChange {
|
||||
amount: damage.healthchange as i32,
|
||||
cause: comp::HealthSource::World,
|
||||
});
|
||||
let damage = Damage::Falling(falldmg);
|
||||
let loadouts = state.ecs().read_storage::<comp::Loadout>();
|
||||
let change = damage.modify_damage(false, loadouts.get(entity), None);
|
||||
stats.health.change_by(change);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -576,43 +568,26 @@ pub fn handle_explosion(
|
||||
continue;
|
||||
}
|
||||
|
||||
// Weapon gives base damage
|
||||
let source = if is_heal {
|
||||
DamageSource::Healing
|
||||
} else {
|
||||
DamageSource::Explosion
|
||||
};
|
||||
let strength = 1.0 - distance_squared / explosion.radius.powi(2);
|
||||
let healthchange = if is_heal {
|
||||
explosion.min_heal as f32
|
||||
+ (explosion.max_heal - explosion.min_heal) as f32 * strength
|
||||
let damage = if is_heal {
|
||||
Damage::Healing(
|
||||
explosion.min_heal as f32
|
||||
+ (explosion.max_heal - explosion.min_heal) as f32 * strength,
|
||||
)
|
||||
} else {
|
||||
-(explosion.min_damage as f32
|
||||
+ (explosion.max_damage - explosion.min_damage) as f32 * strength)
|
||||
};
|
||||
|
||||
let mut damage = Damage {
|
||||
healthchange,
|
||||
source,
|
||||
Damage::Explosion(
|
||||
explosion.min_damage as f32
|
||||
+ (explosion.max_damage - explosion.min_damage) as f32 * strength,
|
||||
)
|
||||
};
|
||||
|
||||
let block = character_b.map(|c_b| c_b.is_block()).unwrap_or(false)
|
||||
&& ori_b.0.angle_between(pos - pos_b.0) < BLOCK_ANGLE.to_radians() / 2.0;
|
||||
|
||||
if let Some(loadout) = loadout_b {
|
||||
damage.modify_damage(block, loadout);
|
||||
}
|
||||
let change = damage.modify_damage(block, loadout_b, owner);
|
||||
|
||||
if damage.healthchange != 0.0 {
|
||||
let cause = if is_heal {
|
||||
HealthSource::Healing { by: owner }
|
||||
} else {
|
||||
HealthSource::Explosion { owner }
|
||||
};
|
||||
stats_b.health.change_by(HealthChange {
|
||||
amount: damage.healthchange as i32,
|
||||
cause,
|
||||
});
|
||||
if change.amount != 0 {
|
||||
stats_b.health.change_by(change);
|
||||
if let Some(owner) = owner_entity {
|
||||
if let Some(energy) = ecs.write_storage::<comp::Energy>().get_mut(owner) {
|
||||
energy
|
||||
|
@ -717,7 +717,7 @@ impl Server {
|
||||
let stats_ns = res.stats_ns.load(Ordering::Relaxed);
|
||||
let phys_ns = res.phys_ns.load(Ordering::Relaxed);
|
||||
let projectile_ns = res.projectile_ns.load(Ordering::Relaxed);
|
||||
let combat_ns = res.combat_ns.load(Ordering::Relaxed);
|
||||
let melee_ns = res.melee_ns.load(Ordering::Relaxed);
|
||||
|
||||
c.with_label_values(&[common::sys::AGENT_SYS])
|
||||
.inc_by(agent_ns);
|
||||
@ -733,8 +733,8 @@ impl Server {
|
||||
.inc_by(phys_ns);
|
||||
c.with_label_values(&[common::sys::PROJECTILE_SYS])
|
||||
.inc_by(projectile_ns);
|
||||
c.with_label_values(&[common::sys::COMBAT_SYS])
|
||||
.inc_by(combat_ns);
|
||||
c.with_label_values(&[common::sys::MELEE_SYS])
|
||||
.inc_by(melee_ns);
|
||||
|
||||
const NANOSEC_PER_SEC: f64 = Duration::from_secs(1).as_nanos() as f64;
|
||||
let h = &self.state_tick_metrics.state_tick_time_hist;
|
||||
@ -752,8 +752,8 @@ impl Server {
|
||||
.observe(phys_ns as f64 / NANOSEC_PER_SEC);
|
||||
h.with_label_values(&[common::sys::PROJECTILE_SYS])
|
||||
.observe(projectile_ns as f64 / NANOSEC_PER_SEC);
|
||||
h.with_label_values(&[common::sys::COMBAT_SYS])
|
||||
.observe(combat_ns as f64 / NANOSEC_PER_SEC);
|
||||
h.with_label_values(&[common::sys::MELEE_SYS])
|
||||
.observe(melee_ns as f64 / NANOSEC_PER_SEC);
|
||||
}
|
||||
|
||||
// Report other info
|
||||
|
Loading…
Reference in New Issue
Block a user