Added energy change server event.

This commit is contained in:
Sam 2020-10-30 16:49:58 -05:00
parent e0cbbf52ed
commit f1f5c2b21b
15 changed files with 127 additions and 86 deletions

View File

@ -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<Self, IdvStorage<Self>>;
}

View File

@ -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::{

View File

@ -109,6 +109,10 @@ pub enum ServerEvent {
entity: EcsEntity,
buff_change: comp::BuffChange,
},
EnergyChange {
uid: Uid,
change: comp::EnergyChange,
},
}
pub struct EventBus<E> {

View File

@ -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(),

View File

@ -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::<Attacking>(data.entity);
update.energy.change_by(50, EnergySource::HitEnemy);
update.energy.change_by(EnergyChange {
amount: 50,
source: EnergySource::HitEnemy,
});
}
}

View File

@ -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 {

View File

@ -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 => {

View File

@ -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::<Attacking>(data.entity);
update.energy.change_by(energy, EnergySource::HitEnemy);
update.energy.change_by(EnergyChange {
amount: energy,
source: EnergySource::HitEnemy,
});
}
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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,

View File

@ -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) => {

View File

@ -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;

View File

@ -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::<comp::Energy>().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::<Energy>().get_mut(entity) {
energy.change_by(change);
}
}
}

View File

@ -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)
},
}
}