mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added functionality for buffs queueing. Saturation now queues.
This commit is contained in:
parent
f5a74b4f33
commit
f24490dc80
@ -31,7 +31,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Basic NPC interaction
|
||||
- Lights in dungeons
|
||||
- Trading system (bound to the `R` key by default, currently only works with players)
|
||||
- Support for dual wielding (not accessible as animations still needed)
|
||||
- Support for modular weapons.
|
||||
- Saturation buff (healing from food) now queues
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -29,19 +29,22 @@ pub enum BuffKind {
|
||||
}
|
||||
|
||||
impl BuffKind {
|
||||
// Checks if buff is buff or debuff
|
||||
/// Checks if buff is buff or debuff
|
||||
pub fn is_buff(self) -> bool {
|
||||
match self {
|
||||
BuffKind::Regeneration { .. } => true,
|
||||
BuffKind::Saturation { .. } => true,
|
||||
BuffKind::Bleeding { .. } => false,
|
||||
BuffKind::Cursed { .. } => false,
|
||||
BuffKind::Potion { .. } => true,
|
||||
BuffKind::CampfireHeal { .. } => true,
|
||||
BuffKind::IncreaseMaxEnergy { .. } => true,
|
||||
BuffKind::IncreaseMaxHealth { .. } => true,
|
||||
BuffKind::Regeneration => true,
|
||||
BuffKind::Saturation => true,
|
||||
BuffKind::Bleeding => false,
|
||||
BuffKind::Cursed => false,
|
||||
BuffKind::Potion => true,
|
||||
BuffKind::CampfireHeal => true,
|
||||
BuffKind::IncreaseMaxEnergy => true,
|
||||
BuffKind::IncreaseMaxHealth => true,
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if buff should queue
|
||||
pub fn queues(self) -> bool { matches!(self, BuffKind::Saturation) }
|
||||
}
|
||||
|
||||
// Struct used to store data relevant to a buff
|
||||
@ -321,7 +324,6 @@ impl Buffs {
|
||||
|
||||
// Gets most powerful buff of a given kind
|
||||
// pub fn get_active_kind(&self, kind: BuffKind) -> Buff
|
||||
|
||||
pub fn remove(&mut self, buff_id: BuffId) {
|
||||
let kind = self.buffs.remove(&buff_id).unwrap().kind;
|
||||
self.kinds
|
||||
@ -329,6 +331,12 @@ impl Buffs {
|
||||
.map(|ids| ids.retain(|id| *id != buff_id));
|
||||
self.sort_kind(kind);
|
||||
}
|
||||
|
||||
/// Returns an immutable reference to the buff kinds on an entity, and a
|
||||
/// mutable reference to the buffs
|
||||
pub fn parts(&mut self) -> (&HashMap<BuffKind, Vec<BuffId>>, &mut HashMap<BuffId, Buff>) {
|
||||
(&self.kinds, &mut self.buffs)
|
||||
}
|
||||
}
|
||||
|
||||
pub type BuffId = u64;
|
||||
|
@ -1,6 +1,6 @@
|
||||
use common::{
|
||||
comp::{
|
||||
BuffCategory, BuffChange, BuffEffect, BuffId, BuffSource, Buffs, Energy, Health,
|
||||
Buff, BuffCategory, BuffChange, BuffEffect, BuffId, BuffSource, Buffs, Energy, Health,
|
||||
HealthChange, HealthSource, Inventory, ModifierKind,
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
@ -35,22 +35,24 @@ impl<'a> System<'a> for Sys {
|
||||
for (entity, mut buff_comp, mut health, mut energy) in
|
||||
(&entities, &mut buffs, &mut healths, &mut energies).join()
|
||||
{
|
||||
let (buff_comp_kinds, buff_comp_buffs) = buff_comp.parts();
|
||||
let mut expired_buffs = Vec::<BuffId>::new();
|
||||
for (id, buff) in buff_comp.buffs.iter_mut() {
|
||||
// Tick the buff and subtract delta from it
|
||||
if let Some(remaining_time) = &mut buff.time {
|
||||
if let Some(new_duration) =
|
||||
remaining_time.checked_sub(Duration::from_secs_f32(dt.0))
|
||||
// For each buff kind present on entity, if the buff kind queues, only ticks
|
||||
// duration of strongest buff of that kind, else it ticks durations of all buffs
|
||||
// of that kind. Any buffs whose durations expire are marked expired.
|
||||
for (kind, ids) in buff_comp_kinds.iter() {
|
||||
if kind.queues() {
|
||||
if let Some((Some(buff), id)) =
|
||||
ids.get(0).map(|id| (buff_comp_buffs.get_mut(id), id))
|
||||
{
|
||||
// The buff still continues.
|
||||
*remaining_time = new_duration;
|
||||
} else {
|
||||
// checked_sub returns None when remaining time
|
||||
// went below 0, so set to 0
|
||||
*remaining_time = Duration::default();
|
||||
// The buff has expired.
|
||||
// Remove it.
|
||||
expired_buffs.push(*id);
|
||||
tick_buff(*id, buff, dt.0, |id| expired_buffs.push(id));
|
||||
}
|
||||
} else {
|
||||
for (id, buff) in buff_comp_buffs
|
||||
.iter_mut()
|
||||
.filter(|(i, _)| ids.iter().any(|id| id == *i))
|
||||
{
|
||||
tick_buff(*id, buff, dt.0, |id| expired_buffs.push(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -172,3 +174,19 @@ impl<'a> System<'a> for Sys {
|
||||
energies.set_event_emission(true);
|
||||
}
|
||||
}
|
||||
|
||||
fn tick_buff(id: u64, buff: &mut Buff, dt: f32, mut expire_buff: impl FnMut(u64)) {
|
||||
if let Some(remaining_time) = &mut buff.time {
|
||||
if let Some(new_duration) = remaining_time.checked_sub(Duration::from_secs_f32(dt)) {
|
||||
// The buff still continues.
|
||||
*remaining_time = new_duration;
|
||||
} else {
|
||||
// checked_sub returns None when remaining time
|
||||
// went below 0, so set to 0
|
||||
*remaining_time = Duration::default();
|
||||
// The buff has expired.
|
||||
// Remove it.
|
||||
expire_buff(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user