mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Extract buff executor into own function
This commit is contained in:
parent
7ea720b2ef
commit
54c48c7112
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user