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:
@ -81,7 +81,9 @@ pub enum BuffChange {
|
|||||||
/// Adds this buff.
|
/// Adds this buff.
|
||||||
Add(Buff),
|
Add(Buff),
|
||||||
/// Removes all buffs with this ID.
|
/// Removes all buffs with this ID.
|
||||||
Remove(BuffId),
|
RemoveById(BuffId),
|
||||||
|
/// Removes buff of this index
|
||||||
|
RemoveByIndex(Vec<usize>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Source of the de/buff
|
/// Source of the de/buff
|
||||||
@ -124,22 +126,6 @@ pub struct Buffs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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.
|
/// This is a primitive check if a specific buff is present.
|
||||||
/// (for purposes like blocking usage of abilities or something like this).
|
/// (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) }
|
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),
|
Chat(comp::UnresolvedChatMsg),
|
||||||
Buff {
|
Buff {
|
||||||
uid: Uid,
|
uid: Uid,
|
||||||
buff: comp::BuffChange,
|
buff_change: comp::BuffChange,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{BuffChange, BuffEffect, BuffId, Buffs, HealthChange, HealthSource, Stats},
|
comp::{BuffChange, BuffEffect, BuffId, Buffs, HealthChange, HealthSource, Stats},
|
||||||
|
event::{EventBus, ServerEvent},
|
||||||
state::DeltaTime,
|
state::DeltaTime,
|
||||||
|
sync::Uid,
|
||||||
};
|
};
|
||||||
use specs::{Entities, Join, Read, System, WriteStorage};
|
use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
/// This system modifies entity stats, changing them using buffs
|
/// This system modifies entity stats, changing them using buffs
|
||||||
@ -16,12 +18,15 @@ impl<'a> System<'a> for Sys {
|
|||||||
type SystemData = (
|
type SystemData = (
|
||||||
Entities<'a>,
|
Entities<'a>,
|
||||||
Read<'a, DeltaTime>,
|
Read<'a, DeltaTime>,
|
||||||
|
Read<'a, EventBus<ServerEvent>>,
|
||||||
|
ReadStorage<'a, Uid>,
|
||||||
WriteStorage<'a, Stats>,
|
WriteStorage<'a, Stats>,
|
||||||
WriteStorage<'a, Buffs>,
|
WriteStorage<'a, Buffs>,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn run(&mut self, (entities, dt, mut stats, mut buffs): Self::SystemData) {
|
fn run(&mut self, (entities, dt, server_bus, uids, mut stats, mut buffs): Self::SystemData) {
|
||||||
for (entity, mut buffs) in (&entities, &mut buffs.restrict_mut()).join() {
|
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 buff_comp = buffs.get_mut_unchecked();
|
||||||
let mut buff_indices_for_removal = Vec::new();
|
let mut buff_indices_for_removal = Vec::new();
|
||||||
// Tick all de/buffs on a Buffs component.
|
// 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.
|
// Remove buffs that have expired.
|
||||||
// Since buffs are added into this vec as it iterates up through the list, it
|
// Since buffs are added into this vec as it iterates up through the
|
||||||
// will be in order of increasing values. Therefore to avoid
|
// list, it will be in order of increasing values.
|
||||||
// removing the incorrect buff, removal will start from the greatest index
|
// Therefore to avoid removing the incorrect buff,
|
||||||
|
// removal will start from the greatest index
|
||||||
// value, which is the last in this vec.
|
// 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() {
|
if let Some(i) = buff_indices_for_removal.pop() {
|
||||||
buff_comp.buffs.remove(i);
|
buff_comp.buffs.remove(i);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,14 +154,19 @@ impl<'a> System<'a> for Sys {
|
|||||||
// Test for server event of buff, remove before merging
|
// Test for server event of buff, remove before merging
|
||||||
server_emitter.emit(ServerEvent::Buff {
|
server_emitter.emit(ServerEvent::Buff {
|
||||||
uid: *uid_b,
|
uid: *uid_b,
|
||||||
buff: buff::BuffChange::Add(buff::Buff {
|
buff_change: buff::BuffChange::Add(buff::Buff {
|
||||||
id: buff::BuffId::Bleeding,
|
id: buff::BuffId::Bleeding,
|
||||||
cat_ids: vec![buff::BuffCategoryId::Physical],
|
cat_ids: vec![buff::BuffCategoryId::Physical],
|
||||||
time: Some(Duration::from_millis(2000)),
|
time: Some(Duration::from_millis(2000)),
|
||||||
effects: vec![buff::BuffEffect::HealthChangeOverTime {
|
effects: vec![
|
||||||
rate: 10.0,
|
buff::BuffEffect::HealthChangeOverTime {
|
||||||
accumulated: 0.0,
|
rate: 10.0,
|
||||||
}],
|
accumulated: 0.0,
|
||||||
|
},
|
||||||
|
buff::BuffEffect::NameChange {
|
||||||
|
prefix: String::from("Injured "),
|
||||||
|
},
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
attack.hit_count += 1;
|
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 ecs = &server.state.ecs();
|
||||||
let mut buffs_all = ecs.write_storage::<comp::Buffs>();
|
let mut buffs_all = ecs.write_storage::<comp::Buffs>();
|
||||||
if let Some(entity) = ecs.entity_from_uid(uid.into()) {
|
if let Some(entity) = ecs.entity_from_uid(uid.into()) {
|
||||||
if let Some(buffs) = buffs_all.get_mut(entity) {
|
if let Some(buffs) = buffs_all.get_mut(entity) {
|
||||||
let mut stats = ecs.write_storage::<comp::Stats>();
|
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) => {
|
buff::BuffChange::Add(new_buff) => {
|
||||||
for effect in &new_buff.effects {
|
for effect in &new_buff.effects {
|
||||||
match effect {
|
match effect {
|
||||||
@ -698,30 +699,35 @@ pub fn handle_buff(server: &mut Server, uid: Uid, buff: buff::BuffChange) {
|
|||||||
}
|
}
|
||||||
buffs.buffs.push(new_buff.clone());
|
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 some_predicate = |current_id: &buff::BuffId| *current_id == id;
|
||||||
let mut i = 0;
|
for i in 0..buffs.buffs.len() {
|
||||||
while i != buffs.buffs.len() {
|
|
||||||
if some_predicate(&mut buffs.buffs[i].id) {
|
if some_predicate(&mut buffs.buffs[i].id) {
|
||||||
let buff = buffs.buffs.remove(i);
|
buff_indices_for_removal.push(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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
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) => {
|
ServerEvent::Chat(msg) => {
|
||||||
chat_messages.push(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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user