Cleaned up logic used to handle buff addition. Old active buffs now get deleted if they had a smaller duration and weaker strength.

This commit is contained in:
Sam 2020-10-18 17:39:13 -05:00
parent 3f7b5a095b
commit 5a5d35fade
3 changed files with 48 additions and 25 deletions

View File

@ -717,7 +717,7 @@ pub fn handle_buff(server: &mut Server, uid: Uid, buff_change: buff::BuffChange)
} else {
let mut duplicate_existed = false;
for i in 0..buffs.active_buffs.len() {
let active_buff = &buffs.active_buffs[i];
let active_buff = &buffs.active_buffs[i].clone();
// Checks if new buff has the same id as an already active buff. If it
// doesn't, new buff added to active buffs. If it does, compares the new
// buff and the active buff, and decides to either add new buff to
@ -726,6 +726,7 @@ pub fn handle_buff(server: &mut Server, uid: Uid, buff_change: buff::BuffChange)
// buffs.
if discriminant(&active_buff.id) == discriminant(&new_buff.id) {
duplicate_existed = true;
// Determines if active buff is weaker than newer buff
if determine_replace_active_buff(
active_buff.clone(),
new_buff.clone(),
@ -733,6 +734,15 @@ pub fn handle_buff(server: &mut Server, uid: Uid, buff_change: buff::BuffChange)
active_buff_indices_for_removal.push(i);
add_buff_effects(new_buff.clone(), stats.get_mut(entity));
buffs.active_buffs.push(new_buff.clone());
// Sees if weaker active has longer duration than new buff
#[allow(clippy::blocks_in_if_conditions)]
if active_buff.time.map_or(true, |act_dur| {
new_buff.time.map_or(false, |new_dur| act_dur > new_dur)
}) {
buffs.inactive_buffs.push(active_buff.clone());
}
// Sees if weaker new buff has longer duration
// than active buff
} else if let Some(active_dur) = active_buff.time {
if let Some(new_dur) = new_buff.time {
if new_dur > active_dur {
@ -742,11 +752,12 @@ pub fn handle_buff(server: &mut Server, uid: Uid, buff_change: buff::BuffChange)
buffs.inactive_buffs.push(new_buff.clone());
}
}
break;
}
}
if !duplicate_existed {
add_buff_effects(new_buff.clone(), stats.get_mut(entity));
buffs.active_buffs.push(new_buff.clone());
buffs.active_buffs.push(new_buff);
}
}
},
@ -873,33 +884,45 @@ fn determine_replace_active_buff(active_buff: buff::Buff, new_buff: buff::Buff)
match new_buff.id {
BuffId::Bleeding {
strength: new_strength,
duration: _,
duration: new_duration,
} => {
if let BuffId::Bleeding {
strength: active_strength,
duration: _,
} = active_buff.id
{
new_strength >= active_strength
new_strength > active_strength
|| (new_strength >= active_strength
&& new_duration.map_or(true, |new_dur| {
active_buff.time.map_or(false, |act_dur| new_dur > act_dur)
}))
} else {
false
}
},
BuffId::Regeneration {
strength: new_strength,
duration: _,
duration: new_duration,
} => {
if let BuffId::Regeneration {
strength: active_strength,
duration: _,
} = active_buff.id
{
new_strength >= active_strength
new_strength > active_strength
|| (new_strength >= active_strength
&& new_duration.map_or(true, |new_dur| {
active_buff.time.map_or(false, |act_dur| new_dur > act_dur)
}))
} else {
false
}
},
BuffId::Cursed { duration: _ } => false,
BuffId::Cursed {
duration: new_duration,
} => new_duration.map_or(true, |new_dur| {
active_buff.time.map_or(false, |act_dur| new_dur > act_dur)
}),
}
}

View File

@ -12,7 +12,7 @@ use crate::{
use common::comp::{BuffId, Buffs};
use conrod_core::{
color,
widget::{self, Button, Text, Image, Rectangle},
widget::{self, Button, Image, Rectangle, Text},
widget_ids, Color, Colorable, Positionable, Sizeable, Widget, WidgetCommon,
};
use inline_tweak::*;
@ -375,15 +375,15 @@ impl<'a> Widget for BuffsBar<'a> {
.zip(state.ids.buff_txts.iter().copied())
.zip(buffs.active_buffs.iter().map(get_buff_info))
.enumerate()
.for_each(|(i, (((id, timer_id),txt_id), buff))| {
.for_each(|(i, (((id, timer_id), txt_id), buff))| {
let max_duration = match buff.id {
BuffId::Regeneration { duration, .. } => duration.unwrap().as_secs_f32(),
BuffId::Bleeding { duration, .. } => duration.unwrap().as_secs_f32(),
_ => 10e6,
_ => 10e6,
};
let current_duration = buff.dur;
// Percentage to determine which frame of the timer overlay is displayed
let duration_percentage = (current_duration / max_duration * 1000.0) as u32;
let duration_percentage = (current_duration / max_duration * 1000.0) as u32;
let buff_img = match buff.id {
BuffId::Regeneration { .. } => self.imgs.buff_plus_0,
BuffId::Bleeding { .. } => self.imgs.debuff_bleed_0,
@ -467,14 +467,14 @@ impl<'a> Widget for BuffsBar<'a> {
event.push(Event::RemoveBuff(buff.id));
}
}
Text::new(&remaining_time)
.down_from(timer_id, tweak!(1.0))
.font_size(self.fonts.cyri.scale(tweak!(10)))
.font_id(self.fonts.cyri.conrod_id)
.graphics_for(timer_id)
.color(TEXT_COLOR)
.set(txt_id, ui);
});
Text::new(&remaining_time)
.down_from(timer_id, tweak!(1.0))
.font_size(self.fonts.cyri.scale(tweak!(10)))
.font_id(self.fonts.cyri.conrod_id)
.graphics_for(timer_id)
.color(TEXT_COLOR)
.set(txt_id, ui);
});
}
event
}

View File

@ -329,10 +329,10 @@ impl<'a> Widget for Group<'a> {
.ecs()
.read_resource::<common::sync::UidAllocator>();
let offset = if self.global_state.settings.gameplay.toggle_debug {
tweak!(320.0)
} else {
110.0
};
tweak!(320.0)
} else {
110.0
};
// Keep track of the total number of widget ids we are using for buffs
let mut total_buff_count = 0;
for (i, &uid) in group_members.iter().copied().enumerate() {
@ -346,7 +346,7 @@ impl<'a> Widget for Group<'a> {
let char_name = stats.name.to_string();
let health_perc = stats.health.current() as f64 / stats.health.maximum() as f64;
// change panel positions when debug info is shown
// change panel positions when debug info is shown
let back = if i == 0 {
Image::new(self.imgs.member_bg)
.top_left_with_margins_on(ui.window, offset, 20.0)
@ -559,7 +559,7 @@ impl<'a> Widget for Group<'a> {
.font_size(20)
.font_id(self.fonts.cyri.conrod_id)
.color(GROUP_COLOR)
.set(state.ids.member_panels_txt[i], ui);
.set(state.ids.member_panels_txt[i], ui);
let back = if i == 0 {
Image::new(self.imgs.member_bg)
.top_left_with_margins_on(ui.window, offset, 20.0)