diff --git a/CHANGELOG.md b/CHANGELOG.md index d3b2d1541f..8ee38ebac5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Campfire resting heal - Initial support for game plugins, both server-side and client-side - Reflective LoD water +- Map indicators for group members ### Changed diff --git a/assets/voxygen/element/buttons/checkbox/active.png b/assets/voxygen/element/buttons/checkbox/active.png new file mode 100644 index 0000000000..6d4821c335 Binary files /dev/null and b/assets/voxygen/element/buttons/checkbox/active.png differ diff --git a/assets/voxygen/element/buttons/checkbox/active.vox b/assets/voxygen/element/buttons/checkbox/active.vox deleted file mode 100644 index ed0f7692e4..0000000000 Binary files a/assets/voxygen/element/buttons/checkbox/active.vox and /dev/null differ diff --git a/assets/voxygen/element/buttons/checkbox/hover.png b/assets/voxygen/element/buttons/checkbox/hover.png new file mode 100644 index 0000000000..12ebdc7226 Binary files /dev/null and b/assets/voxygen/element/buttons/checkbox/hover.png differ diff --git a/assets/voxygen/element/buttons/checkbox/hover.vox b/assets/voxygen/element/buttons/checkbox/hover.vox deleted file mode 100644 index a74eb7c280..0000000000 Binary files a/assets/voxygen/element/buttons/checkbox/hover.vox and /dev/null differ diff --git a/assets/voxygen/element/buttons/checkbox/inactive.png b/assets/voxygen/element/buttons/checkbox/inactive.png new file mode 100644 index 0000000000..fea7a655f2 Binary files /dev/null and b/assets/voxygen/element/buttons/checkbox/inactive.png differ diff --git a/assets/voxygen/element/buttons/checkbox/inactive.vox b/assets/voxygen/element/buttons/checkbox/inactive.vox deleted file mode 100644 index cea5ae21b9..0000000000 Binary files a/assets/voxygen/element/buttons/checkbox/inactive.vox and /dev/null differ diff --git a/assets/voxygen/element/buttons/checkbox/inactive_hover.png b/assets/voxygen/element/buttons/checkbox/inactive_hover.png new file mode 100644 index 0000000000..31f83cd609 Binary files /dev/null and b/assets/voxygen/element/buttons/checkbox/inactive_hover.png differ diff --git a/assets/voxygen/element/buttons/checkbox/inactive_hover.vox b/assets/voxygen/element/buttons/checkbox/inactive_hover.vox deleted file mode 100644 index 00139fbfee..0000000000 Binary files a/assets/voxygen/element/buttons/checkbox/inactive_hover.vox and /dev/null differ diff --git a/assets/voxygen/element/buttons/checkbox/press.png b/assets/voxygen/element/buttons/checkbox/press.png new file mode 100644 index 0000000000..e016d39b35 Binary files /dev/null and b/assets/voxygen/element/buttons/checkbox/press.png differ diff --git a/assets/voxygen/element/buttons/checkbox/press.vox b/assets/voxygen/element/buttons/checkbox/press.vox deleted file mode 100644 index 1929b534c8..0000000000 Binary files a/assets/voxygen/element/buttons/checkbox/press.vox and /dev/null differ diff --git a/assets/voxygen/element/buttons/radio/active.png b/assets/voxygen/element/buttons/radio/active.png new file mode 100644 index 0000000000..c5b89cd4e3 Binary files /dev/null and b/assets/voxygen/element/buttons/radio/active.png differ diff --git a/assets/voxygen/element/buttons/radio/active.vox b/assets/voxygen/element/buttons/radio/active.vox deleted file mode 100644 index b6183beec4..0000000000 Binary files a/assets/voxygen/element/buttons/radio/active.vox and /dev/null differ diff --git a/assets/voxygen/element/buttons/radio/hover.png b/assets/voxygen/element/buttons/radio/hover.png new file mode 100644 index 0000000000..3cadde3b58 Binary files /dev/null and b/assets/voxygen/element/buttons/radio/hover.png differ diff --git a/assets/voxygen/element/buttons/radio/hover.vox b/assets/voxygen/element/buttons/radio/hover.vox deleted file mode 100644 index c9236fe831..0000000000 Binary files a/assets/voxygen/element/buttons/radio/hover.vox and /dev/null differ diff --git a/assets/voxygen/element/buttons/radio/inactive.png b/assets/voxygen/element/buttons/radio/inactive.png new file mode 100644 index 0000000000..01a49fcf70 Binary files /dev/null and b/assets/voxygen/element/buttons/radio/inactive.png differ diff --git a/assets/voxygen/element/buttons/radio/inactive.vox b/assets/voxygen/element/buttons/radio/inactive.vox deleted file mode 100644 index 912990fd7b..0000000000 Binary files a/assets/voxygen/element/buttons/radio/inactive.vox and /dev/null differ diff --git a/assets/voxygen/element/buttons/radio/inactive_hover.png b/assets/voxygen/element/buttons/radio/inactive_hover.png new file mode 100644 index 0000000000..fea0990692 Binary files /dev/null and b/assets/voxygen/element/buttons/radio/inactive_hover.png differ diff --git a/assets/voxygen/element/buttons/radio/inactive_hover.vox b/assets/voxygen/element/buttons/radio/inactive_hover.vox deleted file mode 100644 index a368fe391f..0000000000 Binary files a/assets/voxygen/element/buttons/radio/inactive_hover.vox and /dev/null differ diff --git a/assets/voxygen/element/buttons/radio/press.png b/assets/voxygen/element/buttons/radio/press.png new file mode 100644 index 0000000000..46085c3d30 Binary files /dev/null and b/assets/voxygen/element/buttons/radio/press.png differ diff --git a/assets/voxygen/element/buttons/radio/press.vox b/assets/voxygen/element/buttons/radio/press.vox deleted file mode 100644 index 5c7c1e9788..0000000000 Binary files a/assets/voxygen/element/buttons/radio/press.vox and /dev/null differ diff --git a/assets/voxygen/element/frames/settings_l.png b/assets/voxygen/element/frames/settings_l.png deleted file mode 100644 index 275d4ae09c..0000000000 Binary files a/assets/voxygen/element/frames/settings_l.png and /dev/null differ diff --git a/assets/voxygen/element/frames/settings_r.png b/assets/voxygen/element/frames/settings_r.png deleted file mode 100644 index 6d4787ad03..0000000000 Binary files a/assets/voxygen/element/frames/settings_r.png and /dev/null differ diff --git a/assets/voxygen/element/icons/de_buffs/buff_campfire_heal_0.png b/assets/voxygen/element/icons/de_buffs/buff_campfire_heal_0.png index 3e6c376139..a8fcd70486 100644 Binary files a/assets/voxygen/element/icons/de_buffs/buff_campfire_heal_0.png and b/assets/voxygen/element/icons/de_buffs/buff_campfire_heal_0.png differ diff --git a/assets/voxygen/element/map/group_indicator.png b/assets/voxygen/element/map/group_indicator.png new file mode 100644 index 0000000000..0b475881dd Binary files /dev/null and b/assets/voxygen/element/map/group_indicator.png differ 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..8c680001cd Binary files /dev/null and b/assets/voxygen/element/map/group_indicator_arrow_down.png differ 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..0a6a2424ed Binary files /dev/null and b/assets/voxygen/element/map/group_indicator_arrow_up.png differ 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..cbc3c2eccf Binary files /dev/null and b/assets/voxygen/element/map/group_indicator_hover.png differ diff --git a/common/sys/src/agent.rs b/common/sys/src/agent.rs index 806162c5e3..92744e70bb 100644 --- a/common/sys/src/agent.rs +++ b/common/sys/src/agent.rs @@ -1474,7 +1474,7 @@ impl<'a> System<'a> for Sys { for (_invite, /*alignment,*/ agent, controller) in (&invites, /*&alignments,*/ &mut agents, &mut controllers).join() { - let accept = false; // set back to "matches!(alignment, Alignment::Npc)" when we got better NPC recruitment mechanics + let accept = true; // set back to "matches!(alignment, Alignment::Npc)" when we got better NPC recruitment mechanics if accept { // Clear agent comp *agent = Agent::default(); diff --git a/voxygen/src/hud/img_ids.rs b/voxygen/src/hud/img_ids.rs index 1648664d4b..e6e143c7b8 100644 --- a/voxygen/src/hud/img_ids.rs +++ b/voxygen/src/hud/img_ids.rs @@ -26,18 +26,6 @@ image_ids! { flower: "voxygen.element.icons.item_flower", grass: "voxygen.element.icons.item_grass", - // Checkboxes and Radio buttons - check: "voxygen.element.buttons.radio.inactive", - check_mo: "voxygen.element.buttons.radio.inactive_hover", - check_press: "voxygen.element.buttons.radio.press", - check_checked: "voxygen.element.buttons.radio.active", - check_checked_mo: "voxygen.element.buttons.radio.hover", - checkbox: "voxygen.element.buttons.checkbox.inactive", - checkbox_mo: "voxygen.element.buttons.checkbox.inactive_hover", - checkbox_press: "voxygen.element.buttons.checkbox.press", - checkbox_checked: "voxygen.element.buttons.checkbox.active", - checkbox_checked_mo: "voxygen.element.buttons.checkbox.hover", - // Charwindow xp_charwindow: "voxygen.element.frames.xp_charwindow", divider: "voxygen.element.frames.divider_charwindow", @@ -53,6 +41,19 @@ image_ids! { ////////////////////////////////////////////////////////////////////////////////////////////////////// + + // Checkboxes and Radio buttons + check: "voxygen.element.buttons.radio.inactive", + check_mo: "voxygen.element.buttons.radio.inactive_hover", + check_press: "voxygen.element.buttons.radio.press", + check_checked: "voxygen.element.buttons.radio.active", + check_checked_mo: "voxygen.element.buttons.radio.hover", + checkbox: "voxygen.element.buttons.checkbox.inactive", + checkbox_mo: "voxygen.element.buttons.checkbox.inactive_hover", + checkbox_press: "voxygen.element.buttons.checkbox.press", + checkbox_checked: "voxygen.element.buttons.checkbox.active", + checkbox_checked_mo: "voxygen.element.buttons.checkbox.hover", + // Selection Frame selection: "voxygen.element.frames.selection", selection_hover: "voxygen.element.frames.selection_hover", @@ -179,6 +180,9 @@ 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_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..d22d920408 100644 --- a/voxygen/src/hud/map.rs +++ b/voxygen/src/hud/map.rs @@ -9,14 +9,14 @@ use crate::{ GlobalState, }; use client::{self, Client}; -use common::{comp, terrain::TerrainChunkSize, vol::RectVolSize}; +use common::{comp, comp::group::Role, terrain::TerrainChunkSize, vol::RectVolSize}; use common_net::msg::world_msg::SiteKind; 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 +37,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,16 +643,83 @@ 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; - // Offset from map center due to dragging let rcpos = drag.map(|e| e as f32); // Convert to fractional coordinates relative to the worldsize diff --git a/voxygen/src/hud/minimap.rs b/voxygen/src/hud/minimap.rs index 38f9ae0735..e5de2b90ed 100644 --- a/voxygen/src/hud/minimap.rs +++ b/voxygen/src/hud/minimap.rs @@ -5,7 +5,7 @@ use super::{ }; use crate::ui::{fonts::Fonts, img_ids}; use client::{self, Client}; -use common::{comp, terrain::TerrainChunkSize, vol::RectVolSize}; +use common::{comp, comp::group::Role, terrain::TerrainChunkSize, vol::RectVolSize}; use common_net::msg::world_msg::SiteKind; use conrod_core::{ color, position, @@ -13,7 +13,7 @@ use conrod_core::{ widget_ids, Color, Colorable, Positionable, Sizeable, Widget, WidgetCommon, }; -use specs::WorldExt; +use specs::{saveload::MarkerAllocator, WorldExt}; use vek::*; widget_ids! { @@ -33,6 +33,7 @@ widget_ids! { mmap_west, mmap_site_icons_bgs[], mmap_site_icons[], + member_indicators[], } } @@ -295,12 +296,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 diff --git a/voxygen/src/hud/skillbar.rs b/voxygen/src/hud/skillbar.rs index 3102f09dfe..60a5697764 100644 --- a/voxygen/src/hud/skillbar.rs +++ b/voxygen/src/hud/skillbar.rs @@ -607,7 +607,7 @@ impl<'a> Widget for Skillbar<'a> { .fabricate(hotbar::Slot::Four, [40.0; 2]) .filled_slot(self.imgs.inv_slot) .right_from(state.ids.slot3, 0.0); - if let Some((title, desc)) = tooltip_text(hotbar::Slot::Three) { + if let Some((title, desc)) = tooltip_text(hotbar::Slot::Four) { slot.with_tooltip(self.tooltip_manager, title, desc, &item_tooltip, TEXT_COLOR) .set(state.ids.slot4, ui); } else { @@ -618,7 +618,7 @@ impl<'a> Widget for Skillbar<'a> { .fabricate(hotbar::Slot::Five, [40.0; 2]) .filled_slot(self.imgs.inv_slot) .right_from(state.ids.slot4, 0.0); - if let Some((title, desc)) = tooltip_text(hotbar::Slot::Three) { + if let Some((title, desc)) = tooltip_text(hotbar::Slot::Five) { slot.with_tooltip(self.tooltip_manager, title, desc, &item_tooltip, TEXT_COLOR) .set(state.ids.slot5, ui); } else {