mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fix group tooltips, make ui buff code more efficient, avoid crashing on characters button press
This commit is contained in:
parent
8fa398954d
commit
be1767a5af
@ -9,7 +9,6 @@ use crate::{
|
|||||||
GlobalState,
|
GlobalState,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::hud::BuffInfo;
|
|
||||||
use common::comp::{BuffId, Buffs};
|
use common::comp::{BuffId, Buffs};
|
||||||
use conrod_core::{
|
use conrod_core::{
|
||||||
color,
|
color,
|
||||||
@ -131,55 +130,51 @@ impl<'a> Widget for BuffsBar<'a> {
|
|||||||
.set(state.ids.buffs_align, ui);
|
.set(state.ids.buffs_align, ui);
|
||||||
|
|
||||||
// Buffs and Debuffs
|
// Buffs and Debuffs
|
||||||
// Create two vecs to display buffs and debuffs separately
|
let (buff_count, debuff_count) = buffs.active_buffs.iter().map(get_buff_info).fold(
|
||||||
let mut buffs_vec = Vec::<BuffInfo>::new();
|
(0, 0),
|
||||||
let mut debuffs_vec = Vec::<BuffInfo>::new();
|
|(buff_count, debuff_count), info| {
|
||||||
for buff in buffs.active_buffs.clone() {
|
if info.is_buff {
|
||||||
let info = get_buff_info(buff);
|
(buff_count + 1, debuff_count)
|
||||||
if info.is_buff {
|
} else {
|
||||||
buffs_vec.push(info);
|
(buff_count, debuff_count + 1)
|
||||||
} else {
|
}
|
||||||
debuffs_vec.push(info);
|
},
|
||||||
}
|
);
|
||||||
}
|
// Limit displayed buffs
|
||||||
if state.ids.buffs.len() < buffs_vec.len() {
|
let buff_count = buff_count.min(22);
|
||||||
state.update(|state| {
|
let debuff_count = debuff_count.min(22);
|
||||||
state
|
|
||||||
.ids
|
let gen = &mut ui.widget_id_generator();
|
||||||
.buffs
|
if state.ids.buffs.len() < buff_count {
|
||||||
.resize(buffs_vec.len(), &mut ui.widget_id_generator())
|
state.update(|state| state.ids.buffs.resize(buff_count, gen));
|
||||||
});
|
|
||||||
};
|
};
|
||||||
if state.ids.debuffs.len() < debuffs_vec.len() {
|
if state.ids.debuffs.len() < debuff_count {
|
||||||
state.update(|state| {
|
state.update(|state| state.ids.debuffs.resize(debuff_count, gen));
|
||||||
state
|
|
||||||
.ids
|
|
||||||
.debuffs
|
|
||||||
.resize(debuffs_vec.len(), &mut ui.widget_id_generator())
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
if state.ids.buff_timers.len() < buffs_vec.len() {
|
if state.ids.buff_timers.len() < buff_count {
|
||||||
state.update(|state| {
|
state.update(|state| state.ids.buff_timers.resize(buff_count, gen));
|
||||||
state
|
|
||||||
.ids
|
|
||||||
.buff_timers
|
|
||||||
.resize(buffs_vec.len(), &mut ui.widget_id_generator())
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
if state.ids.debuff_timers.len() < debuffs_vec.len() {
|
if state.ids.debuff_timers.len() < debuff_count {
|
||||||
state.update(|state| {
|
state.update(|state| state.ids.debuff_timers.resize(debuff_count, gen));
|
||||||
state
|
|
||||||
.ids
|
|
||||||
.debuff_timers
|
|
||||||
.resize(debuffs_vec.len(), &mut ui.widget_id_generator())
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
let pulsating_col = Color::Rgba(1.0, 1.0, 1.0, buff_ani);
|
let pulsating_col = Color::Rgba(1.0, 1.0, 1.0, buff_ani);
|
||||||
let norm_col = Color::Rgba(1.0, 1.0, 1.0, 1.0);
|
let norm_col = Color::Rgba(1.0, 1.0, 1.0, 1.0);
|
||||||
// Create Buff Widgets
|
// Create Buff Widgets
|
||||||
for (i, buff) in buffs_vec.iter().enumerate() {
|
state
|
||||||
if i < 22 {
|
.ids
|
||||||
// Limit displayed buffs
|
.buffs
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.zip(state.ids.buff_timers.iter().copied())
|
||||||
|
.zip(
|
||||||
|
buffs
|
||||||
|
.active_buffs
|
||||||
|
.iter()
|
||||||
|
.map(get_buff_info)
|
||||||
|
.filter(|info| info.is_buff),
|
||||||
|
)
|
||||||
|
.enumerate()
|
||||||
|
.for_each(|(i, ((id, timer_id), buff))| {
|
||||||
let max_duration = match buff.id {
|
let max_duration = match buff.id {
|
||||||
BuffId::Regeneration { duration, .. } => duration.unwrap().as_secs_f32(),
|
BuffId::Regeneration { duration, .. } => duration.unwrap().as_secs_f32(),
|
||||||
_ => 10.0,
|
_ => 10.0,
|
||||||
@ -205,7 +200,7 @@ impl<'a> Widget for BuffsBar<'a> {
|
|||||||
} else {
|
} else {
|
||||||
Some(norm_col)
|
Some(norm_col)
|
||||||
})
|
})
|
||||||
.set(state.ids.buffs[i], ui);
|
.set(id, ui);
|
||||||
// Create Buff tooltip
|
// Create Buff tooltip
|
||||||
let title = match buff.id {
|
let title = match buff.id {
|
||||||
BuffId::Regeneration { .. } => {
|
BuffId::Regeneration { .. } => {
|
||||||
@ -239,7 +234,7 @@ impl<'a> Widget for BuffsBar<'a> {
|
|||||||
_ => self.imgs.nothing,
|
_ => self.imgs.nothing,
|
||||||
})
|
})
|
||||||
.w_h(20.0, 20.0)
|
.w_h(20.0, 20.0)
|
||||||
.middle_of(state.ids.buffs[i])
|
.middle_of(id)
|
||||||
.with_tooltip(
|
.with_tooltip(
|
||||||
self.tooltip_manager,
|
self.tooltip_manager,
|
||||||
title,
|
title,
|
||||||
@ -247,18 +242,28 @@ impl<'a> Widget for BuffsBar<'a> {
|
|||||||
&buffs_tooltip,
|
&buffs_tooltip,
|
||||||
BUFF_COLOR,
|
BUFF_COLOR,
|
||||||
)
|
)
|
||||||
.set(state.ids.buff_timers[i], ui)
|
.set(timer_id, ui)
|
||||||
.was_clicked()
|
.was_clicked()
|
||||||
{
|
{
|
||||||
event.push(Event::RemoveBuff(buff.id));
|
event.push(Event::RemoveBuff(buff.id));
|
||||||
};
|
};
|
||||||
};
|
});
|
||||||
}
|
|
||||||
// Create Debuff Widgets
|
// Create Debuff Widgets
|
||||||
for (i, debuff) in debuffs_vec.iter().enumerate() {
|
state
|
||||||
if i < 22 {
|
.ids
|
||||||
// Limit displayed buffs
|
.debuffs
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.zip(state.ids.debuff_timers.iter().copied())
|
||||||
|
.zip(
|
||||||
|
buffs
|
||||||
|
.active_buffs
|
||||||
|
.iter()
|
||||||
|
.map(get_buff_info)
|
||||||
|
.filter(|info| !info.is_buff),
|
||||||
|
)
|
||||||
|
.enumerate()
|
||||||
|
.for_each(|(i, ((id, timer_id), debuff))| {
|
||||||
let max_duration = match debuff.id {
|
let max_duration = match debuff.id {
|
||||||
BuffId::Bleeding { duration, .. } => {
|
BuffId::Bleeding { duration, .. } => {
|
||||||
duration.unwrap_or(Duration::from_secs(60)).as_secs_f32()
|
duration.unwrap_or(Duration::from_secs(60)).as_secs_f32()
|
||||||
@ -292,7 +297,7 @@ impl<'a> Widget for BuffsBar<'a> {
|
|||||||
} else {
|
} else {
|
||||||
Some(norm_col)
|
Some(norm_col)
|
||||||
})
|
})
|
||||||
.set(state.ids.debuffs[i], ui);
|
.set(id, ui);
|
||||||
// Create Debuff tooltip
|
// Create Debuff tooltip
|
||||||
let title = match debuff.id {
|
let title = match debuff.id {
|
||||||
BuffId::Bleeding { .. } => {
|
BuffId::Bleeding { .. } => {
|
||||||
@ -324,7 +329,7 @@ impl<'a> Widget for BuffsBar<'a> {
|
|||||||
_ => self.imgs.nothing,
|
_ => self.imgs.nothing,
|
||||||
})
|
})
|
||||||
.w_h(20.0, 20.0)
|
.w_h(20.0, 20.0)
|
||||||
.middle_of(state.ids.debuffs[i])
|
.middle_of(id)
|
||||||
.with_tooltip(
|
.with_tooltip(
|
||||||
self.tooltip_manager,
|
self.tooltip_manager,
|
||||||
title,
|
title,
|
||||||
@ -332,10 +337,10 @@ impl<'a> Widget for BuffsBar<'a> {
|
|||||||
&buffs_tooltip,
|
&buffs_tooltip,
|
||||||
DEBUFF_COLOR,
|
DEBUFF_COLOR,
|
||||||
)
|
)
|
||||||
.set(state.ids.debuff_timers[i], ui);
|
.set(timer_id, ui);
|
||||||
};
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let BuffPosition::Map = buff_position {
|
if let BuffPosition::Map = buff_position {
|
||||||
// Alignment
|
// Alignment
|
||||||
Rectangle::fill_with([tweak!(300.0), tweak!(280.0)], color::RED)
|
Rectangle::fill_with([tweak!(300.0), tweak!(280.0)], color::RED)
|
||||||
|
@ -5,7 +5,7 @@ use super::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
hud::{get_buff_info, BuffInfo},
|
hud::get_buff_info,
|
||||||
i18n::VoxygenLocalization,
|
i18n::VoxygenLocalization,
|
||||||
settings::Settings,
|
settings::Settings,
|
||||||
ui::{fonts::ConrodVoxygenFonts, ImageFrame, Tooltip, TooltipManager, Tooltipable},
|
ui::{fonts::ConrodVoxygenFonts, ImageFrame, Tooltip, TooltipManager, Tooltipable},
|
||||||
@ -75,7 +75,6 @@ pub struct Group<'a> {
|
|||||||
localized_strings: &'a std::sync::Arc<VoxygenLocalization>,
|
localized_strings: &'a std::sync::Arc<VoxygenLocalization>,
|
||||||
pulse: f32,
|
pulse: f32,
|
||||||
global_state: &'a GlobalState,
|
global_state: &'a GlobalState,
|
||||||
buffs: &'a Buffs,
|
|
||||||
tooltip_manager: &'a mut TooltipManager,
|
tooltip_manager: &'a mut TooltipManager,
|
||||||
|
|
||||||
#[conrod(common_builder)]
|
#[conrod(common_builder)]
|
||||||
@ -94,7 +93,6 @@ impl<'a> Group<'a> {
|
|||||||
localized_strings: &'a std::sync::Arc<VoxygenLocalization>,
|
localized_strings: &'a std::sync::Arc<VoxygenLocalization>,
|
||||||
pulse: f32,
|
pulse: f32,
|
||||||
global_state: &'a GlobalState,
|
global_state: &'a GlobalState,
|
||||||
buffs: &'a Buffs,
|
|
||||||
tooltip_manager: &'a mut TooltipManager,
|
tooltip_manager: &'a mut TooltipManager,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -107,7 +105,6 @@ impl<'a> Group<'a> {
|
|||||||
localized_strings,
|
localized_strings,
|
||||||
pulse,
|
pulse,
|
||||||
global_state,
|
global_state,
|
||||||
buffs,
|
|
||||||
tooltip_manager,
|
tooltip_manager,
|
||||||
common: widget::CommonBuilder::default(),
|
common: widget::CommonBuilder::default(),
|
||||||
}
|
}
|
||||||
@ -145,7 +142,6 @@ impl<'a> Widget for Group<'a> {
|
|||||||
let widget::UpdateArgs { state, ui, .. } = args;
|
let widget::UpdateArgs { state, ui, .. } = args;
|
||||||
let mut events = Vec::new();
|
let mut events = Vec::new();
|
||||||
let localized_strings = self.localized_strings;
|
let localized_strings = self.localized_strings;
|
||||||
//let buffs = self.buffs;
|
|
||||||
let buff_ani = ((self.pulse * 4.0/* speed factor */).cos() * 0.5 + 0.8) + 0.5; //Animation timer
|
let buff_ani = ((self.pulse * 4.0/* speed factor */).cos() * 0.5 + 0.8) + 0.5; //Animation timer
|
||||||
let buffs_tooltip = Tooltip::new({
|
let buffs_tooltip = Tooltip::new({
|
||||||
// Edge images [t, b, r, l]
|
// Edge images [t, b, r, l]
|
||||||
@ -333,6 +329,8 @@ impl<'a> Widget for Group<'a> {
|
|||||||
.ecs()
|
.ecs()
|
||||||
.read_resource::<common::sync::UidAllocator>();
|
.read_resource::<common::sync::UidAllocator>();
|
||||||
|
|
||||||
|
// 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() {
|
for (i, &uid) in group_members.iter().copied().enumerate() {
|
||||||
self.show.group = true;
|
self.show.group = true;
|
||||||
let entity = uid_allocator.retrieve_entity_internal(uid.into());
|
let entity = uid_allocator.retrieve_entity_internal(uid.into());
|
||||||
@ -447,27 +445,29 @@ impl<'a> Widget for Group<'a> {
|
|||||||
.set(state.ids.member_stam[i], ui);
|
.set(state.ids.member_stam[i], ui);
|
||||||
}
|
}
|
||||||
if let Some(buffs) = buffs {
|
if let Some(buffs) = buffs {
|
||||||
let mut buffs_vec = Vec::<BuffInfo>::new();
|
// Limit displayed buffs to 11
|
||||||
for buff in buffs.active_buffs.clone() {
|
let buff_count = buffs.active_buffs.len().min(11);
|
||||||
let info = get_buff_info(buff);
|
total_buff_count += buff_count;
|
||||||
buffs_vec.push(info);
|
let gen = &mut ui.widget_id_generator();
|
||||||
|
if state.ids.buffs.len() < total_buff_count {
|
||||||
|
state.update(|state| state.ids.buffs.resize(total_buff_count, gen));
|
||||||
|
}
|
||||||
|
if state.ids.buff_timers.len() < total_buff_count {
|
||||||
|
state.update(|state| {
|
||||||
|
state.ids.buff_timers.resize(total_buff_count, gen)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
state.update(|state| {
|
|
||||||
state.ids.buffs.resize(
|
|
||||||
state.ids.buffs.len() + buffs_vec.len(),
|
|
||||||
&mut ui.widget_id_generator(),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
state.update(|state| {
|
|
||||||
state.ids.buff_timers.resize(
|
|
||||||
state.ids.buff_timers.len() + buffs_vec.len(),
|
|
||||||
&mut ui.widget_id_generator(),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
// Create Buff Widgets
|
// Create Buff Widgets
|
||||||
for (x, buff) in buffs_vec.iter().enumerate() {
|
let mut prev_id = None;
|
||||||
if x < 11 {
|
state
|
||||||
// Limit displayed buffs
|
.ids
|
||||||
|
.buffs
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.zip(state.ids.buff_timers.iter().copied())
|
||||||
|
.skip(total_buff_count - buff_count)
|
||||||
|
.zip(buffs.active_buffs.iter().map(get_buff_info))
|
||||||
|
.for_each(|((id, timer_id), buff)| {
|
||||||
let max_duration = match buff.id {
|
let max_duration = match buff.id {
|
||||||
BuffId::Regeneration { duration, .. } => {
|
BuffId::Regeneration { duration, .. } => {
|
||||||
duration.unwrap().as_secs_f32()
|
duration.unwrap().as_secs_f32()
|
||||||
@ -485,22 +485,23 @@ impl<'a> Widget for Group<'a> {
|
|||||||
BuffId::Cursed { .. } => self.imgs.debuff_skull_0,
|
BuffId::Cursed { .. } => self.imgs.debuff_skull_0,
|
||||||
};
|
};
|
||||||
let buff_widget = Image::new(buff_img).w_h(20.0, 20.0);
|
let buff_widget = Image::new(buff_img).w_h(20.0, 20.0);
|
||||||
let buff_widget = if x == 0 {
|
let buff_widget = if let Some(id) = prev_id {
|
||||||
|
buff_widget.right_from(id, 1.0)
|
||||||
|
} else {
|
||||||
buff_widget.bottom_left_with_margins_on(
|
buff_widget.bottom_left_with_margins_on(
|
||||||
state.ids.member_panels_frame[i],
|
state.ids.member_panels_frame[i],
|
||||||
-21.0,
|
-21.0,
|
||||||
1.0,
|
1.0,
|
||||||
)
|
)
|
||||||
} else {
|
|
||||||
buff_widget.right_from(state.ids.buffs[state.ids.buffs.len() - buffs_vec.len() + x - 1/*x - 1*/], 1.0)
|
|
||||||
};
|
};
|
||||||
|
prev_id = Some(id);
|
||||||
buff_widget
|
buff_widget
|
||||||
.color(if current_duration < 10.0 {
|
.color(if current_duration < 10.0 {
|
||||||
Some(pulsating_col)
|
Some(pulsating_col)
|
||||||
} else {
|
} else {
|
||||||
Some(norm_col)
|
Some(norm_col)
|
||||||
})
|
})
|
||||||
.set(state.ids.buffs[state.ids.buffs.len() - buffs_vec.len() + x/*x*/], ui);
|
.set(id, ui);
|
||||||
// Create Buff tooltip
|
// Create Buff tooltip
|
||||||
let title = match buff.id {
|
let title = match buff.id {
|
||||||
BuffId::Regeneration { .. } => {
|
BuffId::Regeneration { .. } => {
|
||||||
@ -538,17 +539,20 @@ impl<'a> Widget for Group<'a> {
|
|||||||
_ => self.imgs.nothing,
|
_ => self.imgs.nothing,
|
||||||
})
|
})
|
||||||
.w_h(20.0, 20.0)
|
.w_h(20.0, 20.0)
|
||||||
.middle_of(state.ids.buffs[state.ids.buffs.len() - buffs_vec.len() + x/*x*/])
|
.middle_of(id)
|
||||||
.with_tooltip(
|
.with_tooltip(
|
||||||
self.tooltip_manager,
|
self.tooltip_manager,
|
||||||
title,
|
title,
|
||||||
&desc,
|
&desc,
|
||||||
&buffs_tooltip,
|
&buffs_tooltip,
|
||||||
if buff.is_buff {BUFF_COLOR} else {DEBUFF_COLOR},
|
if buff.is_buff {
|
||||||
|
BUFF_COLOR
|
||||||
|
} else {
|
||||||
|
DEBUFF_COLOR
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.set(state.ids.buff_timers[state.ids.buffs.len() - buffs_vec.len() + x/*x*/], ui);
|
.set(timer_id, ui);
|
||||||
};
|
});
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Values N.A.
|
// Values N.A.
|
||||||
Text::new(&stats.name.to_string())
|
Text::new(&stats.name.to_string())
|
||||||
|
@ -1803,7 +1803,6 @@ impl Hud {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Group Window
|
// Group Window
|
||||||
let buffs = buffs.get(client.entity()).unwrap();
|
|
||||||
for event in Group::new(
|
for event in Group::new(
|
||||||
&mut self.show,
|
&mut self.show,
|
||||||
client,
|
client,
|
||||||
@ -1814,7 +1813,6 @@ impl Hud {
|
|||||||
&self.voxygen_i18n,
|
&self.voxygen_i18n,
|
||||||
self.pulse,
|
self.pulse,
|
||||||
&global_state,
|
&global_state,
|
||||||
&buffs,
|
|
||||||
tooltip_manager,
|
tooltip_manager,
|
||||||
)
|
)
|
||||||
.set(self.ids.group_window, ui_widgets)
|
.set(self.ids.group_window, ui_widgets)
|
||||||
@ -2728,7 +2726,7 @@ pub fn get_quality_col<I: ItemDesc>(item: &I) -> Color {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Get info about applied buffs
|
// Get info about applied buffs
|
||||||
fn get_buff_info(buff: comp::Buff) -> BuffInfo {
|
fn get_buff_info(buff: &comp::Buff) -> BuffInfo {
|
||||||
BuffInfo {
|
BuffInfo {
|
||||||
id: buff.id,
|
id: buff.id,
|
||||||
is_buff: buff
|
is_buff: buff
|
||||||
|
@ -3,7 +3,7 @@ use super::{
|
|||||||
REGION_COLOR, SAY_COLOR, STAMINA_COLOR, TELL_COLOR, TEXT_BG, TEXT_COLOR,
|
REGION_COLOR, SAY_COLOR, STAMINA_COLOR, TELL_COLOR, TEXT_BG, TEXT_COLOR,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
hud::{get_buff_info, BuffInfo},
|
hud::get_buff_info,
|
||||||
i18n::VoxygenLocalization,
|
i18n::VoxygenLocalization,
|
||||||
settings::GameplaySettings,
|
settings::GameplaySettings,
|
||||||
ui::{fonts::ConrodVoxygenFonts, Ingameable},
|
ui::{fonts::ConrodVoxygenFonts, Ingameable},
|
||||||
@ -135,14 +135,18 @@ impl<'a> Ingameable for Overhead<'a> {
|
|||||||
// - 1 Rect::new for mana
|
// - 1 Rect::new for mana
|
||||||
// If there are Buffs
|
// If there are Buffs
|
||||||
// - 1 Alignment Rectangle
|
// - 1 Alignment Rectangle
|
||||||
// - 10 + 10 Buffs and Timer Overlays
|
// - 10 + 10 Buffs and Timer Overlays (only if there is no speech bubble)
|
||||||
// If there's a speech bubble
|
// If there's a speech bubble
|
||||||
// - 2 Text::new for speech bubble
|
// - 2 Text::new for speech bubble
|
||||||
// - 1 Image::new for icon
|
// - 1 Image::new for icon
|
||||||
// - 10 Image::new for speech bubble (9-slice + tail)
|
// - 10 Image::new for speech bubble (9-slice + tail)
|
||||||
self.info.map_or(0, |info| {
|
self.info.map_or(0, |info| {
|
||||||
2 + 1
|
2 + 1
|
||||||
+ info.buffs.active_buffs.len().min(10) * 2
|
+ if self.bubble.is_none() {
|
||||||
|
info.buffs.active_buffs.len().min(10) * 2
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
+ if show_healthbar(info.stats) {
|
+ if show_healthbar(info.stats) {
|
||||||
5 + if info.energy.is_some() { 1 } else { 0 }
|
5 + if info.energy.is_some() { 1 } else { 0 }
|
||||||
} else {
|
} else {
|
||||||
@ -191,11 +195,6 @@ impl<'a> Widget for Overhead<'a> {
|
|||||||
} else {
|
} else {
|
||||||
MANA_BAR_Y + 32.0
|
MANA_BAR_Y + 32.0
|
||||||
};
|
};
|
||||||
let mut buffs_vec = Vec::<BuffInfo>::new();
|
|
||||||
for buff in buffs.active_buffs.clone() {
|
|
||||||
let info = get_buff_info(buff);
|
|
||||||
buffs_vec.push(info);
|
|
||||||
}
|
|
||||||
let font_size = if hp_percentage.abs() > 99.9 { 24 } else { 20 };
|
let font_size = if hp_percentage.abs() > 99.9 { 24 } else { 20 };
|
||||||
// Show K for numbers above 10^3 and truncate them
|
// Show K for numbers above 10^3 and truncate them
|
||||||
// Show M for numbers above 10^6 and truncate them
|
// Show M for numbers above 10^6 and truncate them
|
||||||
@ -211,76 +210,80 @@ impl<'a> Widget for Overhead<'a> {
|
|||||||
};
|
};
|
||||||
// Buffs
|
// Buffs
|
||||||
// Alignment
|
// Alignment
|
||||||
|
let buff_count = buffs.active_buffs.len().min(11);
|
||||||
Rectangle::fill_with([tweak!(168.0), tweak!(100.0)], color::TRANSPARENT)
|
Rectangle::fill_with([tweak!(168.0), tweak!(100.0)], color::TRANSPARENT)
|
||||||
.x_y(-1.0, name_y + tweak!(60.0))
|
.x_y(-1.0, name_y + tweak!(60.0))
|
||||||
.parent(id)
|
.parent(id)
|
||||||
.set(state.ids.buffs_align, ui);
|
.set(state.ids.buffs_align, ui);
|
||||||
if state.ids.buffs.len() < buffs_vec.len() {
|
|
||||||
state.update(|state| {
|
let gen = &mut ui.widget_id_generator();
|
||||||
state
|
if state.ids.buffs.len() < buff_count {
|
||||||
.ids
|
state.update(|state| state.ids.buffs.resize(buff_count, gen));
|
||||||
.buffs
|
|
||||||
.resize(buffs_vec.len(), &mut ui.widget_id_generator())
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
if state.ids.buff_timers.len() < buffs_vec.len() {
|
if state.ids.buff_timers.len() < buff_count {
|
||||||
state.update(|state| {
|
state.update(|state| state.ids.buff_timers.resize(buff_count, gen));
|
||||||
state
|
|
||||||
.ids
|
|
||||||
.buff_timers
|
|
||||||
.resize(buffs_vec.len(), &mut ui.widget_id_generator())
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let buff_ani = ((self.pulse * 4.0).cos() * 0.5 + 0.8) + 0.5; //Animation timer
|
let buff_ani = ((self.pulse * 4.0).cos() * 0.5 + 0.8) + 0.5; //Animation timer
|
||||||
let pulsating_col = Color::Rgba(1.0, 1.0, 1.0, buff_ani);
|
let pulsating_col = Color::Rgba(1.0, 1.0, 1.0, buff_ani);
|
||||||
let norm_col = Color::Rgba(1.0, 1.0, 1.0, 1.0);
|
let norm_col = Color::Rgba(1.0, 1.0, 1.0, 1.0);
|
||||||
// Create Buff Widgets
|
// Create Buff Widgets
|
||||||
for (i, buff) in buffs_vec.iter().enumerate() {
|
if self.bubble.is_none() {
|
||||||
if i < 11 && self.bubble.is_none() {
|
state
|
||||||
// Limit displayed buffs
|
.ids
|
||||||
let max_duration = match buff.id {
|
.buffs
|
||||||
BuffId::Regeneration { duration, .. } => duration.unwrap().as_secs_f32(),
|
.iter()
|
||||||
_ => 10.0,
|
.copied()
|
||||||
};
|
.zip(state.ids.buff_timers.iter().copied())
|
||||||
let current_duration = buff.dur;
|
.zip(buffs.active_buffs.iter().map(get_buff_info))
|
||||||
let duration_percentage = (current_duration / max_duration * 1000.0) as u32; // Percentage to determine which frame of the timer overlay is displayed
|
.enumerate()
|
||||||
let buff_img = match buff.id {
|
.for_each(|(i, ((id, timer_id), buff))| {
|
||||||
BuffId::Regeneration { .. } => self.imgs.buff_plus_0,
|
// Limit displayed buffs
|
||||||
BuffId::Bleeding { .. } => self.imgs.debuff_bleed_0,
|
let max_duration = match buff.id {
|
||||||
BuffId::Cursed { .. } => self.imgs.debuff_skull_0,
|
BuffId::Regeneration { duration, .. } => {
|
||||||
};
|
duration.unwrap().as_secs_f32()
|
||||||
let buff_widget = Image::new(buff_img).w_h(20.0, 20.0);
|
},
|
||||||
// Sort buffs into rows of 5 slots
|
_ => 10.0,
|
||||||
let x = i % 5;
|
};
|
||||||
let y = i / 5;
|
let current_duration = buff.dur;
|
||||||
let buff_widget = buff_widget.bottom_left_with_margins_on(
|
let duration_percentage = (current_duration / max_duration * 1000.0) as u32; // Percentage to determine which frame of the timer overlay is displayed
|
||||||
state.ids.buffs_align,
|
let buff_img = match buff.id {
|
||||||
0.0 + y as f64 * (21.0),
|
BuffId::Regeneration { .. } => self.imgs.buff_plus_0,
|
||||||
0.0 + x as f64 * (21.0),
|
BuffId::Bleeding { .. } => self.imgs.debuff_bleed_0,
|
||||||
);
|
BuffId::Cursed { .. } => self.imgs.debuff_skull_0,
|
||||||
buff_widget
|
};
|
||||||
.color(if current_duration < 10.0 {
|
let buff_widget = Image::new(buff_img).w_h(20.0, 20.0);
|
||||||
Some(pulsating_col)
|
// Sort buffs into rows of 5 slots
|
||||||
} else {
|
let x = i % 5;
|
||||||
Some(norm_col)
|
let y = i / 5;
|
||||||
})
|
let buff_widget = buff_widget.bottom_left_with_margins_on(
|
||||||
.set(state.ids.buffs[i], ui);
|
state.ids.buffs_align,
|
||||||
|
0.0 + y as f64 * (21.0),
|
||||||
|
0.0 + x as f64 * (21.0),
|
||||||
|
);
|
||||||
|
buff_widget
|
||||||
|
.color(if current_duration < 10.0 {
|
||||||
|
Some(pulsating_col)
|
||||||
|
} else {
|
||||||
|
Some(norm_col)
|
||||||
|
})
|
||||||
|
.set(id, ui);
|
||||||
|
|
||||||
Image::new(match duration_percentage as u64 {
|
Image::new(match duration_percentage as u64 {
|
||||||
875..=1000 => self.imgs.nothing, // 8/8
|
875..=1000 => self.imgs.nothing, // 8/8
|
||||||
750..=874 => self.imgs.buff_0, // 7/8
|
750..=874 => self.imgs.buff_0, // 7/8
|
||||||
625..=749 => self.imgs.buff_1, // 6/8
|
625..=749 => self.imgs.buff_1, // 6/8
|
||||||
500..=624 => self.imgs.buff_2, // 5/8
|
500..=624 => self.imgs.buff_2, // 5/8
|
||||||
375..=499 => self.imgs.buff_3, // 4/8
|
375..=499 => self.imgs.buff_3, // 4/8
|
||||||
250..=374 => self.imgs.buff_4, //3/8
|
250..=374 => self.imgs.buff_4, //3/8
|
||||||
125..=249 => self.imgs.buff_5, // 2/8
|
125..=249 => self.imgs.buff_5, // 2/8
|
||||||
0..=124 => self.imgs.buff_6, // 1/8
|
0..=124 => self.imgs.buff_6, // 1/8
|
||||||
_ => self.imgs.nothing,
|
_ => self.imgs.nothing,
|
||||||
})
|
})
|
||||||
.w_h(20.0, 20.0)
|
.w_h(20.0, 20.0)
|
||||||
.middle_of(state.ids.buffs[i])
|
.middle_of(id)
|
||||||
.set(state.ids.buff_timers[i], ui);
|
.set(timer_id, ui);
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
// Name
|
// Name
|
||||||
Text::new(name)
|
Text::new(name)
|
||||||
|
Loading…
Reference in New Issue
Block a user