From 099933bf2af30e425cb8c2ddf33e2c6ec4b1fd7e Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 30 Oct 2020 16:49:58 -0500 Subject: [PATCH] Added energy change server event. --- common/src/comp/energy.rs | 16 +++++++--- common/src/comp/mod.rs | 2 +- common/src/event.rs | 4 +++ common/src/states/basic_beam.rs | 12 ++++--- common/src/states/basic_melee.rs | 7 +++-- common/src/states/charged_melee.rs | 18 +++++------ common/src/states/charged_ranged.rs | 22 ++++++------- common/src/states/combo_melee.rs | 7 +++-- common/src/states/dash_melee.rs | 10 +++--- common/src/states/spin_melee.rs | 10 +++--- common/src/sys/beam.rs | 40 ++++++++++++++---------- common/src/sys/projectile.rs | 20 ++++++------ common/src/sys/stats.rs | 18 ++++++----- server/src/events/entity_manipulation.rs | 20 +++++++++--- server/src/events/mod.rs | 7 +++-- 15 files changed, 127 insertions(+), 86 deletions(-) diff --git a/common/src/comp/energy.rs b/common/src/comp/energy.rs index 55f7017f16..ff03c46a47 100644 --- a/common/src/comp/energy.rs +++ b/common/src/comp/energy.rs @@ -47,9 +47,9 @@ impl Energy { self.current = amount; } - pub fn change_by(&mut self, amount: i32, cause: EnergySource) { - self.current = ((self.current as i32 + amount).max(0) as u32).min(self.maximum); - self.last_change = Some((amount, 0.0, cause)); + pub fn change_by(&mut self, change: EnergyChange) { + self.current = ((self.current as i32 + change.amount).max(0) as u32).min(self.maximum); + self.last_change = Some((change.amount, 0.0, change.source)); } pub fn try_change_by( @@ -62,7 +62,10 @@ impl Energy { } else if self.current as i32 + amount > self.maximum as i32 { Err(StatChangeError::Overflow) } else { - self.change_by(amount, cause); + self.change_by(EnergyChange { + amount, + source: cause, + }); Ok(()) } } @@ -73,6 +76,11 @@ impl Energy { } } +pub struct EnergyChange { + pub amount: i32, + pub source: EnergySource, +} + impl Component for Energy { type Storage = FlaggedStorage>; } diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs index f2016bcb88..621ac92c23 100644 --- a/common/src/comp/mod.rs +++ b/common/src/comp/mod.rs @@ -43,7 +43,7 @@ pub use controller::{ Climb, ControlAction, ControlEvent, Controller, ControllerInputs, GroupManip, Input, InventoryManip, MountState, Mounting, }; -pub use energy::{Energy, EnergySource}; +pub use energy::{Energy, EnergyChange, EnergySource}; pub use group::Group; pub use inputs::CanBuild; pub use inventory::{ diff --git a/common/src/event.rs b/common/src/event.rs index 9dc0d725de..cd1d8aac12 100644 --- a/common/src/event.rs +++ b/common/src/event.rs @@ -109,6 +109,10 @@ pub enum ServerEvent { entity: EcsEntity, buff_change: comp::BuffChange, }, + EnergyChange { + uid: Uid, + change: comp::EnergyChange, + }, } pub struct EventBus { diff --git a/common/src/states/basic_beam.rs b/common/src/states/basic_beam.rs index 12ff5fd381..579777b980 100644 --- a/common/src/states/basic_beam.rs +++ b/common/src/states/basic_beam.rs @@ -1,5 +1,7 @@ use crate::{ - comp::{beam, humanoid, Body, CharacterState, EnergySource, Ori, Pos, StateUpdate}, + comp::{ + beam, humanoid, Body, CharacterState, EnergyChange, EnergySource, Ori, Pos, StateUpdate, + }, event::ServerEvent, states::utils::*, sync::Uid, @@ -148,10 +150,10 @@ impl CharacterBehavior for Data { }); // Consumes energy if there's enough left and ability key is held down - update.energy.change_by( - -(self.static_data.energy_drain as f32 * data.dt.0) as i32, - EnergySource::Ability, - ); + update.energy.change_by(EnergyChange { + amount: -(self.static_data.energy_drain as f32 * data.dt.0) as i32, + source: EnergySource::Ability, + }); } else { update.character = CharacterState::BasicBeam(Data { timer: Duration::default(), diff --git a/common/src/states/basic_melee.rs b/common/src/states/basic_melee.rs index ca4e002cdd..e6f0b05a11 100644 --- a/common/src/states/basic_melee.rs +++ b/common/src/states/basic_melee.rs @@ -1,5 +1,5 @@ use crate::{ - comp::{Attacking, CharacterState, EnergySource, StateUpdate}, + comp::{Attacking, CharacterState, EnergyChange, EnergySource, StateUpdate}, states::utils::*, sys::character_behavior::{CharacterBehavior, JoinData}, Damage, DamageSource, Damages, Knockback, @@ -136,7 +136,10 @@ impl CharacterBehavior for Data { if let Some(attack) = data.attacking { if attack.applied && attack.hit_count > 0 { data.updater.remove::(data.entity); - update.energy.change_by(50, EnergySource::HitEnemy); + update.energy.change_by(EnergyChange { + amount: 50, + source: EnergySource::HitEnemy, + }); } } diff --git a/common/src/states/charged_melee.rs b/common/src/states/charged_melee.rs index deec9de03c..ab85f0fa18 100644 --- a/common/src/states/charged_melee.rs +++ b/common/src/states/charged_melee.rs @@ -1,5 +1,5 @@ use crate::{ - comp::{Attacking, CharacterState, EnergySource, StateUpdate}, + comp::{Attacking, CharacterState, EnergyChange, EnergySource, StateUpdate}, states::utils::{StageSection, *}, sys::character_behavior::*, Damage, DamageSource, Damages, Knockback, @@ -77,10 +77,10 @@ impl CharacterBehavior for Data { }); // Consumes energy if there's enough left and RMB is held down - update.energy.change_by( - -(self.static_data.energy_drain as f32 * data.dt.0) as i32, - EnergySource::Ability, - ); + update.energy.change_by(EnergyChange { + amount: -(self.static_data.energy_drain as f32 * data.dt.0) as i32, + source: EnergySource::Ability, + }); } else if data.inputs.secondary.is_pressed() && update.energy.current() >= self.static_data.energy_cost { @@ -94,10 +94,10 @@ impl CharacterBehavior for Data { }); // Consumes energy if there's enough left and RMB is held down - update.energy.change_by( - -(self.static_data.energy_drain as f32 * data.dt.0 / 5.0) as i32, - EnergySource::Ability, - ); + update.energy.change_by(EnergyChange { + amount: -(self.static_data.energy_drain as f32 * data.dt.0 / 5.0) as i32, + source: EnergySource::Ability, + }); } else { // Transitions to swing update.character = CharacterState::ChargedMelee(Data { diff --git a/common/src/states/charged_ranged.rs b/common/src/states/charged_ranged.rs index e6141cfe44..58ad57b272 100644 --- a/common/src/states/charged_ranged.rs +++ b/common/src/states/charged_ranged.rs @@ -1,8 +1,8 @@ use crate::{ comp::{ buff::{Buff, BuffCategory, BuffData, BuffKind, BuffSource}, - projectile, Body, CharacterState, EnergySource, Gravity, LightEmitter, Projectile, - StateUpdate, + projectile, Body, CharacterState, EnergyChange, EnergySource, Gravity, LightEmitter, + Projectile, StateUpdate, }, event::ServerEvent, states::utils::*, @@ -104,7 +104,7 @@ impl CharacterBehavior for Data { buff: Buff::new( BuffKind::Bleeding, BuffData { - strength: damage / 5.0, + strength: damage.value / 5.0, duration: Some(Duration::from_secs(5)), }, vec![BuffCategory::Physical], @@ -150,10 +150,10 @@ impl CharacterBehavior for Data { }); // Consumes energy if there's enough left and RMB is held down - update.energy.change_by( - -(self.static_data.energy_drain as f32 * data.dt.0) as i32, - EnergySource::Ability, - ); + update.energy.change_by(EnergyChange { + amount: -(self.static_data.energy_drain as f32 * data.dt.0) as i32, + source: EnergySource::Ability, + }); } else if data.inputs.secondary.is_pressed() { // Holds charge update.character = CharacterState::ChargedRanged(Data { @@ -165,10 +165,10 @@ impl CharacterBehavior for Data { }); // Consumes energy if there's enough left and RMB is held down - update.energy.change_by( - -(self.static_data.energy_drain as f32 * data.dt.0 / 5.0) as i32, - EnergySource::Ability, - ); + update.energy.change_by(EnergyChange { + amount: -(self.static_data.energy_drain as f32 * data.dt.0 / 5.0) as i32, + source: EnergySource::Ability, + }); } }, StageSection::Recover => { diff --git a/common/src/states/combo_melee.rs b/common/src/states/combo_melee.rs index 4fe358c1b4..d359b8d9ce 100644 --- a/common/src/states/combo_melee.rs +++ b/common/src/states/combo_melee.rs @@ -1,5 +1,5 @@ use crate::{ - comp::{Attacking, CharacterState, EnergySource, StateUpdate}, + comp::{Attacking, CharacterState, EnergyChange, EnergySource, StateUpdate}, states::utils::*, sys::character_behavior::{CharacterBehavior, JoinData}, Damage, DamageSource, Damages, Knockback, @@ -261,7 +261,10 @@ impl CharacterBehavior for Data { next_stage: self.next_stage, }); data.updater.remove::(data.entity); - update.energy.change_by(energy, EnergySource::HitEnemy); + update.energy.change_by(EnergyChange { + amount: energy, + source: EnergySource::HitEnemy, + }); } } diff --git a/common/src/states/dash_melee.rs b/common/src/states/dash_melee.rs index 3da10c386c..6957ee10d2 100644 --- a/common/src/states/dash_melee.rs +++ b/common/src/states/dash_melee.rs @@ -1,5 +1,5 @@ use crate::{ - comp::{Attacking, CharacterState, EnergySource, StateUpdate}, + comp::{Attacking, CharacterState, EnergyChange, EnergySource, StateUpdate}, states::utils::*, sys::character_behavior::{CharacterBehavior, JoinData}, Damage, DamageSource, Damages, Knockback, @@ -176,10 +176,10 @@ impl CharacterBehavior for Data { } // Consumes energy if there's enough left and charge has not stopped - update.energy.change_by( - -(self.static_data.energy_drain as f32 * data.dt.0) as i32, - EnergySource::Ability, - ); + update.energy.change_by(EnergyChange { + amount: -(self.static_data.energy_drain as f32 * data.dt.0) as i32, + source: EnergySource::Ability, + }); } else { // Transitions to swing section of stage update.character = CharacterState::DashMelee(Data { diff --git a/common/src/states/spin_melee.rs b/common/src/states/spin_melee.rs index 746e2bf58a..ffceb6fb03 100644 --- a/common/src/states/spin_melee.rs +++ b/common/src/states/spin_melee.rs @@ -1,5 +1,5 @@ use crate::{ - comp::{Attacking, CharacterState, EnergySource, StateUpdate}, + comp::{Attacking, CharacterState, EnergyChange, EnergySource, StateUpdate}, states::utils::*, sys::{ character_behavior::{CharacterBehavior, JoinData}, @@ -154,10 +154,10 @@ impl CharacterBehavior for Data { ..*self }); // Consumes energy if there's enough left and RMB is held down - update.energy.change_by( - -(self.static_data.energy_cost as i32), - EnergySource::Ability, - ); + update.energy.change_by(EnergyChange { + amount: -(self.static_data.energy_cost as i32), + source: EnergySource::Ability, + }); } else { // Transitions to recover section of stage update.character = CharacterState::SpinMelee(Data { diff --git a/common/src/sys/beam.rs b/common/src/sys/beam.rs index 3cf769a9a5..143179a131 100644 --- a/common/src/sys/beam.rs +++ b/common/src/sys/beam.rs @@ -1,7 +1,7 @@ use crate::{ comp::{ - group, Beam, BeamSegment, Body, CharacterState, Energy, EnergySource, HealthChange, - HealthSource, Last, Loadout, Ori, Pos, Scale, Stats, + group, Beam, BeamSegment, Body, CharacterState, Energy, EnergyChange, EnergySource, + HealthChange, HealthSource, Last, Loadout, Ori, Pos, Scale, Stats, }, event::{EventBus, ServerEvent}, state::{DeltaTime, Time}, @@ -34,7 +34,7 @@ impl<'a> System<'a> for Sys { ReadStorage<'a, Loadout>, ReadStorage<'a, group::Group>, ReadStorage<'a, CharacterState>, - WriteStorage<'a, Energy>, + ReadStorage<'a, Energy>, WriteStorage<'a, BeamSegment>, WriteStorage<'a, Beam>, ); @@ -57,7 +57,7 @@ impl<'a> System<'a> for Sys { loadouts, groups, character_states, - mut energies, + energies, mut beam_segments, mut beams, ): Self::SystemData, @@ -197,20 +197,26 @@ impl<'a> System<'a> for Sys { }, }); } - if let Some(energy_mut) = beam_owner.and_then(|o| energies.get_mut(o)) { - energy_mut.change_by( - beam_segment.energy_regen as i32, - EnergySource::HitEnemy, - ); + if let Some(uid) = beam_segment.owner { + server_emitter.emit(ServerEvent::EnergyChange { + uid, + change: EnergyChange { + amount: beam_segment.energy_regen as i32, + source: EnergySource::HitEnemy, + }, + }); } - } else if let Some(energy_mut) = beam_owner.and_then(|o| energies.get_mut(o)) { - if energy_mut - .try_change_by( - -(beam_segment.energy_cost as i32), // Stamina use - EnergySource::Ability, - ) - .is_ok() - { + } else if let Some(energy) = beam_owner.and_then(|o| energies.get(o)) { + if energy.current() > beam_segment.energy_cost { + if let Some(uid) = beam_segment.owner { + server_emitter.emit(ServerEvent::EnergyChange { + uid, + change: EnergyChange { + amount: -(beam_segment.energy_cost as i32), // Stamina use + source: EnergySource::Ability, + }, + }) + } server_emitter.emit(ServerEvent::Damage { uid: *uid_b, change, diff --git a/common/src/sys/projectile.rs b/common/src/sys/projectile.rs index a8dce0663e..5959a6ce2f 100644 --- a/common/src/sys/projectile.rs +++ b/common/src/sys/projectile.rs @@ -1,8 +1,8 @@ use crate::{ comp::{ buff::{BuffChange, BuffSource}, - projectile, Energy, EnergySource, Group, HealthSource, Loadout, Ori, PhysicsState, Pos, - Projectile, Vel, + projectile, EnergyChange, EnergySource, Group, HealthSource, Loadout, Ori, PhysicsState, + Pos, Projectile, Vel, }, event::{EventBus, LocalEvent, ServerEvent}, metrics::SysMetrics, @@ -32,7 +32,6 @@ impl<'a> System<'a> for Sys { ReadStorage<'a, Vel>, WriteStorage<'a, Ori>, WriteStorage<'a, Projectile>, - WriteStorage<'a, Energy>, ReadStorage<'a, Loadout>, ReadStorage<'a, Group>, ); @@ -51,7 +50,6 @@ impl<'a> System<'a> for Sys { velocities, mut orientations, mut projectiles, - mut energies, loadouts, groups, ): Self::SystemData, @@ -129,12 +127,14 @@ impl<'a> System<'a> for Sys { } }, projectile::Effect::RewardEnergy(energy) => { - if let Some(energy_mut) = projectile - .owner - .and_then(|o| uid_allocator.retrieve_entity_internal(o.into())) - .and_then(|o| energies.get_mut(o)) - { - energy_mut.change_by(energy as i32, EnergySource::HitEnemy); + if let Some(uid) = projectile.owner { + server_emitter.emit(ServerEvent::EnergyChange { + uid, + change: EnergyChange { + amount: energy as i32, + source: EnergySource::HitEnemy, + }, + }); } }, projectile::Effect::Explode(e) => { diff --git a/common/src/sys/stats.rs b/common/src/sys/stats.rs index 723904aa4a..bf05054cb6 100644 --- a/common/src/sys/stats.rs +++ b/common/src/sys/stats.rs @@ -1,5 +1,5 @@ use crate::{ - comp::{CharacterState, Energy, EnergySource, HealthSource, Stats}, + comp::{CharacterState, Energy, EnergyChange, EnergySource, HealthSource, Stats}, event::{EventBus, ServerEvent}, metrics::SysMetrics, span, @@ -96,11 +96,12 @@ impl<'a> System<'a> for Sys { if res { let mut energy = energy.get_mut_unchecked(); // Have to account for Calc I differential equations due to acceleration - energy.change_by( - (energy.regen_rate * dt.0 + ENERGY_REGEN_ACCEL * dt.0.powf(2.0) / 2.0) + energy.change_by(EnergyChange { + amount: (energy.regen_rate * dt.0 + + ENERGY_REGEN_ACCEL * dt.0.powf(2.0) / 2.0) as i32, - EnergySource::Regen, - ); + source: EnergySource::Regen, + }); energy.regen_rate = (energy.regen_rate + ENERGY_REGEN_ACCEL * dt.0).min(100.0); } @@ -130,9 +131,10 @@ impl<'a> System<'a> for Sys { }; if res { - energy - .get_mut_unchecked() - .change_by(-3, EnergySource::Regen); + energy.get_mut_unchecked().change_by(EnergyChange { + amount: -3, + source: EnergySource::Regen, + }); } }, // Non-combat abilities that consume energy; diff --git a/server/src/events/entity_manipulation.rs b/server/src/events/entity_manipulation.rs index 5c6c8d0ab9..2f0e36269e 100644 --- a/server/src/events/entity_manipulation.rs +++ b/server/src/events/entity_manipulation.rs @@ -8,7 +8,8 @@ use common::{ comp::{ self, buff, chat::{KillSource, KillType}, - object, Alignment, Body, Group, HealthChange, HealthSource, Item, Player, Pos, Stats, + object, Alignment, Body, Energy, EnergyChange, Group, HealthChange, HealthSource, Item, + Player, Pos, Stats, }, lottery::Lottery, msg::{PlayerListUpdate, ServerGeneral}, @@ -596,10 +597,10 @@ pub fn handle_explosion( if let Some(energy) = ecs.write_storage::().get_mut(owner) { - energy.change_by( - explosion.energy_regen as i32, - comp::EnergySource::HitEnemy, - ); + energy.change_by(EnergyChange { + amount: explosion.energy_regen as i32, + source: comp::EnergySource::HitEnemy, + }); } } } @@ -748,3 +749,12 @@ pub fn handle_buff(server: &mut Server, entity: EcsEntity, buff_change: buff::Bu } } } + +pub fn handle_energy_change(server: &Server, uid: Uid, change: EnergyChange) { + let ecs = &server.state.ecs(); + if let Some(entity) = ecs.entity_from_uid(uid.into()) { + if let Some(energy) = ecs.write_storage::().get_mut(entity) { + energy.change_by(change); + } + } +} diff --git a/server/src/events/mod.rs b/server/src/events/mod.rs index 9a9f8cd6ba..358363c4a5 100644 --- a/server/src/events/mod.rs +++ b/server/src/events/mod.rs @@ -8,8 +8,8 @@ use entity_creation::{ handle_loaded_character_data, handle_shockwave, handle_shoot, }; use entity_manipulation::{ - handle_buff, handle_damage, handle_destroy, handle_explosion, handle_knockback, - handle_land_on_ground, handle_level_up, handle_respawn, + handle_buff, handle_damage, handle_destroy, handle_energy_change, handle_explosion, + handle_knockback, handle_land_on_ground, handle_level_up, handle_respawn, }; use group_manip::handle_group; use interaction::{handle_lantern, handle_mount, handle_possess, handle_unmount}; @@ -136,6 +136,9 @@ impl Server { entity, buff_change, } => handle_buff(self, entity, buff_change), + ServerEvent::EnergyChange { uid, change } => { + handle_energy_change(&self, uid, change) + }, } }