mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
overhead info improvements
overhead improvements
This commit is contained in:
parent
1eb671e1a6
commit
3da7e27a7c
@ -173,6 +173,7 @@ impl<'a> Widget for Group<'a> {
|
||||
let in_group = !group_members.is_empty();
|
||||
if !in_group {
|
||||
self.show.group_menu = false;
|
||||
self.show.group = false;
|
||||
}
|
||||
|
||||
// Helper
|
||||
@ -207,6 +208,7 @@ impl<'a> Widget for Group<'a> {
|
||||
// Frame
|
||||
Rectangle::fill_with([220.0, 165.0], color::Color::Rgba(0.0, 0.0, 0.0, 0.8))
|
||||
.bottom_left_with_margins_on(ui.window, 220.0, 10.0)
|
||||
.crop_kids()
|
||||
.set(state.ids.bg, ui);
|
||||
}
|
||||
if open_invite.is_some() {
|
||||
|
@ -42,6 +42,7 @@ widget_ids! {
|
||||
level_skull,
|
||||
health_bar,
|
||||
health_bar_bg,
|
||||
health_txt,
|
||||
mana_bar,
|
||||
health_bar_fg,
|
||||
}
|
||||
@ -62,6 +63,7 @@ pub struct Overhead<'a> {
|
||||
voxygen_i18n: &'a std::sync::Arc<VoxygenLocalization>,
|
||||
imgs: &'a Imgs,
|
||||
fonts: &'a ConrodVoxygenFonts,
|
||||
|
||||
#[conrod(common_builder)]
|
||||
common: widget::CommonBuilder,
|
||||
}
|
||||
@ -107,13 +109,20 @@ impl<'a> Ingameable for Overhead<'a> {
|
||||
// Number of conrod primitives contained in the overhead display. TODO maybe
|
||||
// this could be done automatically?
|
||||
// - 2 Text::new for name
|
||||
// If HP Info is shown + 6
|
||||
// - 1 for level: either Text or Image
|
||||
// - 4 for HP + mana + fg + bg
|
||||
// If there's a speech bubble
|
||||
// - 2 Text::new for speech bubble
|
||||
// - 1 for HP Text
|
||||
// If there's a speech bubble + 13
|
||||
// - 2 Text::new for speec8 bubble
|
||||
// - 1 Image::new for icon
|
||||
// - 10 Image::new for speech bubble (9-slice + tail)
|
||||
7 + if self.bubble.is_some() { 13 } else { 0 }
|
||||
2 + if self.bubble.is_some() { 13 } else { 0 }
|
||||
+ if (self.stats.health.current() as f64 / self.stats.health.maximum() as f64) < 1.0 {
|
||||
6
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,23 +146,32 @@ impl<'a> Widget for Overhead<'a> {
|
||||
const BARSIZE: f64 = 2.0;
|
||||
const MANA_BAR_HEIGHT: f64 = BARSIZE * 1.5;
|
||||
const MANA_BAR_Y: f64 = MANA_BAR_HEIGHT / 2.0;
|
||||
|
||||
let hp_percentage =
|
||||
self.stats.health.current() as f64 / self.stats.health.maximum() as f64 * 100.0;
|
||||
let name_y = if hp_percentage == 100.0 {
|
||||
MANA_BAR_Y + 10.0
|
||||
} else {
|
||||
MANA_BAR_Y + 32.0
|
||||
};
|
||||
let font_size = if hp_percentage == 100.0 { 24 } else { 20 };
|
||||
// Name
|
||||
Text::new(&self.name)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(30)
|
||||
.font_size(font_size)
|
||||
.color(Color::Rgba(0.0, 0.0, 0.0, 1.0))
|
||||
.x_y(-1.0, MANA_BAR_Y + 48.0)
|
||||
.x_y(-1.0, name_y)
|
||||
.parent(id)
|
||||
.set(state.ids.name_bg, ui);
|
||||
Text::new(&self.name)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(30)
|
||||
.font_size(font_size)
|
||||
.color(if self.in_group {
|
||||
GROUP_MEMBER
|
||||
} else {
|
||||
DEFAULT_NPC
|
||||
})
|
||||
.x_y(0.0, MANA_BAR_Y + 50.0)
|
||||
.x_y(0.0, name_y + 1.0)
|
||||
.parent(id)
|
||||
.set(state.ids.name, ui);
|
||||
|
||||
// Speech bubble
|
||||
@ -167,7 +185,7 @@ impl<'a> Widget for Overhead<'a> {
|
||||
.color(text_color)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(18)
|
||||
.up_from(state.ids.name, 20.0)
|
||||
.up_from(state.ids.name, 26.0)
|
||||
.x_align_to(state.ids.name, Align::Middle)
|
||||
.parent(id);
|
||||
|
||||
@ -302,101 +320,121 @@ impl<'a> Widget for Overhead<'a> {
|
||||
.set(state.ids.speech_bubble_icon, ui);
|
||||
}
|
||||
|
||||
let hp_percentage =
|
||||
self.stats.health.current() as f64 / self.stats.health.maximum() as f64 * 100.0;
|
||||
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);
|
||||
if hp_percentage < 100.0 {
|
||||
// Show HP Bar
|
||||
let hp_percentage =
|
||||
self.stats.health.current() as f64 / self.stats.health.maximum() as f64 * 100.0;
|
||||
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);
|
||||
|
||||
// Background
|
||||
Image::new(self.imgs.enemy_health_bg)
|
||||
// Background
|
||||
Image::new(self.imgs.enemy_health_bg)
|
||||
.w_h(84.0 * BARSIZE, 10.0 * BARSIZE)
|
||||
.x_y(0.0, MANA_BAR_Y + 6.5) //-25.5)
|
||||
.color(Some(Color::Rgba(0.1, 0.1, 0.1, 0.8)))
|
||||
.parent(id)
|
||||
.set(state.ids.health_bar_bg, ui);
|
||||
|
||||
// % HP Filling
|
||||
Image::new(self.imgs.enemy_bar)
|
||||
.w_h(73.0 * (hp_percentage / 100.0) * BARSIZE, 6.0 * BARSIZE)
|
||||
.x_y(
|
||||
(4.5 + (hp_percentage / 100.0 * 36.45 - 36.45)) * BARSIZE,
|
||||
MANA_BAR_Y + 7.5,
|
||||
)
|
||||
.color(Some(if hp_percentage <= 25.0 {
|
||||
crit_hp_color
|
||||
} else if hp_percentage <= 50.0 {
|
||||
LOW_HP_COLOR
|
||||
} else {
|
||||
HP_COLOR
|
||||
}))
|
||||
.parent(id)
|
||||
.set(state.ids.health_bar, ui);
|
||||
// % HP Filling
|
||||
Image::new(self.imgs.enemy_bar)
|
||||
.w_h(73.0 * (hp_percentage / 100.0) * BARSIZE, 6.0 * BARSIZE)
|
||||
.x_y(
|
||||
(4.5 + (hp_percentage / 100.0 * 36.45 - 36.45)) * BARSIZE,
|
||||
MANA_BAR_Y + 7.5,
|
||||
)
|
||||
.color(Some(if hp_percentage <= 25.0 {
|
||||
crit_hp_color
|
||||
} else if hp_percentage <= 50.0 {
|
||||
LOW_HP_COLOR
|
||||
} else {
|
||||
HP_COLOR
|
||||
}))
|
||||
.parent(id)
|
||||
.set(state.ids.health_bar, ui);
|
||||
// TODO Only show health values for entities below 100% health
|
||||
let mut txt = format!(
|
||||
"{}/{}",
|
||||
self.stats.health.current().max(1) / 10 as u32, /* Don't show 0 health for
|
||||
* living entities */
|
||||
self.stats.health.maximum() / 10 as u32,
|
||||
);
|
||||
if self.stats.is_dead {
|
||||
txt = self.voxygen_i18n.get("hud.group.dead").to_string()
|
||||
};
|
||||
Text::new(&txt)
|
||||
.mid_top_with_margin_on(state.ids.health_bar_bg, 2.0)
|
||||
.font_size(10)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(TEXT_COLOR)
|
||||
.parent(id)
|
||||
.set(state.ids.health_txt, ui);
|
||||
|
||||
// % Mana Filling
|
||||
if let Some(energy) = self.energy {
|
||||
let energy_factor = energy.current() as f64 / energy.maximum() as f64;
|
||||
// % Mana Filling
|
||||
if let Some(energy) = self.energy {
|
||||
let energy_factor = energy.current() as f64 / energy.maximum() as f64;
|
||||
|
||||
Rectangle::fill_with(
|
||||
[72.0 * energy_factor * BARSIZE, MANA_BAR_HEIGHT],
|
||||
MANA_COLOR,
|
||||
)
|
||||
.x_y(
|
||||
((3.5 + (energy_factor * 36.5)) - 36.45) * BARSIZE,
|
||||
MANA_BAR_Y, //-32.0,
|
||||
)
|
||||
.parent(id)
|
||||
.set(state.ids.mana_bar, ui);
|
||||
}
|
||||
Rectangle::fill_with(
|
||||
[72.0 * energy_factor * BARSIZE, MANA_BAR_HEIGHT],
|
||||
MANA_COLOR,
|
||||
)
|
||||
.x_y(
|
||||
((3.5 + (energy_factor * 36.5)) - 36.45) * BARSIZE,
|
||||
MANA_BAR_Y, //-32.0,
|
||||
)
|
||||
.parent(id)
|
||||
.set(state.ids.mana_bar, ui);
|
||||
}
|
||||
|
||||
// Foreground
|
||||
Image::new(self.imgs.enemy_health)
|
||||
// Foreground
|
||||
Image::new(self.imgs.enemy_health)
|
||||
.w_h(84.0 * BARSIZE, 10.0 * BARSIZE)
|
||||
.x_y(0.0, MANA_BAR_Y + 6.5) //-25.5)
|
||||
.color(Some(Color::Rgba(1.0, 1.0, 1.0, 0.99)))
|
||||
.parent(id)
|
||||
.set(state.ids.health_bar_fg, ui);
|
||||
|
||||
// Level
|
||||
const LOW: Color = Color::Rgba(0.54, 0.81, 0.94, 0.4);
|
||||
const HIGH: Color = Color::Rgba(1.0, 0.0, 0.0, 1.0);
|
||||
const EQUAL: Color = Color::Rgba(1.0, 1.0, 1.0, 1.0);
|
||||
// Change visuals of the level display depending on the player level/opponent
|
||||
// level
|
||||
let level_comp = self.stats.level.level() as i64 - self.own_level as i64;
|
||||
// + 10 level above player -> skull
|
||||
// + 5-10 levels above player -> high
|
||||
// -5 - +5 levels around player level -> equal
|
||||
// - 5 levels below player -> low
|
||||
if level_comp > 9 {
|
||||
let skull_ani = ((self.pulse * 0.7/* speed factor */).cos() * 0.5 + 0.5) * 10.0; //Animation timer
|
||||
Image::new(if skull_ani as i32 == 1 && rand::random::<f32>() < 0.9 {
|
||||
self.imgs.skull_2
|
||||
} else {
|
||||
self.imgs.skull
|
||||
})
|
||||
.w_h(18.0 * BARSIZE, 18.0 * BARSIZE)
|
||||
.x_y(-39.0 * BARSIZE, MANA_BAR_Y + 7.0)
|
||||
.color(Some(Color::Rgba(1.0, 1.0, 1.0, 1.0)))
|
||||
.parent(id)
|
||||
.set(state.ids.level_skull, ui);
|
||||
} else {
|
||||
Text::new(&format!("{}", self.stats.level.level()))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(if self.stats.level.level() > 9 && level_comp < 10 {
|
||||
14
|
||||
// Level
|
||||
const LOW: Color = Color::Rgba(0.54, 0.81, 0.94, 0.4);
|
||||
const HIGH: Color = Color::Rgba(1.0, 0.0, 0.0, 1.0);
|
||||
const EQUAL: Color = Color::Rgba(1.0, 1.0, 1.0, 1.0);
|
||||
// Change visuals of the level display depending on the player level/opponent
|
||||
// level
|
||||
let level_comp = self.stats.level.level() as i64 - self.own_level as i64;
|
||||
// + 10 level above player -> skull
|
||||
// + 5-10 levels above player -> high
|
||||
// -5 - +5 levels around player level -> equal
|
||||
// - 5 levels below player -> low
|
||||
if level_comp > 9 {
|
||||
let skull_ani = ((self.pulse * 0.7/* speed factor */).cos() * 0.5 + 0.5) * 10.0; //Animation timer
|
||||
Image::new(if skull_ani as i32 == 1 && rand::random::<f32>() < 0.9 {
|
||||
self.imgs.skull_2
|
||||
} else {
|
||||
15
|
||||
self.imgs.skull
|
||||
})
|
||||
.color(if level_comp > 4 {
|
||||
HIGH
|
||||
} else if level_comp < -5 {
|
||||
LOW
|
||||
} else {
|
||||
EQUAL
|
||||
})
|
||||
.x_y(-37.0 * BARSIZE, MANA_BAR_Y + 9.0)
|
||||
.w_h(18.0 * BARSIZE, 18.0 * BARSIZE)
|
||||
.x_y(-39.0 * BARSIZE, MANA_BAR_Y + 7.0)
|
||||
.color(Some(Color::Rgba(1.0, 1.0, 1.0, 1.0)))
|
||||
.parent(id)
|
||||
.set(state.ids.level, ui);
|
||||
.set(state.ids.level_skull, ui);
|
||||
} else {
|
||||
Text::new(&format!("{}", self.stats.level.level()))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(if self.stats.level.level() > 9 && level_comp < 10 {
|
||||
14
|
||||
} else {
|
||||
15
|
||||
})
|
||||
.color(if level_comp > 4 {
|
||||
HIGH
|
||||
} else if level_comp < -5 {
|
||||
LOW
|
||||
} else {
|
||||
EQUAL
|
||||
})
|
||||
.x_y(-37.0 * BARSIZE, MANA_BAR_Y + 9.0)
|
||||
.parent(id)
|
||||
.set(state.ids.level, ui);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -219,10 +219,14 @@ impl<'a> Widget for Skillbar<'a> {
|
||||
|
||||
let exp_percentage = (self.stats.exp.current() as f64) / (self.stats.exp.maximum() as f64);
|
||||
|
||||
let hp_percentage =
|
||||
let mut hp_percentage =
|
||||
self.stats.health.current() as f64 / self.stats.health.maximum() as f64 * 100.0;
|
||||
let energy_percentage = self.energy.current() as f64 / self.energy.maximum() as f64 * 100.0;
|
||||
|
||||
let mut energy_percentage =
|
||||
self.energy.current() as f64 / self.energy.maximum() as f64 * 100.0;
|
||||
if self.stats.is_dead {
|
||||
hp_percentage = 0.0;
|
||||
energy_percentage = 0.0;
|
||||
};
|
||||
let scale = 2.0;
|
||||
|
||||
let bar_values = self.global_state.settings.gameplay.bar_numbers;
|
||||
@ -1160,14 +1164,14 @@ impl<'a> Widget for Skillbar<'a> {
|
||||
};
|
||||
Image::new(self.imgs.bar_content)
|
||||
.w_h(97.0 * scale * hp_percentage / 100.0, 16.0 * scale)
|
||||
.color(Some(health_col))
|
||||
.color(Some(health_col))
|
||||
.top_right_with_margins_on(state.ids.healthbar_bg, 2.0 * scale, 1.0 * scale)
|
||||
.set(state.ids.healthbar_filling, ui);
|
||||
// Energybar
|
||||
Image::new(self.imgs.energybar_bg)
|
||||
.w_h(100.0 * scale, 20.0 * scale)
|
||||
.top_right_with_margins_on(state.ids.m2_slot, 0.0, -100.0 * scale)
|
||||
.set(state.ids.energybar_bg, ui);
|
||||
.set(state.ids.energybar_bg, ui);
|
||||
Image::new(self.imgs.bar_content)
|
||||
.w_h(97.0 * scale * energy_percentage / 100.0, 16.0 * scale)
|
||||
.top_left_with_margins_on(state.ids.energybar_bg, 2.0 * scale, 1.0 * scale)
|
||||
@ -1180,11 +1184,21 @@ impl<'a> Widget for Skillbar<'a> {
|
||||
// Bar Text
|
||||
// Values
|
||||
if let BarNumbers::Values = bar_values {
|
||||
let hp_text = format!(
|
||||
let mut hp_text = format!(
|
||||
"{}/{}",
|
||||
(self.stats.health.current() / 10) as u32,
|
||||
(self.stats.health.current() / 10).max(1) as u32, // Don't show 0 health for living players
|
||||
(self.stats.health.maximum() / 10) as u32
|
||||
);
|
||||
let mut energy_text = format!(
|
||||
"{}/{}",
|
||||
self.energy.current() as u32 / 10, /* TODO Fix regeneration with smaller energy
|
||||
* numbers instead of dividing by 10 here */
|
||||
self.energy.maximum() as u32 / 10
|
||||
);
|
||||
if self.stats.is_dead {
|
||||
hp_text = self.localized_strings.get("hud.group.dead").to_string();
|
||||
energy_text = self.localized_strings.get("hud.group.dead").to_string();
|
||||
};
|
||||
Text::new(&hp_text)
|
||||
.mid_top_with_margin_on(state.ids.healthbar_bg, 6.0 * scale)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
@ -1196,13 +1210,7 @@ impl<'a> Widget for Skillbar<'a> {
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.health_text, ui);
|
||||
let energy_text = format!(
|
||||
"{}/{}",
|
||||
self.energy.current() as u32 / 10, /* TODO Fix regeneration with smaller energy
|
||||
* numbers instead of dividing by 10 here */
|
||||
self.energy.maximum() as u32 / 10
|
||||
);
|
||||
.set(state.ids.health_text, ui);
|
||||
Text::new(&energy_text)
|
||||
.mid_top_with_margin_on(state.ids.energybar_bg, 6.0 * scale)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
|
@ -262,15 +262,15 @@ impl<'a> Widget for Social<'a> {
|
||||
.mid_top_with_margin_on(state.ids.frame, 74.0)
|
||||
.scroll_kids_vertically()
|
||||
.set(state.ids.online_align, ui);
|
||||
Rectangle::fill_with([133.0, 370.0], color::TRANSPARENT)
|
||||
Rectangle::fill_with([133.0, 346.0], color::TRANSPARENT)
|
||||
.top_left_with_margins_on(state.ids.online_align, 0.0, 0.0)
|
||||
.crop_kids()
|
||||
.set(state.ids.names_align, ui);
|
||||
Rectangle::fill_with([39.0, 370.0], color::TRANSPARENT)
|
||||
Rectangle::fill_with([39.0, 346.0], color::TRANSPARENT)
|
||||
.right_from(state.ids.names_align, 2.0)
|
||||
.crop_kids()
|
||||
.set(state.ids.levels_align, ui);
|
||||
Rectangle::fill_with([94.0, 370.0], color::TRANSPARENT)
|
||||
Rectangle::fill_with([94.0, 346.0], color::TRANSPARENT)
|
||||
.right_from(state.ids.levels_align, 2.0)
|
||||
.crop_kids()
|
||||
.set(state.ids.zones_align, ui);
|
||||
@ -423,9 +423,9 @@ impl<'a> Widget for Social<'a> {
|
||||
.was_clicked()
|
||||
{};
|
||||
let level_txt = if i == 0 {
|
||||
Text::new(&level).mid_top_with_margin_on(state.ids.levels_align, 2.0)
|
||||
Text::new(&level).mid_top_with_margin_on(state.ids.levels_align, 4.0)
|
||||
} else {
|
||||
Text::new(&level).down_from(state.ids.player_levels[i - 1], 2.0)
|
||||
Text::new(&level).down_from(state.ids.player_levels[i - 1], 4.0)
|
||||
};
|
||||
level_txt
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
@ -433,9 +433,9 @@ impl<'a> Widget for Social<'a> {
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.player_levels[i], ui);
|
||||
let zone_txt = if i == 0 {
|
||||
Text::new(&zone_name).mid_top_with_margin_on(state.ids.zones_align, 2.0)
|
||||
Text::new(&zone_name).mid_top_with_margin_on(state.ids.zones_align, 4.0)
|
||||
} else {
|
||||
Text::new(&zone_name).down_from(state.ids.player_zones[i - 1], 2.0)
|
||||
Text::new(&zone_name).down_from(state.ids.player_zones[i - 1], 4.0)
|
||||
};
|
||||
zone_txt
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
|
Loading…
Reference in New Issue
Block a user