Refactor to avoid changing overhead struct

This commit is contained in:
voxal
2022-01-01 20:21:17 -08:00
parent 39e3d5c163
commit e75f569014
2 changed files with 365 additions and 374 deletions

View File

@ -1777,7 +1777,7 @@ impl Hud {
let speech_bubbles = &self.speech_bubbles; let speech_bubbles = &self.speech_bubbles;
// Render overhead name tags and health bars // Render overhead name tags and health bars
for (pos, info, bubble, _, _, health, _, height_offset, hpfl, in_group, is_me) in ( for (pos, info, bubble, _, _, health, _, height_offset, hpfl, in_group) in (
&entities, &entities,
&pos, &pos,
interpolated.maybe(), interpolated.maybe(),
@ -1835,7 +1835,8 @@ impl Hud {
|| info.selected_entity.map_or(false, |s| s.0 == entity) || info.selected_entity.map_or(false, |s| s.0 == entity)
|| health.map_or(true, overhead::should_show_healthbar) || health.map_or(true, overhead::should_show_healthbar)
|| in_group || in_group
|| is_merchant) || is_merchant
|| !is_me)
&& dist_sqr && dist_sqr
< (if in_group { < (if in_group {
NAMETAG_GROUP_RANGE NAMETAG_GROUP_RANGE
@ -1866,7 +1867,9 @@ impl Hud {
0.0 0.0
}, },
}); });
let bubble = if dist_sqr < SPEECH_BUBBLE_RANGE.powi(2) { let bubble = if (dist_sqr < SPEECH_BUBBLE_RANGE.powi(2) && !is_me)
|| (is_me && global_state.settings.interface.speech_bubble_self)
{
speech_bubbles.get(uid) speech_bubbles.get(uid)
} else { } else {
None None
@ -1884,7 +1887,6 @@ impl Hud {
body.height() * scale.map_or(1.0, |s| s.0) + 0.5, body.height() * scale.map_or(1.0, |s| s.0) + 0.5,
hpfl, hpfl,
in_group, in_group,
is_me,
) )
}) })
}, },
@ -1904,7 +1906,6 @@ impl Hud {
info, info,
bubble, bubble,
in_group, in_group,
is_me,
&global_state.settings.interface, &global_state.settings.interface,
self.pulse, self.pulse,
i18n, i18n,

View File

@ -81,7 +81,6 @@ pub struct Overhead<'a> {
info: Option<Info<'a>>, info: Option<Info<'a>>,
bubble: Option<&'a SpeechBubble>, bubble: Option<&'a SpeechBubble>,
in_group: bool, in_group: bool,
is_me: bool,
settings: &'a InterfaceSettings, settings: &'a InterfaceSettings,
pulse: f32, pulse: f32,
i18n: &'a Localization, i18n: &'a Localization,
@ -97,7 +96,6 @@ impl<'a> Overhead<'a> {
info: Option<Info<'a>>, info: Option<Info<'a>>,
bubble: Option<&'a SpeechBubble>, bubble: Option<&'a SpeechBubble>,
in_group: bool, in_group: bool,
is_me: bool,
settings: &'a InterfaceSettings, settings: &'a InterfaceSettings,
pulse: f32, pulse: f32,
i18n: &'a Localization, i18n: &'a Localization,
@ -108,7 +106,6 @@ impl<'a> Overhead<'a> {
info, info,
bubble, bubble,
in_group, in_group,
is_me,
settings, settings,
pulse, pulse,
i18n, i18n,
@ -183,118 +180,115 @@ impl<'a> Widget for Overhead<'a> {
const MANA_BAR_HEIGHT: f64 = BARSIZE * 1.5; const MANA_BAR_HEIGHT: f64 = BARSIZE * 1.5;
const MANA_BAR_Y: f64 = MANA_BAR_HEIGHT / 2.0; const MANA_BAR_Y: f64 = MANA_BAR_HEIGHT / 2.0;
// Only render info if not me // Only render info if not me
if !self.is_me { if let Some(Info {
if let Some(Info { name,
name, health,
health, buffs,
buffs, energy,
energy, combat_rating,
combat_rating, }) = self.info
}) = self.info {
{ // Used to set healthbar colours based on hp_percentage
// Used to set healthbar colours based on hp_percentage let hp_percentage = health.map_or(100.0, |h| {
let hp_percentage = health.map_or(100.0, |h| { f64::from(h.current() / h.base_max().max(h.maximum()) * 100.0)
f64::from(h.current() / h.base_max().max(h.maximum()) * 100.0) });
}); // Compare levels to decide if a skull is shown
// Compare levels to decide if a skull is shown let health_current = health.map_or(1.0, |h| f64::from(h.current()));
let health_current = health.map_or(1.0, |h| f64::from(h.current())); let health_max = health.map_or(1.0, |h| f64::from(h.maximum()));
let health_max = health.map_or(1.0, |h| f64::from(h.maximum())); let name_y = if (health_current - health_max).abs() < 1e-6 {
let name_y = if (health_current - health_max).abs() < 1e-6 { MANA_BAR_Y + 20.0
MANA_BAR_Y + 20.0 } else {
} else { MANA_BAR_Y + 32.0
MANA_BAR_Y + 32.0 };
}; 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 let health_cur_txt = match health_current as u32 {
let health_cur_txt = match health_current as u32 { 0..=999 => format!("{:.0}", health_current.max(1.0)),
0..=999 => format!("{:.0}", health_current.max(1.0)), 1000..=999999 => format!("{:.0}K", (health_current / 1000.0).max(1.0)),
1000..=999999 => format!("{:.0}K", (health_current / 1000.0).max(1.0)), _ => format!("{:.0}M", (health_current as f64 / 1.0e6).max(1.0)),
_ => format!("{:.0}M", (health_current as f64 / 1.0e6).max(1.0)), };
}; let health_max_txt = match health_max as u32 {
let health_max_txt = match health_max as u32 { 0..=999 => format!("{:.0}", health_max.max(1.0)),
0..=999 => format!("{:.0}", health_max.max(1.0)), 1000..=999999 => format!("{:.0}K", (health_max / 1000.0).max(1.0)),
1000..=999999 => format!("{:.0}K", (health_max / 1000.0).max(1.0)), _ => format!("{:.0}M", (health_max as f64 / 1.0e6).max(1.0)),
_ => format!("{:.0}M", (health_max as f64 / 1.0e6).max(1.0)), };
}; // Buffs
// Buffs // Alignment
// Alignment let buff_count = buffs.kinds.len().min(11);
let buff_count = buffs.kinds.len().min(11); Rectangle::fill_with([168.0, 100.0], color::TRANSPARENT)
Rectangle::fill_with([168.0, 100.0], color::TRANSPARENT) .x_y(-1.0, name_y + 60.0)
.x_y(-1.0, name_y + 60.0) .parent(id)
.parent(id) .set(state.ids.buffs_align, ui);
.set(state.ids.buffs_align, ui);
let gen = &mut ui.widget_id_generator(); let gen = &mut ui.widget_id_generator();
if state.ids.buffs.len() < buff_count { if state.ids.buffs.len() < buff_count {
state.update(|state| state.ids.buffs.resize(buff_count, gen)); state.update(|state| state.ids.buffs.resize(buff_count, gen));
}; };
if state.ids.buff_timers.len() < buff_count { if state.ids.buff_timers.len() < buff_count {
state.update(|state| state.ids.buff_timers.resize(buff_count, gen)); state.update(|state| state.ids.buff_timers.resize(buff_count, gen));
}; };
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
if self.bubble.is_none() { if self.bubble.is_none() {
state state
.ids .ids
.buffs .buffs
.iter() .iter()
.copied() .copied()
.zip(state.ids.buff_timers.iter().copied()) .zip(state.ids.buff_timers.iter().copied())
.zip(buffs.iter_active().map(get_buff_info)) .zip(buffs.iter_active().map(get_buff_info))
.enumerate() .enumerate()
.for_each(|(i, ((id, timer_id), buff))| { .for_each(|(i, ((id, timer_id), buff))| {
// Limit displayed buffs // Limit displayed buffs
let max_duration = buff.data.duration; let max_duration = buff.data.duration;
let current_duration = buff.dur; let current_duration = buff.dur;
let duration_percentage = current_duration.map_or(1000.0, |cur| { let duration_percentage = current_duration.map_or(1000.0, |cur| {
max_duration.map_or(1000.0, |max| { max_duration.map_or(1000.0, |max| {
cur.as_secs_f32() / max.as_secs_f32() * 1000.0 cur.as_secs_f32() / max.as_secs_f32() * 1000.0
})
}) as u32; // Percentage to determine which frame of the timer overlay is displayed
let buff_img = get_buff_image(buff.kind, self.imgs);
let buff_widget = Image::new(buff_img).w_h(20.0, 20.0);
// Sort buffs into rows of 5 slots
let x = i % 5;
let y = i / 5;
let buff_widget = buff_widget.bottom_left_with_margins_on(
state.ids.buffs_align,
0.0 + y as f64 * (21.0),
0.0 + x as f64 * (21.0),
);
buff_widget
.color(
if current_duration
.map_or(false, |cur| cur.as_secs_f32() < 10.0)
{
Some(pulsating_col)
} else {
Some(norm_col)
},
)
.set(id, ui);
Image::new(match duration_percentage as u64 {
875..=1000 => self.imgs.nothing, // 8/8
750..=874 => self.imgs.buff_0, // 7/8
625..=749 => self.imgs.buff_1, // 6/8
500..=624 => self.imgs.buff_2, // 5/8
375..=499 => self.imgs.buff_3, // 4/8
250..=374 => self.imgs.buff_4, // 3/8
125..=249 => self.imgs.buff_5, // 2/8
0..=124 => self.imgs.buff_6, // 1/8
_ => self.imgs.nothing,
}) })
.w_h(20.0, 20.0) }) as u32; // Percentage to determine which frame of the timer overlay is displayed
.middle_of(id) let buff_img = get_buff_image(buff.kind, self.imgs);
.set(timer_id, ui); let buff_widget = Image::new(buff_img).w_h(20.0, 20.0);
}); // Sort buffs into rows of 5 slots
} let x = i % 5;
// Name let y = i / 5;
Text::new(name) let buff_widget = buff_widget.bottom_left_with_margins_on(
state.ids.buffs_align,
0.0 + y as f64 * (21.0),
0.0 + x as f64 * (21.0),
);
buff_widget
.color(
if current_duration.map_or(false, |cur| cur.as_secs_f32() < 10.0) {
Some(pulsating_col)
} else {
Some(norm_col)
},
)
.set(id, ui);
Image::new(match duration_percentage as u64 {
875..=1000 => self.imgs.nothing, // 8/8
750..=874 => self.imgs.buff_0, // 7/8
625..=749 => self.imgs.buff_1, // 6/8
500..=624 => self.imgs.buff_2, // 5/8
375..=499 => self.imgs.buff_3, // 4/8
250..=374 => self.imgs.buff_4, // 3/8
125..=249 => self.imgs.buff_5, // 2/8
0..=124 => self.imgs.buff_6, // 1/8
_ => self.imgs.nothing,
})
.w_h(20.0, 20.0)
.middle_of(id)
.set(timer_id, ui);
});
}
// Name
Text::new(name)
//Text::new(&format!("{} [{:?}]", name, combat_rating)) // <- Uncomment to debug combat ratings //Text::new(&format!("{} [{:?}]", name, combat_rating)) // <- Uncomment to debug combat ratings
.font_id(self.fonts.cyri.conrod_id) .font_id(self.fonts.cyri.conrod_id)
.font_size(font_size) .font_size(font_size)
@ -302,7 +296,7 @@ impl<'a> Widget for Overhead<'a> {
.x_y(-1.0, name_y) .x_y(-1.0, name_y)
.parent(id) .parent(id)
.set(state.ids.name_bg, ui); .set(state.ids.name_bg, ui);
Text::new(name) Text::new(name)
//Text::new(&format!("{} [{:?}]", name, combat_rating)) // <- Uncomment to debug combat ratings //Text::new(&format!("{} [{:?}]", name, combat_rating)) // <- Uncomment to debug combat ratings
.font_id(self.fonts.cyri.conrod_id) .font_id(self.fonts.cyri.conrod_id)
.font_size(font_size) .font_size(font_size)
@ -317,296 +311,292 @@ impl<'a> Widget for Overhead<'a> {
.parent(id) .parent(id)
.set(state.ids.name, ui); .set(state.ids.name, ui);
match health { match health {
Some(health) Some(health)
if should_show_healthbar(health) || decayed_health_displayed(health) => if should_show_healthbar(health) || decayed_health_displayed(health) =>
{ {
// Show HP Bar // Show HP Bar
let hp_ani = (self.pulse * 4.0/* speed factor */).cos() * 0.5 + 1.0; //Animation timer let hp_ani = (self.pulse * 4.0/* speed factor */).cos() * 0.5 + 1.0; //Animation timer
let crit_hp_color: Color = Color::Rgba(0.93, 0.59, 0.03, hp_ani); let crit_hp_color: Color = Color::Rgba(0.93, 0.59, 0.03, hp_ani);
let decayed_health = f64::from(1.0 - health.maximum() / health.base_max()); let decayed_health = f64::from(1.0 - health.maximum() / health.base_max());
// Background // Background
Image::new(if self.in_group {self.imgs.health_bar_group_bg} else {self.imgs.enemy_health_bg}) Image::new(if self.in_group {self.imgs.health_bar_group_bg} else {self.imgs.enemy_health_bg})
.w_h(84.0 * BARSIZE, 10.0 * BARSIZE) .w_h(84.0 * BARSIZE, 10.0 * BARSIZE)
.x_y(0.0, MANA_BAR_Y + 6.5) //-25.5) .x_y(0.0, MANA_BAR_Y + 6.5) //-25.5)
.color(Some(Color::Rgba(0.1, 0.1, 0.1, 0.8))) .color(Some(Color::Rgba(0.1, 0.1, 0.1, 0.8)))
.parent(id) .parent(id)
.set(state.ids.health_bar_bg, ui); .set(state.ids.health_bar_bg, ui);
// % HP Filling // % HP Filling
let size_factor = (hp_percentage / 100.0) * BARSIZE; let size_factor = (hp_percentage / 100.0) * BARSIZE;
let w = if self.in_group { let w = if self.in_group {
82.0 * size_factor 82.0 * size_factor
} else { } else {
73.0 * size_factor 73.0 * size_factor
}; };
let h = 6.0 * BARSIZE; let h = 6.0 * BARSIZE;
let x = if self.in_group { let x = if self.in_group {
(0.0 + (hp_percentage / 100.0 * 41.0 - 41.0)) * BARSIZE (0.0 + (hp_percentage / 100.0 * 41.0 - 41.0)) * BARSIZE
} else { } else {
(4.5 + (hp_percentage / 100.0 * 36.45 - 36.45)) * BARSIZE (4.5 + (hp_percentage / 100.0 * 36.45 - 36.45)) * BARSIZE
}; };
Image::new(self.imgs.enemy_bar) Image::new(self.imgs.enemy_bar)
.w_h(w, h) .w_h(w, h)
.x_y(x, MANA_BAR_Y + 8.0) .x_y(x, MANA_BAR_Y + 8.0)
.color(if self.in_group { .color(if self.in_group {
// Different HP bar colors only for group members // Different HP bar colors only for group members
Some(match hp_percentage { Some(match hp_percentage {
x if (0.0..25.0).contains(&x) => crit_hp_color, x if (0.0..25.0).contains(&x) => crit_hp_color,
x if (25.0..50.0).contains(&x) => LOW_HP_COLOR, x if (25.0..50.0).contains(&x) => LOW_HP_COLOR,
_ => HP_COLOR, _ => HP_COLOR,
})
} else {
Some(ENEMY_HP_COLOR)
}) })
.parent(id) } else {
.set(state.ids.health_bar, ui); Some(ENEMY_HP_COLOR)
})
.parent(id)
.set(state.ids.health_bar, ui);
if decayed_health > 0.0 { if decayed_health > 0.0 {
let x_decayed = if self.in_group { let x_decayed = if self.in_group {
(0.0 - (decayed_health * 41.0 - 41.0)) * BARSIZE (0.0 - (decayed_health * 41.0 - 41.0)) * BARSIZE
} else { } else {
(4.5 - (decayed_health * 36.45 - 36.45)) * BARSIZE (4.5 - (decayed_health * 36.45 - 36.45)) * BARSIZE
};
let decay_bar_len = decayed_health
* if self.in_group {
82.0 * BARSIZE
} else {
73.0 * BARSIZE
};
Image::new(self.imgs.enemy_bar)
.w_h(decay_bar_len, h)
.x_y(x_decayed, MANA_BAR_Y + 8.0)
.color(Some(QUALITY_EPIC))
.parent(id)
.set(state.ids.decay_bar, ui);
}
let mut txt = format!("{}/{}", health_cur_txt, health_max_txt);
if health.is_dead {
txt = self.i18n.get("hud.group.dead").to_string()
}; };
Text::new(&txt)
.mid_top_with_margin_on(state.ids.health_bar_bg, 2.0) let decay_bar_len = decayed_health
.font_size(10) * if self.in_group {
.font_id(self.fonts.cyri.conrod_id) 82.0 * BARSIZE
.color(TEXT_COLOR) } else {
73.0 * BARSIZE
};
Image::new(self.imgs.enemy_bar)
.w_h(decay_bar_len, h)
.x_y(x_decayed, MANA_BAR_Y + 8.0)
.color(Some(QUALITY_EPIC))
.parent(id) .parent(id)
.set(state.ids.health_txt, ui); .set(state.ids.decay_bar, ui);
}
let mut txt = format!("{}/{}", health_cur_txt, health_max_txt);
if health.is_dead {
txt = self.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 // % Mana Filling
if let Some(energy) = energy { if let Some(energy) = energy {
let energy_factor = f64::from(energy.current() / energy.maximum()); let energy_factor = f64::from(energy.current() / energy.maximum());
let size_factor = energy_factor * BARSIZE; let size_factor = energy_factor * BARSIZE;
let w = if self.in_group { let w = if self.in_group {
80.0 * size_factor 80.0 * size_factor
} else { } else {
72.0 * size_factor 72.0 * size_factor
}; };
let x = if self.in_group { let x = if self.in_group {
((0.0 + (energy_factor * 40.0)) - 40.0) * BARSIZE ((0.0 + (energy_factor * 40.0)) - 40.0) * BARSIZE
} else { } else {
((3.5 + (energy_factor * 36.5)) - 36.45) * BARSIZE ((3.5 + (energy_factor * 36.5)) - 36.45) * BARSIZE
}; };
Rectangle::fill_with([w, MANA_BAR_HEIGHT], STAMINA_COLOR) Rectangle::fill_with([w, MANA_BAR_HEIGHT], STAMINA_COLOR)
.x_y( .x_y(
x, MANA_BAR_Y, //-32.0, x, MANA_BAR_Y, //-32.0,
) )
.parent(id) .parent(id)
.set(state.ids.mana_bar, ui); .set(state.ids.mana_bar, ui);
} }
// Foreground // Foreground
Image::new(if self.in_group {self.imgs.health_bar_group} else {self.imgs.enemy_health}) Image::new(if self.in_group {self.imgs.health_bar_group} else {self.imgs.enemy_health})
.w_h(84.0 * BARSIZE, 10.0 * BARSIZE) .w_h(84.0 * BARSIZE, 10.0 * BARSIZE)
.x_y(0.0, MANA_BAR_Y + 6.5) //-25.5) .x_y(0.0, MANA_BAR_Y + 6.5) //-25.5)
.color(Some(Color::Rgba(1.0, 1.0, 1.0, 0.99))) .color(Some(Color::Rgba(1.0, 1.0, 1.0, 0.99)))
.parent(id) .parent(id)
.set(state.ids.health_bar_fg, ui); .set(state.ids.health_bar_fg, ui);
let indicator_col = cr_color(combat_rating); let indicator_col = cr_color(combat_rating);
let artifact_diffculty = 122.0; let artifact_diffculty = 122.0;
if combat_rating > artifact_diffculty && !self.in_group { if combat_rating > artifact_diffculty && !self.in_group {
let skull_ani = let skull_ani =
((self.pulse * 0.7/* speed factor */).cos() * 0.5 + 0.5) * 10.0; //Animation timer ((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 { Image::new(if skull_ani as i32 == 1 && rand::random::<f32>() < 0.9 {
self.imgs.skull_2 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 { } else {
Image::new(if self.in_group { self.imgs.skull
self.imgs.nothing })
} else { .w_h(18.0 * BARSIZE, 18.0 * BARSIZE)
self.imgs.combat_rating_ico .x_y(-39.0 * BARSIZE, MANA_BAR_Y + 7.0)
}) .color(Some(Color::Rgba(1.0, 1.0, 1.0, 1.0)))
.w_h(7.0 * BARSIZE, 7.0 * BARSIZE) .parent(id)
.x_y(-37.0 * BARSIZE, MANA_BAR_Y + 6.0) .set(state.ids.level_skull, ui);
.color(Some(indicator_col)) } else {
.parent(id) Image::new(if self.in_group {
.set(state.ids.level, ui); self.imgs.nothing
} } else {
}, self.imgs.combat_rating_ico
_ => {}, })
} .w_h(7.0 * BARSIZE, 7.0 * BARSIZE)
.x_y(-37.0 * BARSIZE, MANA_BAR_Y + 6.0)
.color(Some(indicator_col))
.parent(id)
.set(state.ids.level, ui);
}
},
_ => {},
} }
} }
// Speech bubble // Speech bubble
// Only render if setting or other players // Only render if setting or other players
if !self.is_me || self.settings.speech_bubble_self { if let Some(bubble) = self.bubble {
if let Some(bubble) = self.bubble { let dark_mode = self.settings.speech_bubble_dark_mode;
let dark_mode = self.settings.speech_bubble_dark_mode; let localizer = |s: &str, i| -> String { self.i18n.get_variation(s, i).to_string() };
let localizer = let bubble_contents: String = bubble.message(localizer);
|s: &str, i| -> String { self.i18n.get_variation(s, i).to_string() }; let (text_color, shadow_color) = bubble_color(bubble, dark_mode);
let bubble_contents: String = bubble.message(localizer); let mut text = Text::new(&bubble_contents)
let (text_color, shadow_color) = bubble_color(bubble, dark_mode); .color(text_color)
let mut text = Text::new(&bubble_contents) .font_id(self.fonts.cyri.conrod_id)
.color(text_color) .font_size(18)
.font_id(self.fonts.cyri.conrod_id) .up_from(state.ids.name, 26.0)
.font_size(18) .x_align_to(state.ids.name, Align::Middle)
.up_from(state.ids.name, 26.0) .parent(id);
.x_align_to(state.ids.name, Align::Middle)
.parent(id);
if let Some(w) = text.get_w(ui) { if let Some(w) = text.get_w(ui) {
if w > MAX_BUBBLE_WIDTH { if w > MAX_BUBBLE_WIDTH {
text = text.w(MAX_BUBBLE_WIDTH); text = text.w(MAX_BUBBLE_WIDTH);
}
} }
Image::new(if dark_mode { }
self.imgs.dark_bubble_top_left Image::new(if dark_mode {
} else { self.imgs.dark_bubble_top_left
self.imgs.speech_bubble_top_left } else {
}) self.imgs.speech_bubble_top_left
.w_h(16.0, 16.0) })
.top_left_with_margin_on(state.ids.speech_bubble_text, -20.0) .w_h(16.0, 16.0)
.parent(id) .top_left_with_margin_on(state.ids.speech_bubble_text, -20.0)
.set(state.ids.speech_bubble_top_left, ui); .parent(id)
Image::new(if dark_mode { .set(state.ids.speech_bubble_top_left, ui);
self.imgs.dark_bubble_top Image::new(if dark_mode {
} else { self.imgs.dark_bubble_top
self.imgs.speech_bubble_top } else {
}) self.imgs.speech_bubble_top
.h(16.0) })
.padded_w_of(state.ids.speech_bubble_text, -4.0) .h(16.0)
.mid_top_with_margin_on(state.ids.speech_bubble_text, -20.0) .padded_w_of(state.ids.speech_bubble_text, -4.0)
.parent(id) .mid_top_with_margin_on(state.ids.speech_bubble_text, -20.0)
.set(state.ids.speech_bubble_top, ui); .parent(id)
Image::new(if dark_mode { .set(state.ids.speech_bubble_top, ui);
self.imgs.dark_bubble_top_right Image::new(if dark_mode {
} else { self.imgs.dark_bubble_top_right
self.imgs.speech_bubble_top_right } else {
}) self.imgs.speech_bubble_top_right
.w_h(16.0, 16.0) })
.top_right_with_margin_on(state.ids.speech_bubble_text, -20.0) .w_h(16.0, 16.0)
.parent(id) .top_right_with_margin_on(state.ids.speech_bubble_text, -20.0)
.set(state.ids.speech_bubble_top_right, ui); .parent(id)
Image::new(if dark_mode { .set(state.ids.speech_bubble_top_right, ui);
self.imgs.dark_bubble_left Image::new(if dark_mode {
} else { self.imgs.dark_bubble_left
self.imgs.speech_bubble_left } else {
}) self.imgs.speech_bubble_left
.w(16.0) })
.padded_h_of(state.ids.speech_bubble_text, -4.0) .w(16.0)
.mid_left_with_margin_on(state.ids.speech_bubble_text, -20.0) .padded_h_of(state.ids.speech_bubble_text, -4.0)
.parent(id) .mid_left_with_margin_on(state.ids.speech_bubble_text, -20.0)
.set(state.ids.speech_bubble_left, ui); .parent(id)
Image::new(if dark_mode { .set(state.ids.speech_bubble_left, ui);
self.imgs.dark_bubble_mid Image::new(if dark_mode {
} else { self.imgs.dark_bubble_mid
self.imgs.speech_bubble_mid } else {
}) self.imgs.speech_bubble_mid
.padded_wh_of(state.ids.speech_bubble_text, -4.0) })
.top_left_with_margin_on(state.ids.speech_bubble_text, -4.0) .padded_wh_of(state.ids.speech_bubble_text, -4.0)
.parent(id) .top_left_with_margin_on(state.ids.speech_bubble_text, -4.0)
.set(state.ids.speech_bubble_mid, ui); .parent(id)
Image::new(if dark_mode { .set(state.ids.speech_bubble_mid, ui);
self.imgs.dark_bubble_right Image::new(if dark_mode {
} else { self.imgs.dark_bubble_right
self.imgs.speech_bubble_right } else {
}) self.imgs.speech_bubble_right
.w(16.0) })
.padded_h_of(state.ids.speech_bubble_text, -4.0) .w(16.0)
.mid_right_with_margin_on(state.ids.speech_bubble_text, -20.0) .padded_h_of(state.ids.speech_bubble_text, -4.0)
.parent(id) .mid_right_with_margin_on(state.ids.speech_bubble_text, -20.0)
.set(state.ids.speech_bubble_right, ui); .parent(id)
Image::new(if dark_mode { .set(state.ids.speech_bubble_right, ui);
self.imgs.dark_bubble_bottom_left Image::new(if dark_mode {
} else { self.imgs.dark_bubble_bottom_left
self.imgs.speech_bubble_bottom_left } else {
}) self.imgs.speech_bubble_bottom_left
.w_h(16.0, 16.0) })
.bottom_left_with_margin_on(state.ids.speech_bubble_text, -20.0) .w_h(16.0, 16.0)
.parent(id) .bottom_left_with_margin_on(state.ids.speech_bubble_text, -20.0)
.set(state.ids.speech_bubble_bottom_left, ui); .parent(id)
Image::new(if dark_mode { .set(state.ids.speech_bubble_bottom_left, ui);
self.imgs.dark_bubble_bottom Image::new(if dark_mode {
} else { self.imgs.dark_bubble_bottom
self.imgs.speech_bubble_bottom } else {
}) self.imgs.speech_bubble_bottom
.h(16.0) })
.padded_w_of(state.ids.speech_bubble_text, -4.0) .h(16.0)
.mid_bottom_with_margin_on(state.ids.speech_bubble_text, -20.0) .padded_w_of(state.ids.speech_bubble_text, -4.0)
.parent(id) .mid_bottom_with_margin_on(state.ids.speech_bubble_text, -20.0)
.set(state.ids.speech_bubble_bottom, ui); .parent(id)
Image::new(if dark_mode { .set(state.ids.speech_bubble_bottom, ui);
self.imgs.dark_bubble_bottom_right Image::new(if dark_mode {
} else { self.imgs.dark_bubble_bottom_right
self.imgs.speech_bubble_bottom_right } else {
}) self.imgs.speech_bubble_bottom_right
.w_h(16.0, 16.0) })
.bottom_right_with_margin_on(state.ids.speech_bubble_text, -20.0) .w_h(16.0, 16.0)
.parent(id) .bottom_right_with_margin_on(state.ids.speech_bubble_text, -20.0)
.set(state.ids.speech_bubble_bottom_right, ui); .parent(id)
let tail = Image::new(if dark_mode { .set(state.ids.speech_bubble_bottom_right, ui);
self.imgs.dark_bubble_tail let tail = Image::new(if dark_mode {
} else { self.imgs.dark_bubble_tail
self.imgs.speech_bubble_tail } else {
}) self.imgs.speech_bubble_tail
.parent(id) })
.mid_bottom_with_margin_on(state.ids.speech_bubble_text, -32.0); .parent(id)
.mid_bottom_with_margin_on(state.ids.speech_bubble_text, -32.0);
if dark_mode { if dark_mode {
tail.w_h(22.0, 13.0) tail.w_h(22.0, 13.0)
} else { } else {
tail.w_h(22.0, 28.0) tail.w_h(22.0, 28.0)
} }
.set(state.ids.speech_bubble_tail, ui); .set(state.ids.speech_bubble_tail, ui);
let mut text_shadow = Text::new(&bubble_contents) let mut text_shadow = Text::new(&bubble_contents)
.color(shadow_color) .color(shadow_color)
.font_id(self.fonts.cyri.conrod_id) .font_id(self.fonts.cyri.conrod_id)
.font_size(18) .font_size(18)
.x_relative_to(state.ids.speech_bubble_text, 1.0) .x_relative_to(state.ids.speech_bubble_text, 1.0)
.y_relative_to(state.ids.speech_bubble_text, -1.0) .y_relative_to(state.ids.speech_bubble_text, -1.0)
.parent(id); .parent(id);
// Move text to front (conrod depth is lowest first; not a z-index) // Move text to front (conrod depth is lowest first; not a z-index)
text.depth(text_shadow.get_depth() - 1.0) text.depth(text_shadow.get_depth() - 1.0)
.set(state.ids.speech_bubble_text, ui); .set(state.ids.speech_bubble_text, ui);
if let Some(w) = text_shadow.get_w(ui) { if let Some(w) = text_shadow.get_w(ui) {
if w > MAX_BUBBLE_WIDTH { if w > MAX_BUBBLE_WIDTH {
text_shadow = text_shadow.w(MAX_BUBBLE_WIDTH); text_shadow = text_shadow.w(MAX_BUBBLE_WIDTH);
}
} }
text_shadow.set(state.ids.speech_bubble_shadow, ui); }
let icon = if self.settings.speech_bubble_icon { text_shadow.set(state.ids.speech_bubble_shadow, ui);
bubble_icon(bubble, self.imgs) let icon = if self.settings.speech_bubble_icon {
} else { bubble_icon(bubble, self.imgs)
self.imgs.nothing } else {
}; self.imgs.nothing
Image::new(icon) };
Image::new(icon)
.w_h(16.0, 16.0) .w_h(16.0, 16.0)
.top_left_with_margin_on(state.ids.speech_bubble_text, -16.0) .top_left_with_margin_on(state.ids.speech_bubble_text, -16.0)
// TODO: Figure out whether this should be parented. // TODO: Figure out whether this should be parented.
// .parent(id) // .parent(id)
.set(state.ids.speech_bubble_icon, ui); .set(state.ids.speech_bubble_icon, ui);
}
} }
} }
} }