Unify healthbar showing calculation, move bubble acquisition into closure

This commit is contained in:
Imbris 2020-09-19 13:53:40 -04:00
parent 6cd6a96b64
commit 9464fd49a9
2 changed files with 21 additions and 39 deletions

View File

@ -710,7 +710,6 @@ impl Hud {
let hp_floater_lists = ecs.read_storage::<vcomp::HpFloaterList>();
let uids = ecs.read_storage::<common::sync::Uid>();
let interpolated = ecs.read_storage::<vcomp::Interpolated>();
let players = ecs.read_storage::<comp::Player>();
let scales = ecs.read_storage::<comp::Scale>();
let bodies = ecs.read_storage::<comp::Body>();
let items = ecs.read_storage::<comp::Item>();
@ -1078,14 +1077,15 @@ impl Hud {
.set(overitem_id, ui_widgets);
}
let speech_bubbles = &self.speech_bubbles;
// Render overhead name tags and health bars
for (pos, info, display_bubble, stats, height_offset, hpfl, uid, in_group) in (
for (pos, info, bubble, stats, height_offset, hpfl, in_group) in (
&entities,
&pos,
interpolated.maybe(),
&stats,
energy.maybe(),
players.maybe(),
scales.maybe(),
&bodies,
&hp_floater_lists,
@ -1098,7 +1098,7 @@ impl Hud {
entity != me && !stats.is_dead
})
.filter_map(
|(entity, pos, interpolated, stats, energy, player, scale, body, hpfl, uid)| {
|(entity, pos, interpolated, stats, energy, scale, body, hpfl, uid)| {
// Use interpolated position if available
let pos = interpolated.map_or(pos.0, |i| i.pos);
let in_group = client.group_members().contains_key(uid);
@ -1110,7 +1110,7 @@ impl Hud {
let display_overhead_info =
(info.target_entity.map_or(false, |e| e == entity)
|| info.selected_entity.map_or(false, |s| s.0 == entity)
|| stats.health.current() != stats.health.maximum()
|| overhead::show_healthbar(stats)
|| in_group)
&& dist_sqr
< (if in_group {
@ -1125,50 +1125,31 @@ impl Hud {
})
.powi(2);
let info = display_overhead_info.then(|| {
// TODO: This is temporary
// If the player used the default character name display their name
// instead
let name = if stats.name == "Character Name" {
player.map_or(&stats.name, |p| &p.alias)
} else {
&stats.name
};
overhead::Info {
name,
stats,
energy,
}
let info = display_overhead_info.then(|| overhead::Info {
name: &stats.name,
stats,
energy,
});
let display_bubble = dist_sqr < SPEECH_BUBBLE_RANGE.powi(2);
let bubble = if dist_sqr < SPEECH_BUBBLE_RANGE.powi(2) {
speech_bubbles.get(uid)
} else {
None
};
(info.is_some() || display_bubble).then(|| {
(info.is_some() || bubble.is_some()).then(|| {
(
pos,
info,
display_bubble,
bubble,
stats,
body.height() * scale.map_or(1.0, |s| s.0) + 0.5,
hpfl,
uid,
in_group,
)
})
},
)
{
let bubble = if display_bubble {
self.speech_bubbles.get(uid)
} else {
None
};
// Skip if no bubble and doesn't meet the criteria to display nametag
if bubble.is_none() && info.is_none() {
continue;
}
let overhead_id = overhead_walker.next(
&mut self.ids.overheads,
&mut ui_widgets.widget_id_generator(),

View File

@ -54,6 +54,9 @@ pub struct Info<'a> {
pub energy: Option<&'a Energy>,
}
/// Determines whether to show the healthbar
pub fn show_healthbar(stats: &Stats) -> bool { stats.health.current() != stats.health.maximum() }
/// ui widget containing everything that goes over a character's head
/// (Speech bubble, Name, Level, HP/energy bars, etc.)
#[derive(WidgetCommon)]
@ -122,9 +125,7 @@ impl<'a> Ingameable for Overhead<'a> {
// - 1 Image::new for icon
// - 10 Image::new for speech bubble (9-slice + tail)
self.info.map_or(0, |info| {
2 + if f64::from(info.stats.health.current()) / f64::from(info.stats.health.maximum())
< 1.0
{
2 + if show_healthbar(info.stats) {
5 + if info.energy.is_some() { 1 } else { 0 }
} else {
0
@ -206,7 +207,7 @@ impl<'a> Widget for Overhead<'a> {
.parent(id)
.set(state.ids.name, ui);
if hp_percentage < 100.0 {
if show_healthbar(stats) {
// Show HP Bar
let hp_ani = (self.pulse * 4.0/* speed factor */).cos() * 0.5 + 1.0; //Animation timer
let crit_hp_color: Color = Color::Rgba(0.79, 0.19, 0.17, hp_ani);