From 8b6c73744ea09e767a1d0646c4a1cfdb9c78a2cc Mon Sep 17 00:00:00 2001 From: Monty Marz Date: Tue, 17 Nov 2020 21:45:44 +0100 Subject: [PATCH] more map stuff --- voxygen/src/hud/map.rs | 346 +++++++++++++++++++++++++------------ voxygen/src/hud/minimap.rs | 2 +- voxygen/src/hud/mod.rs | 30 ++-- voxygen/src/render/mod.rs | 12 +- voxygen/src/settings.rs | 4 +- 5 files changed, 256 insertions(+), 138 deletions(-) diff --git a/voxygen/src/hud/map.rs b/voxygen/src/hud/map.rs index 52f4c71688..e49b0903ca 100644 --- a/voxygen/src/hud/map.rs +++ b/voxygen/src/hud/map.rs @@ -1,16 +1,19 @@ use super::{ img_ids::{Imgs, ImgsRot}, - Show, TEXT_COLOR, UI_HIGHLIGHT_0, UI_MAIN, QUALITY_LOW, QUALITY_COMMON, QUALITY_MODERATE, QUALITY_HIGH, QUALITY_EPIC, QUALITY_DEBUG, + Show, QUALITY_COMMON, QUALITY_DEBUG, QUALITY_EPIC, QUALITY_HIGH, QUALITY_LOW, QUALITY_MODERATE, + TEXT_COLOR, UI_HIGHLIGHT_0, UI_MAIN, }; use crate::{ i18n::Localization, - ui::{fonts::Fonts, img_ids, ImageFrame, ImageSlider, Tooltip, TooltipManager, Tooltipable}, + ui::{fonts::Fonts, img_ids, ImageFrame, Tooltip, TooltipManager, Tooltipable}, GlobalState, }; use client::{self, Client}; use common::{comp, msg::world_msg::SiteKind, terrain::TerrainChunkSize, vol::RectVolSize}; use conrod_core::{ - color, position, + color, + input::Key, + position, widget::{self, Button, Image, Rectangle, Text}, widget_ids, Color, Colorable, Positionable, Sizeable, Widget, WidgetCommon, }; @@ -49,6 +52,8 @@ widget_ids! { show_difficulty_img, show_difficulty_box, show_difficulty_text, + recenter_txt, + drag_txt, } } @@ -82,7 +87,7 @@ impl<'a> Map<'a> { tooltip_manager: &'a mut TooltipManager, ) -> Self { Self { - show: show, + show, imgs, rot_imgs, world_map, @@ -236,14 +241,20 @@ impl<'a> Widget for Map<'a> { let h_src = max_zoom / zoom; // Handle dragging let drag = self.global_state.settings.gameplay.map_drag; - let dragged: Vec2:: = ui.widget_input(state.ids.grid).drags().left().map(|drag| Vec2::::from(drag.delta_xy)).sum(); + let dragged: Vec2 = ui + .widget_input(state.ids.grid) + .drags() + .left() + .map(|drag| Vec2::::from(drag.delta_xy)) + .sum(); let drag_new = drag + dragged / zoom; events.push(Event::MapDrag(drag_new)); let rect_src = position::Rect::from_xy_dim( [ (player_pos.x as f64 / TerrainChunkSize::RECT_SIZE.x as f64) - drag.x, - ((worldsize.y - player_pos.y as f64) / TerrainChunkSize::RECT_SIZE.y as f64) + drag.y, + ((worldsize.y - player_pos.y as f64) / TerrainChunkSize::RECT_SIZE.y as f64) + + drag.y, ], [w_src, h_src], ); @@ -266,7 +277,7 @@ impl<'a> Widget for Map<'a> { .source_rectangle(rect_src) .set(state.ids.grid, ui); - if let Some(new_val) = ImageSlider::discrete( + /*if let Some(new_val) = ImageSlider::discrete( self.global_state.settings.gameplay.map_zoom as i32, 1, 30, @@ -281,13 +292,26 @@ impl<'a> Widget for Map<'a> { .set(state.ids.zoom_slider, ui) { events.push(Event::MapZoom(new_val as f64)); - } + }*/ // Handle zooming with the mousewheel let zoom_lvl = self.global_state.settings.gameplay.map_zoom; - let scrolled: f64 = ui.widget_input(state.ids.grid).scrolls().map(|scroll| scroll.y).sum(); - let new_zoom_lvl = (zoom_lvl * (1.0 + scrolled * 0.1)).clamped(1.0, 20.0/*max_zoom*/); + let scrolled: f64 = ui + .widget_input(state.ids.grid) + .scrolls() + .map(|scroll| scroll.y) + .sum(); + let new_zoom_lvl = + (zoom_lvl * (1.0 + scrolled * 0.1)).clamped(1.0, 20.0 /* max_zoom */); events.push(Event::MapZoom(new_zoom_lvl as f64)); - + // Handle recenter by pressing space + if ui + .widget_input(state.ids.grid) + .presses() + .key() + .any(|key_press| matches!(key_press.key, Key::Space) || matches!(key_press.key, Key::Escape)|| matches!(key_press.key, Key::M)) + { + events.push(Event::MapDrag(drag_new - drag_new)); + } // Icon settings // Alignment @@ -297,17 +321,26 @@ impl<'a> Widget for Map<'a> { // Checkboxes // Show difficulties Image::new(self.imgs.map_dif_5) - .top_left_with_margins_on(state.ids.map_settings_align, 5.0, 5.0) - .w_h(20.0, 20.0) - .set(state.ids.show_difficulty_img, ui); + .top_left_with_margins_on(state.ids.map_settings_align, 5.0, 5.0) + .w_h(20.0, 20.0) + .set(state.ids.show_difficulty_img, ui); if Button::image(if self.show.map_difficulty { - self.imgs.checkbox_checked} else {self.imgs.checkbox}) + self.imgs.checkbox_checked + } else { + self.imgs.checkbox + }) .w_h(18.0, 18.0) .hover_image(if self.show.map_difficulty { - self.imgs.checkbox_checked_mo} else {self.imgs.checkbox_mo}) + self.imgs.checkbox_checked_mo + } else { + self.imgs.checkbox_mo + }) .press_image(if self.show.map_difficulty { - self.imgs.checkbox_checked} else {self.imgs.checkbox_press}) - .right_from(state.ids.show_difficulty_img, 10.0) + self.imgs.checkbox_checked + } else { + self.imgs.checkbox_press + }) + .right_from(state.ids.show_difficulty_img, 10.0) .set(state.ids.show_difficulty_box, ui) .was_clicked() { @@ -322,17 +355,26 @@ impl<'a> Widget for Map<'a> { .set(state.ids.show_difficulty_text, ui); // Towns Image::new(self.imgs.mmap_site_town) - .down_from(state.ids.show_difficulty_img, 10.0) - .w_h(20.0, 20.0) - .set(state.ids.show_towns_img, ui); + .down_from(state.ids.show_difficulty_img, 10.0) + .w_h(20.0, 20.0) + .set(state.ids.show_towns_img, ui); if Button::image(if self.show.map_towns { - self.imgs.checkbox_checked} else {self.imgs.checkbox}) + self.imgs.checkbox_checked + } else { + self.imgs.checkbox + }) .w_h(18.0, 18.0) .hover_image(if self.show.map_towns { - self.imgs.checkbox_checked_mo} else {self.imgs.checkbox_mo}) + self.imgs.checkbox_checked_mo + } else { + self.imgs.checkbox_mo + }) .press_image(if self.show.map_towns { - self.imgs.checkbox_checked} else {self.imgs.checkbox_press}) - .right_from(state.ids.show_towns_img, 10.0) + self.imgs.checkbox_checked + } else { + self.imgs.checkbox_press + }) + .right_from(state.ids.show_towns_img, 10.0) .set(state.ids.show_towns_box, ui) .was_clicked() { @@ -347,17 +389,26 @@ impl<'a> Widget for Map<'a> { .set(state.ids.show_towns_text, ui); // Castles Image::new(self.imgs.mmap_site_castle) - .down_from(state.ids.show_towns_img, 10.0) - .w_h(20.0, 20.0) - .set(state.ids.show_castles_img, ui); + .down_from(state.ids.show_towns_img, 10.0) + .w_h(20.0, 20.0) + .set(state.ids.show_castles_img, ui); if Button::image(if self.show.map_castles { - self.imgs.checkbox_checked} else {self.imgs.checkbox}) + self.imgs.checkbox_checked + } else { + self.imgs.checkbox + }) .w_h(18.0, 18.0) .hover_image(if self.show.map_castles { - self.imgs.checkbox_checked_mo} else {self.imgs.checkbox_mo}) + self.imgs.checkbox_checked_mo + } else { + self.imgs.checkbox_mo + }) .press_image(if self.show.map_castles { - self.imgs.checkbox_checked} else {self.imgs.checkbox_press}) - .right_from(state.ids.show_castles_img, 10.0) + self.imgs.checkbox_checked + } else { + self.imgs.checkbox_press + }) + .right_from(state.ids.show_castles_img, 10.0) .set(state.ids.show_castles_box, ui) .was_clicked() { @@ -372,29 +423,38 @@ impl<'a> Widget for Map<'a> { .set(state.ids.show_castles_text, ui); // Dungeons Image::new(self.imgs.mmap_site_dungeon) -.down_from(state.ids.show_castles_img, 10.0) -.w_h(20.0, 20.0) -.set(state.ids.show_dungeons_img, ui); -if Button::image(if self.show.map_dungeons { - self.imgs.checkbox_checked} else {self.imgs.checkbox}) -.w_h(18.0, 18.0) -.hover_image(if self.show.map_dungeons { - self.imgs.checkbox_checked_mo} else {self.imgs.checkbox_mo}) -.press_image(if self.show.map_dungeons { - self.imgs.checkbox_checked} else {self.imgs.checkbox_press}) - .right_from(state.ids.show_dungeons_img, 10.0) -.set(state.ids.show_dungeons_box, ui) -.was_clicked() -{ - events.push(Event::ShowDungeons); -} -Text::new("Dungeons") - .right_from(state.ids.show_dungeons_box, 10.0) - .font_size(self.fonts.cyri.scale(14)) - .font_id(self.fonts.cyri.conrod_id) - .graphics_for(state.ids.show_dungeons_box) - .color(TEXT_COLOR) - .set(state.ids.show_dungeons_text, ui); + .down_from(state.ids.show_castles_img, 10.0) + .w_h(20.0, 20.0) + .set(state.ids.show_dungeons_img, ui); + if Button::image(if self.show.map_dungeons { + self.imgs.checkbox_checked + } else { + self.imgs.checkbox + }) + .w_h(18.0, 18.0) + .hover_image(if self.show.map_dungeons { + self.imgs.checkbox_checked_mo + } else { + self.imgs.checkbox_mo + }) + .press_image(if self.show.map_dungeons { + self.imgs.checkbox_checked + } else { + self.imgs.checkbox_press + }) + .right_from(state.ids.show_dungeons_img, 10.0) + .set(state.ids.show_dungeons_box, ui) + .was_clicked() + { + events.push(Event::ShowDungeons); + } + Text::new("Dungeons") + .right_from(state.ids.show_dungeons_box, 10.0) + .font_size(self.fonts.cyri.scale(14)) + .font_id(self.fonts.cyri.conrod_id) + .graphics_for(state.ids.show_dungeons_box) + .color(TEXT_COLOR) + .set(state.ids.show_dungeons_text, ui); // Map icons if state.ids.mmap_site_icons.len() < self.client.sites().len() { state.update(|state| { @@ -435,10 +495,28 @@ Text::new("Dungeons") SiteKind::Castle => "Castle", }; let desc = format!("Difficulty: {}", dif); - Button::image(match &site.kind { - SiteKind::Town => if self.show.map_towns {self.imgs.mmap_site_town } else {self.imgs.nothing}, - SiteKind::Dungeon => if self.show.map_dungeons {self.imgs.mmap_site_dungeon} else {self.imgs.nothing}, - SiteKind::Castle => if self.show.map_castles {self.imgs.mmap_site_castle} else {self.imgs.nothing}, + let site_btn = Button::image(match &site.kind { + SiteKind::Town => { + if self.show.map_towns { + self.imgs.mmap_site_town + } else { + self.imgs.nothing + } + }, + SiteKind::Dungeon => { + if self.show.map_dungeons { + self.imgs.mmap_site_dungeon + } else { + self.imgs.nothing + } + }, + SiteKind::Castle => { + if self.show.map_castles { + self.imgs.mmap_site_castle + } else { + self.imgs.nothing + } + }, }) .x_y_position_relative_to( state.ids.grid, @@ -453,63 +531,94 @@ Text::new("Dungeons") }) .image_color(UI_HIGHLIGHT_0) .parent(ui.window) - .with_tooltip(self.tooltip_manager, title, &desc, &site_tooltip, match dif { - 1 => QUALITY_LOW, - 2 => QUALITY_COMMON, - 3 => QUALITY_MODERATE, - 4 => QUALITY_HIGH, - 5 => QUALITY_EPIC, - 6 => QUALITY_DEBUG, - _ => TEXT_COLOR, - }) - .set(state.ids.mmap_site_icons[i], ui); + .with_tooltip( + self.tooltip_manager, + title, + &desc, + &site_tooltip, + match dif { + 1 => QUALITY_LOW, + 2 => QUALITY_COMMON, + 3 => QUALITY_MODERATE, + 4 => QUALITY_HIGH, + 5 => QUALITY_EPIC, + 6 => QUALITY_DEBUG, + _ => TEXT_COLOR, + }, + ); + // Only display sites that are toggled on + match &site.kind { + SiteKind::Town => { + if self.show.map_towns { + site_btn.set(state.ids.mmap_site_icons[i], ui); + } + }, + SiteKind::Dungeon => { + if self.show.map_dungeons { + site_btn.set(state.ids.mmap_site_icons[i], ui); + } + }, + SiteKind::Castle => { + if self.show.map_castles { + site_btn.set(state.ids.mmap_site_icons[i], ui); + } + }, + } // Difficulty from 0-6 // 0 = towns and places without a difficulty level if self.show.map_difficulty { - - let size = 1.8; // Size factor for difficulty indicators - let dif_img = Image::new(match dif { - 1 => self.imgs.map_dif_0, - 2 => self.imgs.map_dif_1, - 3 => self.imgs.map_dif_2, - 4 => self.imgs.map_dif_3, - 5 => self.imgs.map_dif_4, - 6 => self.imgs.map_dif_5, - _ => self.imgs.nothing, - }) - .mid_top_with_margin_on(state.ids.mmap_site_icons[i], match dif { - 6 => -12.0 * size, - _ => -4.0 * size, - }) - .w(match dif { - 6 => 12.0 * size, - _ => 4.0 * size * dif as f64, - }) - .h(match dif { - 6 => 12.0 * size, - _ => 4.0 * size, - }) - .color(Some(match dif { - 1 => QUALITY_LOW, - 2 => QUALITY_COMMON, - 3 => QUALITY_MODERATE, - 4 => QUALITY_HIGH, - 5 => QUALITY_EPIC, - 6 => TEXT_COLOR, - _ => TEXT_COLOR, - } - ) - ); - match &site.kind { - SiteKind::Town => if self.show.map_towns {dif_img.set(state.ids.site_difs[i], ui) }, - SiteKind::Dungeon => if self.show.map_dungeons {dif_img.set(state.ids.site_difs[i], ui)}, - SiteKind::Castle => if self.show.map_castles {dif_img.set(state.ids.site_difs[i], ui)}, + let size = 1.8; // Size factor for difficulty indicators + let dif_img = Image::new(match dif { + 1 => self.imgs.map_dif_0, + 2 => self.imgs.map_dif_1, + 3 => self.imgs.map_dif_2, + 4 => self.imgs.map_dif_3, + 5 => self.imgs.map_dif_4, + 6 => self.imgs.map_dif_5, + _ => self.imgs.nothing, + }) + .mid_top_with_margin_on(state.ids.mmap_site_icons[i], match dif { + 6 => -12.0 * size, + _ => -4.0 * size, + }) + .w(match dif { + 6 => 12.0 * size, + _ => 4.0 * size * dif as f64, + }) + .h(match dif { + 6 => 12.0 * size, + _ => 4.0 * size, + }) + .color(Some(match dif { + 1 => QUALITY_LOW, + 2 => QUALITY_COMMON, + 3 => QUALITY_MODERATE, + 4 => QUALITY_HIGH, + 5 => QUALITY_EPIC, + 6 => TEXT_COLOR, + _ => TEXT_COLOR, + })); + match &site.kind { + SiteKind::Town => { + if self.show.map_towns { + dif_img.set(state.ids.site_difs[i], ui) + } + }, + SiteKind::Dungeon => { + if self.show.map_dungeons { + dif_img.set(state.ids.site_difs[i], ui) + } + }, + SiteKind::Castle => { + if self.show.map_castles { + dif_img.set(state.ids.site_difs[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 @@ -518,13 +627,14 @@ Text::new("Dungeons") (e as f64 / sz).clamped(0.0, 1.0) });*/ //let xy = rel * 760.0; - let rpos = drag.map(|e| (e * zoom_lvl) as f32 / 2.0); + let rpos = drag.map(|e| (e * zoom_lvl) as f32 / tweak!(2.6)); if !rpos - .map2(map_size, |e, sz| e.abs() > sz as f32 / 1.67) + .map2(map_size, |e, sz| e > sz as f32 / tweak!(1.67)) .reduce_or() { let scale = 0.6; let arrow_sz = Vec2::new(32.0, 37.0) * scale; + if drag.x == 0.0 && drag.y == 0.0 { Image::new(self.rot_imgs.indicator_mmap_small.target_north) //.top_left_with_margins_on(state.ids.grid, 407.0 - drag.y * zoom_lvl, 417.0 + drag.x * zoom_lvl) .x_y_position_relative_to( @@ -535,8 +645,18 @@ Text::new("Dungeons") .w_h(arrow_sz.x, arrow_sz.y) .color(Some(UI_HIGHLIGHT_0)) .floating(true) - .parent(ui.window) - .set(state.ids.indicator, ui); + //.parent(ui.window) + .set(state.ids.indicator, ui);} + } + + if drag.x != 0.0 || drag.y != 0.0 { + Text::new("Press [Space] to recenter the map to your location.") + .mid_bottom_with_margin_on(state.ids.grid, tweak!(-20.0)) + .font_size(self.fonts.cyri.scale(14)) + .font_id(self.fonts.cyri.conrod_id) + .graphics_for(state.ids.grid) + .color(TEXT_COLOR) + .set(state.ids.drag_txt, ui); } events diff --git a/voxygen/src/hud/minimap.rs b/voxygen/src/hud/minimap.rs index 9e6c1bc788..b01fe92d83 100644 --- a/voxygen/src/hud/minimap.rs +++ b/voxygen/src/hud/minimap.rs @@ -292,7 +292,7 @@ impl<'a> Widget for MiniMap<'a> { Color::Rgba(0.75, 0.0, 0.0, 1.0) } else { TEXT_COLOR - }) + }) .parent(ui.window) .set(*id, ui); } diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index a222287741..4198c4abe5 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -70,11 +70,13 @@ use common::{ terrain::TerrainChunk, vol::RectRasterableVol, }; +use common::util::srgba_to_linear; use conrod_core::{ text::cursor::Index, widget::{self, Button, Image, Text}, widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, Widget, }; +use inline_tweak::*; use specs::{Join, WorldExt}; use std::{ collections::{HashMap, VecDeque}, @@ -467,7 +469,7 @@ impl Show { fn toggle_bag(&mut self) { self.bag(!self.bag); } fn map(&mut self, open: bool) { - if !self.esc_menu { + if !self.esc_menu { self.map = open; self.bag = false; self.crafting = false; @@ -503,8 +505,7 @@ impl Show { } } - fn toggle_map(&mut self) { - self.map(!self.map) } + fn toggle_map(&mut self) { self.map(!self.map) } fn toggle_mini_map(&mut self) { self.mini_map = !self.mini_map; } @@ -625,7 +626,7 @@ pub struct Hud { force_chat_input: Option, force_chat_cursor: Option, tab_complete: Option, - pulse: f32, + pulse: f32, velocity: f32, i18n: std::sync::Arc, slot_manager: slots::SlotManager, @@ -645,8 +646,7 @@ impl Hud { let ids = Ids::new(ui.id_generator()); // NOTE: Use a border the same color as the LOD ocean color (but with a // translucent alpha since UI have transparency and LOD doesn't). - let mut water_color = lod::water_color(); - water_color.a = 0.5; + let water_color = srgba_to_linear(Rgba::new(0.0, tweak!(0.18), tweak!(0.37), tweak!(1.0))); // Load world map let world_map = ( ui.add_graphic_with_rotations(Graphic::Image( @@ -729,7 +729,7 @@ impl Hud { force_chat_input: None, force_chat_cursor: None, tab_complete: None, - pulse: 0.0, + pulse: 0.0, velocity: 0.0, i18n, slot_manager, @@ -2261,7 +2261,7 @@ impl Hud { self.pulse, &self.i18n, &global_state, - tooltip_manager, + tooltip_manager, ) .set(self.ids.map, ui_widgets) { @@ -2269,20 +2269,14 @@ impl Hud { map::Event::Close => { self.show.map(false); self.show.want_grab = true; - self.force_ungrab = false; + self.force_ungrab = false; }, map::Event::ShowDifficulties => { self.show.map_difficulty = !self.show.map_difficulty }, - map::Event::ShowTowns => { - self.show.map_towns = !self.show.map_towns - }, - map::Event::ShowCastles => { - self.show.map_castles = !self.show.map_castles - }, - map::Event::ShowDungeons => { - self.show.map_dungeons = !self.show.map_dungeons - }, + map::Event::ShowTowns => self.show.map_towns = !self.show.map_towns, + map::Event::ShowCastles => self.show.map_castles = !self.show.map_castles, + map::Event::ShowDungeons => self.show.map_dungeons = !self.show.map_dungeons, map::Event::MapZoom(map_zoom) => { events.push(Event::MapZoom(map_zoom)); }, diff --git a/voxygen/src/render/mod.rs b/voxygen/src/render/mod.rs index 57d57ebdf3..245734d67c 100644 --- a/voxygen/src/render/mod.rs +++ b/voxygen/src/render/mod.rs @@ -112,13 +112,17 @@ impl Default for AaMode { pub enum CloudMode { /// No clouds. As cheap as it gets. None, - /// Clouds, but barely. Ideally, any machine should be able to handle this just fine. + /// Clouds, but barely. Ideally, any machine should be able to handle this + /// just fine. Minimal, - /// Enough visual detail to be pleasing, but generally using poor-but-cheap approximations to derive parameters + /// Enough visual detail to be pleasing, but generally using poor-but-cheap + /// approximations to derive parameters Low, - /// More detail. Enough to look good in most cases. For those that value looks but also high framerates. + /// More detail. Enough to look good in most cases. For those that value + /// looks but also high framerates. Medium, - /// High, but with extra compute power thrown at it to smooth out subtle imperfections + /// High, but with extra compute power thrown at it to smooth out subtle + /// imperfections Ultra, /// Lots of detail with good-but-costly derivation of parameters. #[serde(other)] diff --git a/voxygen/src/settings.rs b/voxygen/src/settings.rs index 7949ff3cfa..3da82fd38a 100644 --- a/voxygen/src/settings.rs +++ b/voxygen/src/settings.rs @@ -10,8 +10,8 @@ use hashbrown::{HashMap, HashSet}; use serde::{Deserialize, Serialize}; use std::{fs, path::PathBuf}; use tracing::warn; -use winit::event::{MouseButton, VirtualKeyCode}; use vek::*; +use winit::event::{MouseButton, VirtualKeyCode}; // ControlSetting-like struct used by Serde, to handle not serializing/building // post-deserializing the inverse_keybindings hashmap #[derive(Serialize, Deserialize)] @@ -548,7 +548,7 @@ impl Default for GameplaySettings { auto_walk_behavior: PressBehavior::Toggle, stop_auto_walk_on_input: true, map_zoom: 4.0, - map_drag: Vec2 { x: 0.0, y: 0.0}, + map_drag: Vec2 { x: 0.0, y: 0.0 }, loading_tips: true, } }