From b5a2104ca5be66f5a47d51df2dc15dc050293dec Mon Sep 17 00:00:00 2001 From: Monty Marz Date: Mon, 14 Dec 2020 16:35:32 +0100 Subject: [PATCH] group member indicator visuals functional group member indicators adjust visuals z-comparison --- assets/voxygen/element/frames/settings_l.png | 3 - assets/voxygen/element/frames/settings_r.png | 3 - .../voxygen/element/map/group_indicator.png | 3 + .../map/group_indicator_arrow_down.png | 3 + .../element/map/group_indicator_arrow_up.png | 3 + .../element/map/group_indicator_hover.png | 3 + voxygen/src/hud/img_ids.rs | 4 + voxygen/src/hud/map.rs | 90 +++++++++++++++++-- voxygen/src/hud/minimap.rs | 73 ++++++++++++++- 9 files changed, 167 insertions(+), 18 deletions(-) delete mode 100644 assets/voxygen/element/frames/settings_l.png delete mode 100644 assets/voxygen/element/frames/settings_r.png create mode 100644 assets/voxygen/element/map/group_indicator.png create mode 100644 assets/voxygen/element/map/group_indicator_arrow_down.png create mode 100644 assets/voxygen/element/map/group_indicator_arrow_up.png create mode 100644 assets/voxygen/element/map/group_indicator_hover.png diff --git a/assets/voxygen/element/frames/settings_l.png b/assets/voxygen/element/frames/settings_l.png deleted file mode 100644 index c62f856974..0000000000 --- a/assets/voxygen/element/frames/settings_l.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:428ff7b46ac5743f8534c11cad93c89a6e5df416019c1ff36d6701a97c2199e8 -size 531 diff --git a/assets/voxygen/element/frames/settings_r.png b/assets/voxygen/element/frames/settings_r.png deleted file mode 100644 index b0916979f5..0000000000 --- a/assets/voxygen/element/frames/settings_r.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bdefc30dabafb2b844bf0ae6361270a00fc3a1faa6cc6f032261e426c99362d1 -size 560 diff --git a/assets/voxygen/element/map/group_indicator.png b/assets/voxygen/element/map/group_indicator.png new file mode 100644 index 0000000000..d9bd3b0675 --- /dev/null +++ b/assets/voxygen/element/map/group_indicator.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f88b8923ae8da84d11a3813c0955e37c26341966c1708afc52ec4fe0e5c0ef16 +size 1935 diff --git a/assets/voxygen/element/map/group_indicator_arrow_down.png b/assets/voxygen/element/map/group_indicator_arrow_down.png new file mode 100644 index 0000000000..e27dd6f183 --- /dev/null +++ b/assets/voxygen/element/map/group_indicator_arrow_down.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:29b6d69e03e7dd1328adb6bc28627702ff7250a1799aa03eb0e943e7313ee040 +size 2086 diff --git a/assets/voxygen/element/map/group_indicator_arrow_up.png b/assets/voxygen/element/map/group_indicator_arrow_up.png new file mode 100644 index 0000000000..5c5ab8a7f0 --- /dev/null +++ b/assets/voxygen/element/map/group_indicator_arrow_up.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9ef979bcda621d3bfc15490ca62ca64d1fada5b1d93c59e1953d0f6ff89301e0 +size 2088 diff --git a/assets/voxygen/element/map/group_indicator_hover.png b/assets/voxygen/element/map/group_indicator_hover.png new file mode 100644 index 0000000000..a10fc2a795 --- /dev/null +++ b/assets/voxygen/element/map/group_indicator_hover.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da243ffa063164e73a3dd7c3712264b929a2ff212338a9a58d421ada28795212 +size 1926 diff --git a/voxygen/src/hud/img_ids.rs b/voxygen/src/hud/img_ids.rs index 1648664d4b..f2059988f3 100644 --- a/voxygen/src/hud/img_ids.rs +++ b/voxygen/src/hud/img_ids.rs @@ -179,6 +179,10 @@ image_ids! { map_frame_art: "voxygen.element.misc_bg.map_frame_art", indicator_mmap: "voxygen.element.buttons.indicator_mmap", indicator_map_overlay: "voxygen.element.buttons.indicator_mmap_small", + indicator_group: "voxygen.element.map.group_indicator", + indicator_group_hover: "voxygen.element.map.group_indicator_hover", + indicator_group_up: "voxygen.element.map.group_indicator_arrow_up", + indicator_group_down: "voxygen.element.map.group_indicator_arrow_down", // MiniMap mmap_frame: "voxygen.element.frames.mmap", diff --git a/voxygen/src/hud/map.rs b/voxygen/src/hud/map.rs index 6faaa7eed2..4c75ed690e 100644 --- a/voxygen/src/hud/map.rs +++ b/voxygen/src/hud/map.rs @@ -9,14 +9,15 @@ use crate::{ GlobalState, }; use client::{self, Client}; -use common::{comp, terrain::TerrainChunkSize, vol::RectVolSize}; -use common_net::msg::world_msg::SiteKind; +use common::{ + comp, comp::group::Role, msg::world_msg::SiteKind, terrain::TerrainChunkSize, vol::RectVolSize, +}; use conrod_core::{ color, position, widget::{self, Button, Image, Rectangle, Text}, widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, Widget, WidgetCommon, }; -use specs::WorldExt; +use specs::{saveload::MarkerAllocator, WorldExt}; use vek::*; widget_ids! { @@ -37,6 +38,8 @@ widget_ids! { zoom_slider, mmap_site_icons[], site_difs[], + member_indicators[], + member_height_indicators[], map_settings_align, show_towns_img, show_towns_box, @@ -641,15 +644,84 @@ impl<'a> Widget for Map<'a> { } } } + // Group member indicators + let client_state = self.client.state(); + let stats = client_state.ecs().read_storage::(); + let member_pos = client_state.ecs().read_storage::(); + let group_members = self + .client + .group_members() + .iter() + .filter_map(|(u, r)| match r { + Role::Member => Some(u), + Role::Pet => None, + }) + .collect::>(); + let group_size = group_members.len(); + //let in_group = !group_members.is_empty(); + let uid_allocator = client_state + .ecs() + .read_resource::(); + if state.ids.member_indicators.len() < group_size { + state.update(|s| { + s.ids + .member_indicators + .resize(group_size, &mut ui.widget_id_generator()) + }) + }; + for (i, &uid) in group_members.iter().copied().enumerate() { + let entity = uid_allocator.retrieve_entity_internal(uid.into()); + let member_pos = entity.and_then(|entity| member_pos.get(entity)); + let stats = entity.and_then(|entity| stats.get(entity)); + let name= if let Some(stats) = stats {stats.name.to_string()} else {"".to_string()}; + if let Some(member_pos) = member_pos { + // Site pos in world coordinates relative to the player + let rwpos = member_pos.0.xy().map(|e| e as f32) - player_pos; + // Convert to chunk coordinates + let rcpos = rwpos.map2(TerrainChunkSize::RECT_SIZE, |e, sz| e / sz as f32) + // Add map dragging + + drag.map(|e| e as f32); + // Convert to fractional coordinates relative to the worldsize + let rfpos = rcpos / max_zoom as f32; + // Convert to relative pixel coordinates from the center of the map + // Accounting for zooming + let rpos = rfpos.map2(map_size, |e, sz| e * sz as f32 * zoom as f32); + + if rpos + .map2(map_size, |e, sz| e.abs() > sz as f32 / 2.0) + .reduce_or() + { + continue; + } + let factor = 1.2; + let z_comparison = (member_pos.0.z - player_pos.z) as i32; + + Button::image(match z_comparison { + 10..=i32::MAX => self.imgs.indicator_group_up, + i32::MIN..=-10 => self.imgs.indicator_group_down, + _ => self.imgs.indicator_group, + }) + .x_y_position_relative_to( + state.ids.grid, + position::Relative::Scalar(rpos.x as f64), + position::Relative::Scalar(rpos.y as f64), + ) + .w_h(20.0 * factor, 20.0 * factor) + .floating(true) + .with_tooltip( + self.tooltip_manager, + &name, + "", + &site_tooltip, + TEXT_COLOR, + ) + .set(state.ids.member_indicators[i], ui); + } + } // Cursor pos relative to playerpos and widget size // Cursor stops moving on an axis as soon as it's position exceeds the maximum - // // size of the widget - - /*let rel = Vec2::from(player_pos).map2(worldsize, |e: f32, sz: f64| { - (e as f64 / sz).clamped(0.0, 1.0) - });*/ - //let xy = rel * 760.0; + // // size of the widget // Offset from map center due to dragging let rcpos = drag.map(|e| e as f32); diff --git a/voxygen/src/hud/minimap.rs b/voxygen/src/hud/minimap.rs index 38f9ae0735..23ba6bc8dd 100644 --- a/voxygen/src/hud/minimap.rs +++ b/voxygen/src/hud/minimap.rs @@ -5,15 +5,14 @@ use super::{ }; use crate::ui::{fonts::Fonts, img_ids}; use client::{self, Client}; -use common::{comp, terrain::TerrainChunkSize, vol::RectVolSize}; -use common_net::msg::world_msg::SiteKind; +use common::{comp, comp::group::Role, msg::world_msg::SiteKind, terrain::TerrainChunkSize, vol::RectVolSize}; use conrod_core::{ color, position, widget::{self, Button, Image, Rectangle, Text}, widget_ids, Color, Colorable, Positionable, Sizeable, Widget, WidgetCommon, }; -use specs::WorldExt; +use specs::{saveload::MarkerAllocator, WorldExt}; use vek::*; widget_ids! { @@ -33,6 +32,7 @@ widget_ids! { mmap_west, mmap_site_icons_bgs[], mmap_site_icons[], + member_indicators[], } } @@ -295,12 +295,79 @@ impl<'a> Widget for MiniMap<'a> { .set(state.ids.mmap_site_icons[i], ui); } + // Group member indicators + let client_state = self.client.state(); + let member_pos = client_state.ecs().read_storage::(); + let group_members = self + .client + .group_members() + .iter() + .filter_map(|(u, r)| match r { + Role::Member => Some(u), + Role::Pet => None, + }) + .collect::>(); + let group_size = group_members.len(); + //let in_group = !group_members.is_empty(); + let uid_allocator = client_state + .ecs() + .read_resource::(); + if state.ids.member_indicators.len() < group_size { + state.update(|s| { + s.ids + .member_indicators + .resize(group_size, &mut ui.widget_id_generator()) + }) + }; + for (i, &uid) in group_members.iter().copied().enumerate() { + let entity = uid_allocator.retrieve_entity_internal(uid.into()); + let member_pos = entity.and_then(|entity| member_pos.get(entity)); + + if let Some(member_pos) = member_pos { + // Site pos in world coordinates relative to the player + let rwpos = member_pos.0.xy().map(|e| e as f32) - player_pos; + // Convert to chunk coordinates + let rcpos = rwpos.map2(TerrainChunkSize::RECT_SIZE, |e, sz| e / sz as f32); + // Convert to fractional coordinates relative to the worldsize + let rfpos = rcpos / max_zoom as f32; + // Convert to unrotated pixel coordinates from the player location on the map + // (the center) + // Accounting for zooming + let rpixpos = rfpos.map2(map_size, |e, sz| e * sz as f32 * zoom as f32); + let rpos = Vec2::unit_x().rotated_z(self.ori.x) * rpixpos.x + + Vec2::unit_y().rotated_z(self.ori.x) * rpixpos.y; + + if rpos + .map2(map_size, |e, sz| e.abs() > sz as f32 / 2.0) + .reduce_or() + { + continue; + } + let factor = 1.2; + let z_comparison = (member_pos.0.z - player_pos.z) as i32; + Button::image(match z_comparison { + 10..=i32::MAX => self.imgs.indicator_group_up, + i32::MIN..=-10 => self.imgs.indicator_group_down, + _ => self.imgs.indicator_group, + }) + .x_y_position_relative_to( + state.ids.grid, + position::Relative::Scalar(rpos.x as f64), + position::Relative::Scalar(rpos.y as f64), + ) + .w_h(16.0 * factor, 16.0 * factor) + .image_color(Color::Rgba(1.0, 1.0, 1.0, 1.0)) + .set(state.ids.member_indicators[i], ui); + } + } + // Indicator let ind_scale = 0.4; Image::new(self.rot_imgs.indicator_mmap_small.none) .middle_of(state.ids.grid) .w_h(32.0 * ind_scale, 37.0 * ind_scale) .color(Some(UI_HIGHLIGHT_0)) + .floating(true) .set(state.ids.indicator, ui); // Compass directions