mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fixed issue with max health change over time buff being reset if re-applied. Addressed review comments.
This commit is contained in:
parent
4c79936c07
commit
42388976d7
@ -424,7 +424,9 @@ fn compare_end_time(a: Option<Time>, b: Option<Time>) -> bool {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
impl PartialEq for Buff {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.data.strength == other.data.strength && self.end_time == other.end_time
|
||||
self.data.strength == other.data.strength
|
||||
&& self.end_time == other.end_time
|
||||
&& self.start_time == other.start_time
|
||||
}
|
||||
}
|
||||
|
||||
@ -461,8 +463,10 @@ pub enum BuffSource {
|
||||
pub struct Buffs {
|
||||
/// Uid used for synchronization
|
||||
id_counter: u64,
|
||||
/// Maps Kinds of buff to Id's of currently applied buffs of that kind
|
||||
pub kinds: HashMap<BuffKind, Vec<BuffId>>,
|
||||
/// Maps Kinds of buff to Id's of currently applied buffs of that kind and
|
||||
/// the time that the first buff was added (time gets reset if entity no
|
||||
/// longer has buffs of that kind)
|
||||
pub kinds: HashMap<BuffKind, (Vec<BuffId>, Time)>,
|
||||
// All currently applied buffs stored by Id
|
||||
pub buffs: HashMap<BuffId, Buff>,
|
||||
}
|
||||
@ -471,13 +475,14 @@ pub struct Buffs {
|
||||
impl Buffs {
|
||||
fn sort_kind(&mut self, kind: BuffKind) {
|
||||
if let Some(buff_order) = self.kinds.get_mut(&kind) {
|
||||
if buff_order.is_empty() {
|
||||
if buff_order.0.is_empty() {
|
||||
self.kinds.remove(&kind);
|
||||
} else {
|
||||
let buffs = &self.buffs;
|
||||
// Intentionally sorted in reverse so that the strongest buffs are earlier in
|
||||
// the vector
|
||||
buff_order
|
||||
.0
|
||||
.sort_by(|a, b| buffs[b].partial_cmp(&buffs[a]).unwrap_or(Ordering::Equal));
|
||||
}
|
||||
}
|
||||
@ -485,7 +490,7 @@ impl Buffs {
|
||||
|
||||
pub fn remove_kind(&mut self, kind: BuffKind) {
|
||||
if let Some(buff_ids) = self.kinds.get_mut(&kind) {
|
||||
for id in buff_ids {
|
||||
for id in &buff_ids.0 {
|
||||
self.buffs.remove(id);
|
||||
}
|
||||
self.kinds.remove(&kind);
|
||||
@ -494,7 +499,11 @@ impl Buffs {
|
||||
|
||||
fn force_insert(&mut self, id: BuffId, buff: Buff, current_time: Time) -> BuffId {
|
||||
let kind = buff.kind;
|
||||
self.kinds.entry(kind).or_default().push(id);
|
||||
self.kinds
|
||||
.entry(kind)
|
||||
.or_insert((Vec::new(), current_time))
|
||||
.0
|
||||
.push(id);
|
||||
self.buffs.insert(id, buff);
|
||||
self.sort_kind(kind);
|
||||
if kind.queues() {
|
||||
@ -514,7 +523,7 @@ impl Buffs {
|
||||
pub fn iter_kind(&self, kind: BuffKind) -> impl Iterator<Item = (BuffId, &Buff)> + '_ {
|
||||
self.kinds
|
||||
.get(&kind)
|
||||
.map(|ids| ids.iter())
|
||||
.map(|ids| ids.0.iter())
|
||||
.unwrap_or_else(|| [].iter())
|
||||
.map(move |id| (*id, &self.buffs[id]))
|
||||
}
|
||||
@ -526,9 +535,9 @@ impl Buffs {
|
||||
if kind.stacks() {
|
||||
// Iterate stackable buffs in reverse order to show the timer of the soonest one
|
||||
// to expire
|
||||
Either::Left(ids.iter().filter_map(|id| self.buffs.get(id)).rev())
|
||||
Either::Left(ids.0.iter().filter_map(|id| self.buffs.get(id)).rev())
|
||||
} else {
|
||||
Either::Right(self.buffs.get(&ids[0]).into_iter())
|
||||
Either::Right(self.buffs.get(&ids.0[0]).into_iter())
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -539,22 +548,16 @@ impl Buffs {
|
||||
let kind = kind.kind;
|
||||
self.kinds
|
||||
.get_mut(&kind)
|
||||
.map(|ids| ids.retain(|id| *id != buff_id));
|
||||
.map(|ids| ids.0.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)
|
||||
}
|
||||
|
||||
fn delay_queueable_buffs(&mut self, kind: BuffKind, current_time: Time) {
|
||||
let mut next_start_time: Option<Time> = None;
|
||||
debug_assert!(kind.queues());
|
||||
if let Some(buffs) = self.kinds.get(&kind) {
|
||||
buffs.iter().for_each(|id| {
|
||||
buffs.0.iter().for_each(|id| {
|
||||
if let Some(buff) = self.buffs.get_mut(id) {
|
||||
// End time only being updated when there is some next_start_time will
|
||||
// technically cause buffs to "end early" if they have a weaker strength than a
|
||||
|
@ -329,9 +329,9 @@ impl<'a> System<'a> for Sys {
|
||||
.kinds
|
||||
.iter()
|
||||
.map(|(kind, ids)| (*kind, ids.clone()))
|
||||
.collect::<Vec<(BuffKind, Vec<BuffId>)>>();
|
||||
.collect::<Vec<(BuffKind, (Vec<BuffId>, Time))>>();
|
||||
buff_kinds.sort_by_key(|(kind, _)| !kind.affects_subsequent_buffs());
|
||||
for (buff_kind, buff_ids) in buff_kinds.into_iter() {
|
||||
for (buff_kind, (buff_ids, kind_start_time)) in buff_kinds.into_iter() {
|
||||
let mut active_buff_ids = Vec::new();
|
||||
if buff_kind.stacks() {
|
||||
// Process all the buffs of this kind
|
||||
@ -359,6 +359,7 @@ impl<'a> System<'a> for Sys {
|
||||
effect,
|
||||
buff.kind,
|
||||
buff.start_time,
|
||||
kind_start_time,
|
||||
&read_data,
|
||||
&mut stat,
|
||||
health,
|
||||
@ -404,6 +405,7 @@ fn execute_effect(
|
||||
effect: &BuffEffect,
|
||||
buff_kind: BuffKind,
|
||||
buff_start_time: Time,
|
||||
buff_kind_start_time: Time,
|
||||
read_data: &ReadData,
|
||||
stat: &mut Stats,
|
||||
health: &Health,
|
||||
@ -515,7 +517,7 @@ fn execute_effect(
|
||||
kind,
|
||||
target_fraction,
|
||||
} => {
|
||||
let potential_amount = (time.0 - buff_start_time.0) as f32 * rate;
|
||||
let potential_amount = (time.0 - buff_kind_start_time.0) as f32 * rate;
|
||||
|
||||
// Percentage change that should be applied to max_health
|
||||
let potential_fraction = 1.0
|
||||
|
@ -1308,10 +1308,10 @@ pub fn handle_parry_hook(server: &Server, defender: EcsEntity, attacker: Option<
|
||||
let duration = char_state
|
||||
.durations()
|
||||
.and_then(|durs| durs.recover)
|
||||
.map_or(0.5, |dur| dur.as_secs_f32())
|
||||
.map_or(0.5, |dur| dur.as_secs_f64())
|
||||
.max(0.5)
|
||||
.mul(2.0);
|
||||
let data = buff::BuffData::new(1.0, Some(Secs(duration as f64)), None);
|
||||
let data = buff::BuffData::new(1.0, Some(Secs(duration)), None);
|
||||
let source = if let Some(uid) = ecs.read_storage::<Uid>().get(defender) {
|
||||
BuffSource::Character { by: *uid }
|
||||
} else {
|
||||
|
@ -1312,7 +1312,7 @@ impl ParticleMgr {
|
||||
let mut multiplicity = 0;
|
||||
// Only show particles for potion sickness at the beginning, after the
|
||||
// drinking animation finishes
|
||||
if buff_ids
|
||||
if buff_ids.0
|
||||
.iter()
|
||||
.filter_map(|id| buffs.buffs.get(id))
|
||||
.any(|buff| {
|
||||
|
Loading…
Reference in New Issue
Block a user