mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
When buffs expire from duration, now only they expire rather than ending all buffs of the same type.
This commit is contained in:
parent
125de0b46e
commit
b8690473e4
@ -81,7 +81,9 @@ pub enum BuffChange {
|
||||
/// Adds this buff.
|
||||
Add(Buff),
|
||||
/// Removes all buffs with this ID.
|
||||
Remove(BuffId),
|
||||
RemoveById(BuffId),
|
||||
/// Removes buff of this index
|
||||
RemoveByIndex(Vec<usize>),
|
||||
}
|
||||
|
||||
/// Source of the de/buff
|
||||
@ -124,22 +126,6 @@ pub struct Buffs {
|
||||
}
|
||||
|
||||
impl Buffs {
|
||||
/// Adds a request for adding given `buff`.
|
||||
/*pub fn add_buff(&mut self, buff: Buff) {
|
||||
let change = BuffChange::Add(buff);
|
||||
self.changes.push(change);
|
||||
self.last_change = 0.0;
|
||||
}
|
||||
|
||||
/// Adds a request for removal of all buffs with given Id.
|
||||
/// TODO: Better removal, allowing to specify which ability to remove
|
||||
/// directly.
|
||||
pub fn remove_buff_by_id(&mut self, id: BuffId) {
|
||||
let change = BuffChange::Remove(id);
|
||||
self.changes.push(change);
|
||||
self.last_change = 0.0;
|
||||
}*/
|
||||
|
||||
/// This is a primitive check if a specific buff is present.
|
||||
/// (for purposes like blocking usage of abilities or something like this).
|
||||
pub fn has_buff_id(&self, id: &BuffId) -> bool { self.buffs.iter().any(|buff| buff.id == *id) }
|
||||
|
@ -108,7 +108,7 @@ pub enum ServerEvent {
|
||||
Chat(comp::UnresolvedChatMsg),
|
||||
Buff {
|
||||
uid: Uid,
|
||||
buff: comp::BuffChange,
|
||||
buff_change: comp::BuffChange,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
use crate::{
|
||||
comp::{BuffChange, BuffEffect, BuffId, Buffs, HealthChange, HealthSource, Stats},
|
||||
event::{EventBus, ServerEvent},
|
||||
state::DeltaTime,
|
||||
sync::Uid,
|
||||
};
|
||||
use specs::{Entities, Join, Read, System, WriteStorage};
|
||||
use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
|
||||
use std::time::Duration;
|
||||
|
||||
/// This system modifies entity stats, changing them using buffs
|
||||
@ -16,12 +18,15 @@ impl<'a> System<'a> for Sys {
|
||||
type SystemData = (
|
||||
Entities<'a>,
|
||||
Read<'a, DeltaTime>,
|
||||
Read<'a, EventBus<ServerEvent>>,
|
||||
ReadStorage<'a, Uid>,
|
||||
WriteStorage<'a, Stats>,
|
||||
WriteStorage<'a, Buffs>,
|
||||
);
|
||||
|
||||
fn run(&mut self, (entities, dt, mut stats, mut buffs): Self::SystemData) {
|
||||
for (entity, mut buffs) in (&entities, &mut buffs.restrict_mut()).join() {
|
||||
fn run(&mut self, (entities, dt, server_bus, uids, mut stats, mut buffs): Self::SystemData) {
|
||||
let mut server_emitter = server_bus.emitter();
|
||||
for (entity, uid, mut buffs) in (&entities, &uids, &mut buffs.restrict_mut()).join() {
|
||||
let buff_comp = buffs.get_mut_unchecked();
|
||||
let mut buff_indices_for_removal = Vec::new();
|
||||
// Tick all de/buffs on a Buffs component.
|
||||
@ -72,16 +77,21 @@ impl<'a> System<'a> for Sys {
|
||||
};
|
||||
}
|
||||
}
|
||||
server_emitter.emit(ServerEvent::Buff {
|
||||
uid: *uid,
|
||||
buff_change: BuffChange::RemoveByIndex(buff_indices_for_removal),
|
||||
});
|
||||
// Remove buffs that have expired.
|
||||
// Since buffs are added into this vec as it iterates up through the list, it
|
||||
// will be in order of increasing values. Therefore to avoid
|
||||
// removing the incorrect buff, removal will start from the greatest index
|
||||
// Since buffs are added into this vec as it iterates up through the
|
||||
// list, it will be in order of increasing values.
|
||||
// Therefore to avoid removing the incorrect buff,
|
||||
// removal will start from the greatest index
|
||||
// value, which is the last in this vec.
|
||||
while !buff_indices_for_removal.is_empty() {
|
||||
/*while !buff_indices_for_removal.is_empty() {
|
||||
if let Some(i) = buff_indices_for_removal.pop() {
|
||||
buff_comp.buffs.remove(i);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -154,14 +154,19 @@ impl<'a> System<'a> for Sys {
|
||||
// Test for server event of buff, remove before merging
|
||||
server_emitter.emit(ServerEvent::Buff {
|
||||
uid: *uid_b,
|
||||
buff: buff::BuffChange::Add(buff::Buff {
|
||||
buff_change: buff::BuffChange::Add(buff::Buff {
|
||||
id: buff::BuffId::Bleeding,
|
||||
cat_ids: vec![buff::BuffCategoryId::Physical],
|
||||
time: Some(Duration::from_millis(2000)),
|
||||
effects: vec![buff::BuffEffect::HealthChangeOverTime {
|
||||
rate: 10.0,
|
||||
accumulated: 0.0,
|
||||
}],
|
||||
effects: vec![
|
||||
buff::BuffEffect::HealthChangeOverTime {
|
||||
rate: 10.0,
|
||||
accumulated: 0.0,
|
||||
},
|
||||
buff::BuffEffect::NameChange {
|
||||
prefix: String::from("Injured "),
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
attack.hit_count += 1;
|
||||
|
@ -675,13 +675,14 @@ pub fn handle_level_up(server: &mut Server, entity: EcsEntity, new_level: u32) {
|
||||
));
|
||||
}
|
||||
|
||||
pub fn handle_buff(server: &mut Server, uid: Uid, buff: buff::BuffChange) {
|
||||
pub fn handle_buff(server: &mut Server, uid: Uid, buff_change: buff::BuffChange) {
|
||||
let ecs = &server.state.ecs();
|
||||
let mut buffs_all = ecs.write_storage::<comp::Buffs>();
|
||||
if let Some(entity) = ecs.entity_from_uid(uid.into()) {
|
||||
if let Some(buffs) = buffs_all.get_mut(entity) {
|
||||
let mut stats = ecs.write_storage::<comp::Stats>();
|
||||
match buff {
|
||||
let mut buff_indices_for_removal = Vec::new();
|
||||
match buff_change {
|
||||
buff::BuffChange::Add(new_buff) => {
|
||||
for effect in &new_buff.effects {
|
||||
match effect {
|
||||
@ -698,30 +699,35 @@ pub fn handle_buff(server: &mut Server, uid: Uid, buff: buff::BuffChange) {
|
||||
}
|
||||
buffs.buffs.push(new_buff.clone());
|
||||
},
|
||||
buff::BuffChange::Remove(id) => {
|
||||
buff::BuffChange::RemoveByIndex(indices) => {
|
||||
buff_indices_for_removal = indices;
|
||||
},
|
||||
buff::BuffChange::RemoveById(id) => {
|
||||
let some_predicate = |current_id: &buff::BuffId| *current_id == id;
|
||||
let mut i = 0;
|
||||
while i != buffs.buffs.len() {
|
||||
for i in 0..buffs.buffs.len() {
|
||||
if some_predicate(&mut buffs.buffs[i].id) {
|
||||
let buff = buffs.buffs.remove(i);
|
||||
for effect in &buff.effects {
|
||||
match effect {
|
||||
// Only remove an effect here if its effect was not continuously
|
||||
// applied
|
||||
buff::BuffEffect::NameChange { prefix } => {
|
||||
if let Some(stats) = stats.get_mut(entity) {
|
||||
stats.name = stats.name.replace(prefix, "");
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
} else {
|
||||
i += 1;
|
||||
buff_indices_for_removal.push(i);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
while !buff_indices_for_removal.is_empty() {
|
||||
if let Some(i) = buff_indices_for_removal.pop() {
|
||||
let buff = buffs.buffs.remove(i);
|
||||
for effect in &buff.effects {
|
||||
match effect {
|
||||
// Only remove an effect here if its effect was not continuously
|
||||
// applied
|
||||
buff::BuffEffect::NameChange { prefix } => {
|
||||
if let Some(stats) = stats.get_mut(entity) {
|
||||
stats.name = stats.name.replacen(prefix, "", 1);
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ impl Server {
|
||||
ServerEvent::Chat(msg) => {
|
||||
chat_messages.push(msg);
|
||||
},
|
||||
ServerEvent::Buff { uid, buff } => handle_buff(self, uid, buff),
|
||||
ServerEvent::Buff { uid, buff_change } => handle_buff(self, uid, buff_change),
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user