diff --git a/CHANGELOG.md b/CHANGELOG.md index 48b76f69e8..8ded03bf87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Display item name over loot/dropped items - Added Lottery system for loot - Added context-sensitive crosshair - Announce alias changes to all clients diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index 2898937ae7..1711c7d290 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -9,6 +9,7 @@ mod item_imgs; mod map; mod minimap; mod overhead; +mod overitem; mod popup; mod settings_window; mod skillbar; @@ -141,6 +142,7 @@ widget_ids! { scts[], overheads[], + overitems[], // Intro Text intro_bg, @@ -664,6 +666,7 @@ impl Hud { let players = ecs.read_storage::(); let scales = ecs.read_storage::(); let bodies = ecs.read_storage::(); + let items = ecs.read_storage::(); let entities = ecs.entities(); let me = client.entity(); let own_level = stats @@ -1000,9 +1003,29 @@ impl Hud { } let mut overhead_walker = self.ids.overheads.walk(); + let mut overitem_walker = self.ids.overitems.walk(); let mut sct_walker = self.ids.scts.walk(); let mut sct_bg_walker = self.ids.sct_bgs.walk(); + // Render overitem name + for (pos, item, distance) in (&entities, &pos, &items) + .join() + .map(|(_, pos, item)| (pos, item, pos.0.distance_squared(player_pos))) + .filter(|(_, _, distance)| distance < &common::comp::MAX_PICKUP_RANGE_SQR) + { + let overitem_id = overitem_walker.next( + &mut self.ids.overitems, + &mut ui_widgets.widget_id_generator(), + ); + let ingame_pos = pos.0 + Vec3::unit_z() * 1.2; + + // Item name + overitem::Overitem::new(&item.name(), &distance, &self.fonts) + .x_y(0.0, 100.0) + .position_ingame(ingame_pos) + .set(overitem_id, ui_widgets); + } + // Render overhead name tags and health bars for (pos, name, stats, energy, height_offset, hpfl, uid) in ( &entities, diff --git a/voxygen/src/hud/overitem.rs b/voxygen/src/hud/overitem.rs new file mode 100644 index 0000000000..bb4458ecb6 --- /dev/null +++ b/voxygen/src/hud/overitem.rs @@ -0,0 +1,83 @@ +use crate::ui::{fonts::ConrodVoxygenFonts, Ingameable}; +use conrod_core::{ + widget::{self, Text}, + widget_ids, Color, Colorable, Positionable, Widget, WidgetCommon, +}; + +widget_ids! { + struct Ids { + // Name + name_bg, + name, + } +} + +/// ui widget containing everything that goes over a item +/// (Item, DistanceFromPlayer, Rarity, etc.) +#[derive(WidgetCommon)] +pub struct Overitem<'a> { + name: &'a str, + distance: &'a f32, + fonts: &'a ConrodVoxygenFonts, + #[conrod(common_builder)] + common: widget::CommonBuilder, +} + +impl<'a> Overitem<'a> { + pub fn new(name: &'a str, distance: &'a f32, fonts: &'a ConrodVoxygenFonts) -> Self { + Self { + name, + distance, + fonts, + common: widget::CommonBuilder::default(), + } + } +} + +pub struct State { + ids: Ids, +} + +impl<'a> Ingameable for Overitem<'a> { + fn prim_count(&self) -> usize { + // Number of conrod primitives contained in the overitem isplay. TODO maybe + // this could be done automatically? + // - 2 Text::new for name + 2 + } +} + +impl<'a> Widget for Overitem<'a> { + type Event = (); + type State = State; + type Style = (); + + fn init_state(&self, id_gen: widget::id::Generator) -> Self::State { + State { + ids: Ids::new(id_gen), + } + } + + fn style(&self) -> Self::Style {} + + fn update(self, args: widget::UpdateArgs) -> Self::Event { + let widget::UpdateArgs { state, ui, .. } = args; + + let font_size = + ((1.0 - (self.distance / common::comp::MAX_PICKUP_RANGE_SQR)) * 30.0) as u32; + + // ItemName + Text::new(&self.name) + .font_id(self.fonts.cyri.conrod_id) + .font_size(font_size) + .color(Color::Rgba(0.0, 0.0, 0.0, 1.0)) + .x_y(-1.0, 48.0) + .set(state.ids.name_bg, ui); + Text::new(&self.name) + .font_id(self.fonts.cyri.conrod_id) + .font_size(font_size) + .color(Color::Rgba(0.61, 0.61, 0.89, 1.0)) + .x_y(0.0, 50.0) + .set(state.ids.name, ui); + } +}