mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added map marker
This commit is contained in:
parent
4d09180ddb
commit
d0953fcab0
@ -50,6 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- You can now block and parry with melee weapons
|
- You can now block and parry with melee weapons
|
||||||
- Lift is now calculated for gliders based on dimensions (currently same for all)
|
- Lift is now calculated for gliders based on dimensions (currently same for all)
|
||||||
- Specific music tracks can now play exclusively in towns.
|
- Specific music tracks can now play exclusively in towns.
|
||||||
|
- Custom map markers can be placed now
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
BIN
assets/voxygen/element/ui/generic/icons/m_click.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/element/ui/generic/icons/m_click.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/element/ui/generic/icons/m_scroll.png
(Stored with Git LFS)
Normal file → Executable file
BIN
assets/voxygen/element/ui/generic/icons/m_scroll.png
(Stored with Git LFS)
Normal file → Executable file
Binary file not shown.
BIN
assets/voxygen/element/ui/map/buttons/location_marker.png
(Stored with Git LFS)
Executable file
BIN
assets/voxygen/element/ui/map/buttons/location_marker.png
(Stored with Git LFS)
Executable file
Binary file not shown.
@ -21,7 +21,10 @@
|
|||||||
"hud.map.difficulty_dungeon": "Dungeon\n\nDifficulty: {difficulty}",
|
"hud.map.difficulty_dungeon": "Dungeon\n\nDifficulty: {difficulty}",
|
||||||
"hud.map.drag": "Drag",
|
"hud.map.drag": "Drag",
|
||||||
"hud.map.zoom": "Zoom",
|
"hud.map.zoom": "Zoom",
|
||||||
|
"hud.map.mid_click": "Set Waypoint",
|
||||||
"hud.map.recenter": "Recenter",
|
"hud.map.recenter": "Recenter",
|
||||||
|
"hud.map.marked_location": "Marked Location",
|
||||||
|
"hud.map.marked_location_remove": "Click to remove",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
@ -308,6 +308,7 @@ image_ids! {
|
|||||||
m2_ico: "voxygen.element.ui.generic.icons.m2",
|
m2_ico: "voxygen.element.ui.generic.icons.m2",
|
||||||
m_scroll_ico: "voxygen.element.ui.generic.icons.m_scroll",
|
m_scroll_ico: "voxygen.element.ui.generic.icons.m_scroll",
|
||||||
m_move_ico: "voxygen.element.ui.generic.icons.m_move",
|
m_move_ico: "voxygen.element.ui.generic.icons.m_move",
|
||||||
|
m_click_ico: "voxygen.element.ui.generic.icons.m_click",
|
||||||
skillbar_slot: "voxygen.element.ui.skillbar.slot",
|
skillbar_slot: "voxygen.element.ui.skillbar.slot",
|
||||||
|
|
||||||
// Other Icons/Art
|
// Other Icons/Art
|
||||||
@ -337,6 +338,7 @@ image_ids! {
|
|||||||
indicator_group: "voxygen.element.ui.map.buttons.group_indicator",
|
indicator_group: "voxygen.element.ui.map.buttons.group_indicator",
|
||||||
indicator_group_up: "voxygen.element.ui.map.buttons.group_indicator_arrow_up",
|
indicator_group_up: "voxygen.element.ui.map.buttons.group_indicator_arrow_up",
|
||||||
indicator_group_down: "voxygen.element.ui.map.buttons.group_indicator_arrow_down",
|
indicator_group_down: "voxygen.element.ui.map.buttons.group_indicator_arrow_down",
|
||||||
|
location_marker: "voxygen.element.ui.map.buttons.location_marker",
|
||||||
map_mode_overlay: "voxygen.element.ui.map.buttons.map_modes",
|
map_mode_overlay: "voxygen.element.ui.map.buttons.map_modes",
|
||||||
|
|
||||||
// MiniMap
|
// MiniMap
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::{
|
use super::{
|
||||||
img_ids::{Imgs, ImgsRot},
|
img_ids::{Imgs, ImgsRot},
|
||||||
QUALITY_COMMON, QUALITY_DEBUG, QUALITY_EPIC, QUALITY_HIGH, QUALITY_LOW, QUALITY_MODERATE,
|
Show, QUALITY_COMMON, QUALITY_DEBUG, QUALITY_EPIC, QUALITY_HIGH, QUALITY_LOW, QUALITY_MODERATE,
|
||||||
TEXT_COLOR, TEXT_GRAY_COLOR, UI_HIGHLIGHT_0, UI_MAIN,
|
TEXT_COLOR, TEXT_GRAY_COLOR, TEXT_VELORITE, UI_HIGHLIGHT_0, UI_MAIN,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
i18n::Localization,
|
i18n::Localization,
|
||||||
@ -40,6 +40,7 @@ widget_ids! {
|
|||||||
site_difs[],
|
site_difs[],
|
||||||
member_indicators[],
|
member_indicators[],
|
||||||
member_height_indicators[],
|
member_height_indicators[],
|
||||||
|
location_marker,
|
||||||
map_settings_align,
|
map_settings_align,
|
||||||
show_towns_img,
|
show_towns_img,
|
||||||
show_towns_box,
|
show_towns_box,
|
||||||
@ -64,6 +65,8 @@ widget_ids! {
|
|||||||
drag_ico,
|
drag_ico,
|
||||||
zoom_txt,
|
zoom_txt,
|
||||||
zoom_ico,
|
zoom_ico,
|
||||||
|
waypoint_ico,
|
||||||
|
waypoint_txt,
|
||||||
map_mode_btn,
|
map_mode_btn,
|
||||||
map_mode_overlay,
|
map_mode_overlay,
|
||||||
}
|
}
|
||||||
@ -73,6 +76,7 @@ const SHOW_ECONOMY: bool = false; // turn this display off (for 0.9) until we ha
|
|||||||
|
|
||||||
#[derive(WidgetCommon)]
|
#[derive(WidgetCommon)]
|
||||||
pub struct Map<'a> {
|
pub struct Map<'a> {
|
||||||
|
show: &'a Show,
|
||||||
client: &'a Client,
|
client: &'a Client,
|
||||||
world_map: &'a (Vec<img_ids::Rotations>, Vec2<u32>),
|
world_map: &'a (Vec<img_ids::Rotations>, Vec2<u32>),
|
||||||
imgs: &'a Imgs,
|
imgs: &'a Imgs,
|
||||||
@ -84,10 +88,12 @@ pub struct Map<'a> {
|
|||||||
global_state: &'a GlobalState,
|
global_state: &'a GlobalState,
|
||||||
rot_imgs: &'a ImgsRot,
|
rot_imgs: &'a ImgsRot,
|
||||||
tooltip_manager: &'a mut TooltipManager,
|
tooltip_manager: &'a mut TooltipManager,
|
||||||
|
location_marker: Option<Vec2<f32>>,
|
||||||
}
|
}
|
||||||
impl<'a> Map<'a> {
|
impl<'a> Map<'a> {
|
||||||
#[allow(clippy::too_many_arguments)] // TODO: Pending review in #587
|
#[allow(clippy::too_many_arguments)] // TODO: Pending review in #587
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
show: &'a Show,
|
||||||
client: &'a Client,
|
client: &'a Client,
|
||||||
imgs: &'a Imgs,
|
imgs: &'a Imgs,
|
||||||
rot_imgs: &'a ImgsRot,
|
rot_imgs: &'a ImgsRot,
|
||||||
@ -97,8 +103,10 @@ impl<'a> Map<'a> {
|
|||||||
localized_strings: &'a Localization,
|
localized_strings: &'a Localization,
|
||||||
global_state: &'a GlobalState,
|
global_state: &'a GlobalState,
|
||||||
tooltip_manager: &'a mut TooltipManager,
|
tooltip_manager: &'a mut TooltipManager,
|
||||||
|
location_marker: Option<Vec2<f32>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
show,
|
||||||
imgs,
|
imgs,
|
||||||
rot_imgs,
|
rot_imgs,
|
||||||
world_map,
|
world_map,
|
||||||
@ -109,6 +117,7 @@ impl<'a> Map<'a> {
|
|||||||
localized_strings,
|
localized_strings,
|
||||||
global_state,
|
global_state,
|
||||||
tooltip_manager,
|
tooltip_manager,
|
||||||
|
location_marker,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,6 +130,8 @@ pub enum Event {
|
|||||||
SettingsChange(InterfaceChange),
|
SettingsChange(InterfaceChange),
|
||||||
Close,
|
Close,
|
||||||
RequestSiteInfo(SiteId),
|
RequestSiteInfo(SiteId),
|
||||||
|
SetLocationMarker(Vec2<f32>),
|
||||||
|
ToggleMarker,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_site_economy(site_rich: &SiteInfoRich) -> String {
|
fn get_site_economy(site_rich: &SiteInfoRich) -> String {
|
||||||
@ -273,12 +284,6 @@ impl<'a> Widget for Map<'a> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Image::new(self.imgs.map_frame_art)
|
|
||||||
.mid_top_with_margin_on(state.ids.map_align, 5.0)
|
|
||||||
.w_h(765.0, 765.0)
|
|
||||||
.parent(state.ids.bg)
|
|
||||||
.set(state.ids.map_layers[0], ui);
|
|
||||||
|
|
||||||
// Map Size
|
// Map Size
|
||||||
let worldsize = self.world_map.1;
|
let worldsize = self.world_map.1;
|
||||||
|
|
||||||
@ -298,6 +303,7 @@ impl<'a> Widget for Map<'a> {
|
|||||||
|
|
||||||
let w_src = max_zoom / zoom;
|
let w_src = max_zoom / zoom;
|
||||||
let h_src = max_zoom / zoom;
|
let h_src = max_zoom / zoom;
|
||||||
|
|
||||||
// Handle dragging
|
// Handle dragging
|
||||||
let drag = self.global_state.settings.interface.map_drag;
|
let drag = self.global_state.settings.interface.map_drag;
|
||||||
let dragged: Vec2<f64> = ui
|
let dragged: Vec2<f64> = ui
|
||||||
@ -318,6 +324,20 @@ impl<'a> Widget for Map<'a> {
|
|||||||
],
|
],
|
||||||
[w_src, h_src],
|
[w_src, h_src],
|
||||||
);
|
);
|
||||||
|
// Handle Location Marking
|
||||||
|
if let Some(click) = ui
|
||||||
|
.widget_input(state.ids.map_layers[0])
|
||||||
|
.clicks()
|
||||||
|
.middle()
|
||||||
|
.next()
|
||||||
|
{
|
||||||
|
events.push(Event::SetLocationMarker(
|
||||||
|
(Vec2::<f64>::from(click.xy) / map_size / zoom * max_zoom - drag)
|
||||||
|
.map2(TerrainChunkSize::RECT_SIZE, |e, sz| e as f32 * sz as f32)
|
||||||
|
+ player_pos,
|
||||||
|
));
|
||||||
|
events.push(Event::ToggleMarker);
|
||||||
|
}
|
||||||
// X-Button
|
// X-Button
|
||||||
if Button::image(self.imgs.close_button)
|
if Button::image(self.imgs.close_button)
|
||||||
.w_h(24.0, 25.0)
|
.w_h(24.0, 25.0)
|
||||||
@ -333,14 +353,14 @@ impl<'a> Widget for Map<'a> {
|
|||||||
// Map Layer Images
|
// Map Layer Images
|
||||||
for (index, layer) in self.world_map.0.iter().enumerate() {
|
for (index, layer) in self.world_map.0.iter().enumerate() {
|
||||||
if index == 0 {
|
if index == 0 {
|
||||||
Image::new(layer.none)
|
Button::image(layer.none)
|
||||||
.mid_top_with_margin_on(state.ids.map_align, 10.0)
|
.mid_top_with_margin_on(state.ids.map_align, 10.0)
|
||||||
.w_h(map_size.x, map_size.y)
|
.w_h(map_size.x, map_size.y)
|
||||||
.parent(state.ids.bg)
|
.parent(state.ids.bg)
|
||||||
.source_rectangle(rect_src)
|
.source_rectangle(rect_src)
|
||||||
.set(state.ids.map_layers[index], ui);
|
.set(state.ids.map_layers[index], ui);
|
||||||
} else if show_topo_map {
|
} else if show_topo_map {
|
||||||
Image::new(layer.none)
|
Button::image(layer.none)
|
||||||
.mid_top_with_margin_on(state.ids.map_align, 10.0)
|
.mid_top_with_margin_on(state.ids.map_align, 10.0)
|
||||||
.w_h(map_size.x, map_size.y)
|
.w_h(map_size.x, map_size.y)
|
||||||
.parent(state.ids.bg)
|
.parent(state.ids.bg)
|
||||||
@ -587,10 +607,10 @@ impl<'a> Widget for Map<'a> {
|
|||||||
.resize(self.client.sites().len(), &mut ui.widget_id_generator())
|
.resize(self.client.sites().len(), &mut ui.widget_id_generator())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for (i, site_rich) in self.client.sites().values().enumerate() {
|
|
||||||
let site = &site_rich.site;
|
let wpos_to_rpos = |wpos: Vec2<f32>| {
|
||||||
// Site pos in world coordinates relative to the player
|
// Site pos in world coordinates relative to the player
|
||||||
let rwpos = site.wpos.map(|e| e as f32) - player_pos;
|
let rwpos = wpos - player_pos;
|
||||||
// Convert to chunk coordinates
|
// Convert to chunk coordinates
|
||||||
let rcpos = rwpos.map2(TerrainChunkSize::RECT_SIZE, |e, sz| e / sz as f32)
|
let rcpos = rwpos.map2(TerrainChunkSize::RECT_SIZE, |e, sz| e / sz as f32)
|
||||||
// Add map dragging
|
// Add map dragging
|
||||||
@ -600,14 +620,27 @@ impl<'a> Widget for Map<'a> {
|
|||||||
// Convert to relative pixel coordinates from the center of the map
|
// Convert to relative pixel coordinates from the center of the map
|
||||||
// Accounting for zooming
|
// Accounting for zooming
|
||||||
let rpos = rfpos.map2(map_size, |e, sz| e * sz as f32 * zoom as f32);
|
let rpos = rfpos.map2(map_size, |e, sz| e * sz as f32 * zoom as f32);
|
||||||
let rside = zoom * 6.0;
|
|
||||||
|
|
||||||
if rpos
|
if rpos
|
||||||
.map2(map_size, |e, sz| e.abs() > sz as f32 / 2.0)
|
.map2(map_size, |e, sz| e.abs() > sz as f32 / 2.0)
|
||||||
.reduce_or()
|
.reduce_or()
|
||||||
{
|
{
|
||||||
continue;
|
None
|
||||||
|
} else {
|
||||||
|
Some(rpos)
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i, site_rich) in self.client.sites().values().enumerate() {
|
||||||
|
let site = &site_rich.site;
|
||||||
|
|
||||||
|
let rpos = match wpos_to_rpos(site.wpos.map(|e| e as f32)) {
|
||||||
|
Some(rpos) => rpos,
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
|
||||||
|
let rside = zoom * 6.0;
|
||||||
|
|
||||||
let title = site.name.as_deref().unwrap_or_else(|| match &site.kind {
|
let title = site.name.as_deref().unwrap_or_else(|| match &site.kind {
|
||||||
SiteKind::Town => i18n.get("hud.map.town"),
|
SiteKind::Town => i18n.get("hud.map.town"),
|
||||||
SiteKind::Dungeon { .. } => i18n.get("hud.map.dungeon"),
|
SiteKind::Dungeon { .. } => i18n.get("hud.map.dungeon"),
|
||||||
@ -783,24 +816,11 @@ impl<'a> Widget for Map<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(member_pos) = member_pos {
|
if let Some(member_pos) = member_pos {
|
||||||
// Site pos in world coordinates relative to the player
|
let rpos = match wpos_to_rpos(member_pos.0.xy().map(|e| e as f32)) {
|
||||||
let rwpos = member_pos.0.xy().map(|e| e as f32) - player_pos;
|
Some(rpos) => rpos,
|
||||||
// Convert to chunk coordinates
|
None => continue,
|
||||||
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 factor = 1.2;
|
||||||
let z_comparison = (member_pos.0.z - player_pos.z) as i32;
|
let z_comparison = (member_pos.0.z - player_pos.z) as i32;
|
||||||
|
|
||||||
@ -820,6 +840,43 @@ impl<'a> Widget for Map<'a> {
|
|||||||
.set(state.ids.member_indicators[i], ui);
|
.set(state.ids.member_indicators[i], ui);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Location marker
|
||||||
|
if self.show.map_marker {
|
||||||
|
if let Some((lm, rpos)) = self
|
||||||
|
.location_marker
|
||||||
|
.and_then(|lm| Some(lm).zip(wpos_to_rpos(lm)))
|
||||||
|
{
|
||||||
|
let factor = 1.4;
|
||||||
|
|
||||||
|
if Button::image(self.imgs.location_marker)
|
||||||
|
.x_y_position_relative_to(
|
||||||
|
state.ids.map_layers[0],
|
||||||
|
position::Relative::Scalar(rpos.x as f64),
|
||||||
|
position::Relative::Scalar(rpos.y as f64 + 10.0 * factor),
|
||||||
|
)
|
||||||
|
.w_h(20.0 * factor, 20.0 * factor)
|
||||||
|
.floating(true)
|
||||||
|
.with_tooltip(
|
||||||
|
self.tooltip_manager,
|
||||||
|
i18n.get("hud.map.marked_location"),
|
||||||
|
&format!(
|
||||||
|
"X: {}, Y: {}\n\n{}",
|
||||||
|
lm.x as i32,
|
||||||
|
lm.y as i32,
|
||||||
|
i18n.get("hud.map.marked_location_remove")
|
||||||
|
),
|
||||||
|
&site_tooltip,
|
||||||
|
TEXT_VELORITE,
|
||||||
|
)
|
||||||
|
.set(state.ids.location_marker, ui)
|
||||||
|
.was_clicked()
|
||||||
|
{
|
||||||
|
events.push(Event::ToggleMarker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Cursor pos relative to playerpos and widget size
|
// Cursor pos relative to playerpos and widget size
|
||||||
// Cursor stops moving on an axis as soon as it's position exceeds the maximum
|
// Cursor stops moving on an axis as soon as it's position exceeds the maximum
|
||||||
// // size of the widget
|
// // size of the widget
|
||||||
@ -918,6 +975,18 @@ impl<'a> Widget for Map<'a> {
|
|||||||
.graphics_for(state.ids.map_layers[0])
|
.graphics_for(state.ids.map_layers[0])
|
||||||
.color(TEXT_COLOR)
|
.color(TEXT_COLOR)
|
||||||
.set(state.ids.zoom_txt, ui);
|
.set(state.ids.zoom_txt, ui);
|
||||||
|
Image::new(self.imgs.m_click_ico)
|
||||||
|
.right_from(state.ids.zoom_txt, 5.0)
|
||||||
|
.w_h(icon_size.x, icon_size.y)
|
||||||
|
.color(Some(UI_HIGHLIGHT_0))
|
||||||
|
.set(state.ids.waypoint_ico, ui);
|
||||||
|
Text::new(i18n.get("hud.map.mid_click"))
|
||||||
|
.right_from(state.ids.waypoint_ico, 5.0)
|
||||||
|
.font_size(self.fonts.cyri.scale(14))
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.graphics_for(state.ids.map_layers[0])
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.set(state.ids.waypoint_txt, ui);
|
||||||
|
|
||||||
// Show topographic map
|
// Show topographic map
|
||||||
if Button::image(self.imgs.button)
|
if Button::image(self.imgs.button)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use super::{
|
use super::{
|
||||||
img_ids::{Imgs, ImgsRot},
|
img_ids::{Imgs, ImgsRot},
|
||||||
QUALITY_COMMON, QUALITY_DEBUG, QUALITY_EPIC, QUALITY_HIGH, QUALITY_LOW, QUALITY_MODERATE,
|
Show, QUALITY_COMMON, QUALITY_DEBUG, QUALITY_EPIC, QUALITY_HIGH, QUALITY_LOW, QUALITY_MODERATE,
|
||||||
TEXT_COLOR, UI_HIGHLIGHT_0, UI_MAIN,
|
TEXT_COLOR, UI_HIGHLIGHT_0, UI_MAIN,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -39,13 +39,14 @@ widget_ids! {
|
|||||||
mmap_site_icons_bgs[],
|
mmap_site_icons_bgs[],
|
||||||
mmap_site_icons[],
|
mmap_site_icons[],
|
||||||
member_indicators[],
|
member_indicators[],
|
||||||
|
location_marker,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(WidgetCommon)]
|
#[derive(WidgetCommon)]
|
||||||
pub struct MiniMap<'a> {
|
pub struct MiniMap<'a> {
|
||||||
|
show: &'a Show,
|
||||||
client: &'a Client,
|
client: &'a Client,
|
||||||
|
|
||||||
imgs: &'a Imgs,
|
imgs: &'a Imgs,
|
||||||
rot_imgs: &'a ImgsRot,
|
rot_imgs: &'a ImgsRot,
|
||||||
world_map: &'a (Vec<img_ids::Rotations>, Vec2<u32>),
|
world_map: &'a (Vec<img_ids::Rotations>, Vec2<u32>),
|
||||||
@ -54,10 +55,12 @@ pub struct MiniMap<'a> {
|
|||||||
common: widget::CommonBuilder,
|
common: widget::CommonBuilder,
|
||||||
ori: Vec3<f32>,
|
ori: Vec3<f32>,
|
||||||
global_state: &'a GlobalState,
|
global_state: &'a GlobalState,
|
||||||
|
location_marker: Option<Vec2<f32>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> MiniMap<'a> {
|
impl<'a> MiniMap<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
show: &'a Show,
|
||||||
client: &'a Client,
|
client: &'a Client,
|
||||||
imgs: &'a Imgs,
|
imgs: &'a Imgs,
|
||||||
rot_imgs: &'a ImgsRot,
|
rot_imgs: &'a ImgsRot,
|
||||||
@ -65,8 +68,10 @@ impl<'a> MiniMap<'a> {
|
|||||||
fonts: &'a Fonts,
|
fonts: &'a Fonts,
|
||||||
ori: Vec3<f32>,
|
ori: Vec3<f32>,
|
||||||
global_state: &'a GlobalState,
|
global_state: &'a GlobalState,
|
||||||
|
location_marker: Option<Vec2<f32>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
show,
|
||||||
client,
|
client,
|
||||||
imgs,
|
imgs,
|
||||||
rot_imgs,
|
rot_imgs,
|
||||||
@ -75,6 +80,7 @@ impl<'a> MiniMap<'a> {
|
|||||||
common: widget::CommonBuilder::default(),
|
common: widget::CommonBuilder::default(),
|
||||||
ori,
|
ori,
|
||||||
global_state,
|
global_state,
|
||||||
|
location_marker,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -289,10 +295,10 @@ impl<'a> Widget for MiniMap<'a> {
|
|||||||
.resize(self.client.sites().len(), &mut ui.widget_id_generator())
|
.resize(self.client.sites().len(), &mut ui.widget_id_generator())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for (i, site_rich) in self.client.sites().values().enumerate() {
|
|
||||||
let site = &site_rich.site;
|
let wpos_to_rpos = |wpos: Vec2<f32>, limit: bool| {
|
||||||
// Site pos in world coordinates relative to the player
|
// Site pos in world coordinates relative to the player
|
||||||
let rwpos = site.wpos.map(|e| e as f32) - player_pos;
|
let rwpos = wpos - player_pos;
|
||||||
// Convert to chunk coordinates
|
// Convert to chunk coordinates
|
||||||
let rcpos = rwpos.map2(TerrainChunkSize::RECT_SIZE, |e, sz| e / sz as f32);
|
let rcpos = rwpos.map2(TerrainChunkSize::RECT_SIZE, |e, sz| e / sz as f32);
|
||||||
// Convert to fractional coordinates relative to the worldsize
|
// Convert to fractional coordinates relative to the worldsize
|
||||||
@ -308,8 +314,22 @@ impl<'a> Widget for MiniMap<'a> {
|
|||||||
.map2(map_size, |e, sz| e.abs() > sz as f32 / 2.0)
|
.map2(map_size, |e, sz| e.abs() > sz as f32 / 2.0)
|
||||||
.reduce_or()
|
.reduce_or()
|
||||||
{
|
{
|
||||||
continue;
|
limit.then(|| {
|
||||||
|
let clamped = rpos / rpos.map(|e| e.abs()).reduce_partial_max();
|
||||||
|
clamped * map_size.map(|e| e as f32) / 2.0
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Some(rpos)
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i, site_rich) in self.client.sites().values().enumerate() {
|
||||||
|
let site = &site_rich.site;
|
||||||
|
|
||||||
|
let rpos = match wpos_to_rpos(site.wpos.map(|e| e as f32), false) {
|
||||||
|
Some(rpos) => rpos,
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
|
||||||
Image::new(match &site.kind {
|
Image::new(match &site.kind {
|
||||||
SiteKind::Town => self.imgs.mmap_site_town_bg,
|
SiteKind::Town => self.imgs.mmap_site_town_bg,
|
||||||
@ -382,25 +402,11 @@ impl<'a> Widget for MiniMap<'a> {
|
|||||||
let member_pos = entity.and_then(|entity| member_pos.get(entity));
|
let member_pos = entity.and_then(|entity| member_pos.get(entity));
|
||||||
|
|
||||||
if let Some(member_pos) = member_pos {
|
if let Some(member_pos) = member_pos {
|
||||||
// Site pos in world coordinates relative to the player
|
let rpos = match wpos_to_rpos(member_pos.0.xy().map(|e| e as f32), false) {
|
||||||
let rwpos = member_pos.0.xy().map(|e| e as f32) - player_pos;
|
Some(rpos) => rpos,
|
||||||
// Convert to chunk coordinates
|
None => continue,
|
||||||
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(orientation.x) * rpixpos.x
|
|
||||||
+ Vec2::unit_y().rotated_z(orientation.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 factor = 1.2;
|
||||||
let z_comparison = (member_pos.0.z - player_pos.z) as i32;
|
let z_comparison = (member_pos.0.z - player_pos.z) as i32;
|
||||||
Button::image(match z_comparison {
|
Button::image(match z_comparison {
|
||||||
@ -419,6 +425,23 @@ impl<'a> Widget for MiniMap<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Location marker
|
||||||
|
if self.show.map_marker {
|
||||||
|
if let Some(rpos) = self.location_marker.and_then(|lm| wpos_to_rpos(lm, true)) {
|
||||||
|
let factor = 1.2;
|
||||||
|
|
||||||
|
Button::image(self.imgs.location_marker)
|
||||||
|
.x_y_position_relative_to(
|
||||||
|
state.ids.map_layers[0],
|
||||||
|
position::Relative::Scalar(rpos.x as f64),
|
||||||
|
position::Relative::Scalar(rpos.y as f64 + 8.0 * factor),
|
||||||
|
)
|
||||||
|
.w_h(16.0 * factor, 16.0 * factor)
|
||||||
|
//.image_color(Color::Rgba(1.0, 1.0, 1.0, 1.0))
|
||||||
|
.floating(true)
|
||||||
|
.set(state.ids.location_marker, ui);
|
||||||
|
}
|
||||||
|
}
|
||||||
// Indicator
|
// Indicator
|
||||||
let ind_scale = 0.4;
|
let ind_scale = 0.4;
|
||||||
let ind_rotation = if is_facing_north {
|
let ind_rotation = if is_facing_north {
|
||||||
|
@ -104,6 +104,7 @@ use std::{
|
|||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
const TEXT_COLOR: Color = Color::Rgba(1.0, 1.0, 1.0, 1.0);
|
const TEXT_COLOR: Color = Color::Rgba(1.0, 1.0, 1.0, 1.0);
|
||||||
|
const TEXT_VELORITE: Color = Color::Rgba(0.0, 0.66, 0.66, 1.0);
|
||||||
const TEXT_GRAY_COLOR: Color = Color::Rgba(0.5, 0.5, 0.5, 1.0);
|
const TEXT_GRAY_COLOR: Color = Color::Rgba(0.5, 0.5, 0.5, 1.0);
|
||||||
const TEXT_DULL_RED_COLOR: Color = Color::Rgba(0.56, 0.2, 0.2, 1.0);
|
const TEXT_DULL_RED_COLOR: Color = Color::Rgba(0.56, 0.2, 0.2, 1.0);
|
||||||
const TEXT_BG: Color = Color::Rgba(0.0, 0.0, 0.0, 1.0);
|
const TEXT_BG: Color = Color::Rgba(0.0, 0.0, 0.0, 1.0);
|
||||||
@ -511,6 +512,8 @@ pub struct Show {
|
|||||||
auto_walk: bool,
|
auto_walk: bool,
|
||||||
camera_clamp: bool,
|
camera_clamp: bool,
|
||||||
prompt_dialog: Option<PromptDialogSettings>,
|
prompt_dialog: Option<PromptDialogSettings>,
|
||||||
|
location_marker: Option<Vec2<f32>>,
|
||||||
|
map_marker: bool,
|
||||||
}
|
}
|
||||||
impl Show {
|
impl Show {
|
||||||
fn bag(&mut self, open: bool) {
|
fn bag(&mut self, open: bool) {
|
||||||
@ -876,6 +879,8 @@ impl Hud {
|
|||||||
auto_walk: false,
|
auto_walk: false,
|
||||||
camera_clamp: false,
|
camera_clamp: false,
|
||||||
prompt_dialog: None,
|
prompt_dialog: None,
|
||||||
|
location_marker: None,
|
||||||
|
map_marker: false,
|
||||||
},
|
},
|
||||||
to_focus: None,
|
to_focus: None,
|
||||||
//never_show: false,
|
//never_show: false,
|
||||||
@ -2289,6 +2294,7 @@ impl Hud {
|
|||||||
|
|
||||||
// MiniMap
|
// MiniMap
|
||||||
for event in MiniMap::new(
|
for event in MiniMap::new(
|
||||||
|
&self.show,
|
||||||
client,
|
client,
|
||||||
&self.imgs,
|
&self.imgs,
|
||||||
&self.rot_imgs,
|
&self.rot_imgs,
|
||||||
@ -2296,6 +2302,7 @@ impl Hud {
|
|||||||
&self.fonts,
|
&self.fonts,
|
||||||
camera.get_orientation(),
|
camera.get_orientation(),
|
||||||
&global_state,
|
&global_state,
|
||||||
|
self.show.location_marker,
|
||||||
)
|
)
|
||||||
.set(self.ids.minimap, ui_widgets)
|
.set(self.ids.minimap, ui_widgets)
|
||||||
{
|
{
|
||||||
@ -2725,6 +2732,7 @@ impl Hud {
|
|||||||
// Map
|
// Map
|
||||||
if self.show.map {
|
if self.show.map {
|
||||||
for event in Map::new(
|
for event in Map::new(
|
||||||
|
&self.show,
|
||||||
client,
|
client,
|
||||||
&self.imgs,
|
&self.imgs,
|
||||||
&self.rot_imgs,
|
&self.rot_imgs,
|
||||||
@ -2734,6 +2742,7 @@ impl Hud {
|
|||||||
i18n,
|
i18n,
|
||||||
&global_state,
|
&global_state,
|
||||||
tooltip_manager,
|
tooltip_manager,
|
||||||
|
self.show.location_marker,
|
||||||
)
|
)
|
||||||
.set(self.ids.map, ui_widgets)
|
.set(self.ids.map, ui_widgets)
|
||||||
{
|
{
|
||||||
@ -2749,6 +2758,12 @@ impl Hud {
|
|||||||
map::Event::RequestSiteInfo(id) => {
|
map::Event::RequestSiteInfo(id) => {
|
||||||
events.push(Event::RequestSiteInfo(id));
|
events.push(Event::RequestSiteInfo(id));
|
||||||
},
|
},
|
||||||
|
map::Event::SetLocationMarker(pos) => {
|
||||||
|
self.show.location_marker = Some(pos);
|
||||||
|
},
|
||||||
|
map::Event::ToggleMarker => {
|
||||||
|
self.show.map_marker = !self.show.map_marker;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user