Extract buff executor into own function

This commit is contained in:
juliancoffee 2022-09-05 15:48:23 +03:00
parent 7ea720b2ef
commit 54c48c7112

View File

@ -11,10 +11,10 @@ use common::{
Energy, Group, Health, HealthChange, Inventory, LightEmitter, ModifierKind, PhysicsState,
Stats,
},
event::{EventBus, ServerEvent},
event::{Emitter, EventBus, ServerEvent},
resources::{DeltaTime, Time},
terrain::SpriteKind,
uid::UidAllocator,
uid::{Uid, UidAllocator},
Damage, DamageSource,
};
use common_base::prof_span;
@ -22,8 +22,8 @@ use common_ecs::{Job, Origin, ParMode, Phase, System};
use hashbrown::HashMap;
use rayon::iter::ParallelIterator;
use specs::{
saveload::MarkerAllocator, shred::ResourceId, Entities, Join, ParJoin, Read, ReadExpect,
ReadStorage, SystemData, World, WriteStorage,
saveload::MarkerAllocator, shred::ResourceId, Entities, Entity, Join, ParJoin, Read,
ReadExpect, ReadStorage, SystemData, World, WriteStorage,
};
use std::time::Duration;
@ -257,6 +257,62 @@ impl<'a> System<'a> for Sys {
// Now, execute the buff, based on it's delta
for effect in &mut buff.effects {
execute_effect(
effect,
buff.kind,
buff.time,
&read_data,
&mut *stat,
health,
energy,
entity,
buff_owner,
&mut server_emitter,
dt,
);
}
}
}
// Remove buffs that expire
if !expired_buffs.is_empty() {
server_emitter.emit(ServerEvent::Buff {
entity,
buff_change: BuffChange::RemoveById(expired_buffs),
});
}
// Remove buffs that don't persist on death
if health.is_dead {
server_emitter.emit(ServerEvent::Buff {
entity,
buff_change: BuffChange::RemoveByCategory {
all_required: vec![],
any_required: vec![],
none_required: vec![BuffCategory::PersistOnDeath],
},
});
}
}
// Turned back to true
buffs.set_event_emission(true);
stats.set_event_emission(true);
}
}
fn execute_effect(
effect: &mut BuffEffect,
buff_kind: BuffKind,
buff_time: Option<std::time::Duration>,
read_data: &ReadData,
stat: &mut Stats,
health: &Health,
energy: &Energy,
entity: Entity,
buff_owner: Option<Uid>,
server_emitter: &mut Emitter<ServerEvent>,
dt: f32,
) {
match effect {
BuffEffect::HealthChangeOverTime {
rate,
@ -268,10 +324,10 @@ impl<'a> System<'a> for Sys {
// Apply health change only once per second, per health, or
// when a buff is removed
if accumulated.abs() > rate.abs().min(1.0)
|| buff.time.map_or(false, |dur| dur == Duration::default())
|| buff_time.map_or(false, |dur| dur == Duration::default())
{
let (cause, by) = if *accumulated != 0.0 {
(Some(DamageSource::Buff(buff.kind)), buff_owner)
(Some(DamageSource::Buff(buff_kind)), buff_owner)
} else {
(None, None)
};
@ -280,14 +336,12 @@ impl<'a> System<'a> for Sys {
ModifierKind::Fractional => health.maximum() * *accumulated,
};
let damage_contributor = by.and_then(|uid| {
read_data.uid_allocator.retrieve_entity_internal(uid.0).map(
|entity| {
DamageContributor::new(
uid,
read_data.groups.get(entity).cloned(),
)
},
)
read_data
.uid_allocator
.retrieve_entity_internal(uid.0)
.map(|entity| {
DamageContributor::new(uid, read_data.groups.get(entity).cloned())
})
});
server_emitter.emit(ServerEvent::HealthChange {
entity,
@ -312,13 +366,11 @@ impl<'a> System<'a> for Sys {
// Apply energy change only once per second, per energy, or
// when a buff is removed
if accumulated.abs() > rate.abs().min(10.0)
|| buff.time.map_or(false, |dur| dur == Duration::default())
|| buff_time.map_or(false, |dur| dur == Duration::default())
{
let amount = match *kind {
ModifierKind::Additive => *accumulated,
ModifierKind::Fractional => {
energy.maximum() as f32 * *accumulated
},
ModifierKind::Fractional => energy.maximum() as f32 * *accumulated,
};
server_emitter.emit(ServerEvent::EnergyChange {
entity,
@ -382,8 +434,7 @@ impl<'a> System<'a> for Sys {
// Potential progress towards target fraction, if
// target_fraction ~ 1.0 then set progress to 1.0 to avoid
// divide by zero
let progress = if (1.0 - *target_fraction).abs() > f32::EPSILON
{
let progress = if (1.0 - *target_fraction).abs() > f32::EPSILON {
(1.0 - potential_fraction) / (1.0 - *target_fraction)
} else {
1.0
@ -417,34 +468,6 @@ impl<'a> System<'a> for Sys {
},
};
}
}
}
// Remove buffs that expire
if !expired_buffs.is_empty() {
server_emitter.emit(ServerEvent::Buff {
entity,
buff_change: BuffChange::RemoveById(expired_buffs),
});
}
// Remove buffs that don't persist on death
if health.is_dead {
server_emitter.emit(ServerEvent::Buff {
entity,
buff_change: BuffChange::RemoveByCategory {
all_required: vec![],
any_required: vec![],
none_required: vec![BuffCategory::PersistOnDeath],
},
});
}
}
// Turned back to true
buffs.set_event_emission(true);
stats.set_event_emission(true);
}
}
fn tick_buff(id: u64, buff: &mut Buff, dt: f32, mut expire_buff: impl FnMut(u64)) {
// If a buff is recently applied from an aura, do not tick duration