Add topographic option to map

This commit is contained in:
James Melkonian 2021-04-05 22:15:42 -07:00
parent f2ebbb7f7f
commit 16871208f2
13 changed files with 272 additions and 134 deletions

View File

@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Attacks now emit sound effects from the target on hit. - Attacks now emit sound effects from the target on hit.
- Crafting menu tabs - Crafting menu tabs
- Auto camera setting, making the game easier to play with one hand - Auto camera setting, making the game easier to play with one hand
- Topographic map option
### Changed ### Changed

View File

@ -31,7 +31,7 @@ debug = false
codegen-units = 8 codegen-units = 8
lto = false lto = false
# TEMP false to avoid fingerprints bug # TEMP false to avoid fingerprints bug
incremental = true incremental = false
# All dependencies (but not this crate itself) # All dependencies (but not this crate itself)
[profile.dev.package."*"] [profile.dev.package."*"]
opt-level = 3 opt-level = 3

BIN
assets/voxygen/element/map/topographic.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -6,6 +6,7 @@
// Map and Questlog // Map and Questlog
"hud.map.map_title": "Map", "hud.map.map_title": "Map",
"hud.map.qlog_title": "Quests", "hud.map.qlog_title": "Quests",
"hud.map.topo_map": "Topographic",
"hud.map.difficulty": "Difficulty", "hud.map.difficulty": "Difficulty",
"hud.map.towns": "Towns", "hud.map.towns": "Towns",
"hud.map.castles": "Castles", "hud.map.castles": "Castles",

View File

@ -34,7 +34,10 @@ use common::{
outcome::Outcome, outcome::Outcome,
recipe::RecipeBook, recipe::RecipeBook,
resources::{DeltaTime, PlayerEntity, TimeOfDay}, resources::{DeltaTime, PlayerEntity, TimeOfDay},
terrain::{block::Block, map::MapConfig, neighbors, BiomeKind, SitesKind, TerrainChunk, TerrainChunkSize}, terrain::{
block::Block, map::MapConfig, neighbors, BiomeKind, SitesKind, TerrainChunk,
TerrainChunkSize,
},
trade::{PendingTrade, SitePrices, TradeAction, TradeId, TradeResult}, trade::{PendingTrade, SitePrices, TradeAction, TradeId, TradeResult},
uid::{Uid, UidAllocator}, uid::{Uid, UidAllocator},
vol::RectVolSize, vol::RectVolSize,
@ -326,8 +329,9 @@ impl Client {
let horizons = [unzip_horizons(&west), unzip_horizons(&east)]; let horizons = [unzip_horizons(&west), unzip_horizons(&east)];
// Redraw map (with shadows this time). // Redraw map (with shadows this time).
let mut world_map_political = vec![0u32; rgba.size().product() as usize];
let mut world_map_rgba = vec![0u32; rgba.size().product() as usize]; let mut world_map_rgba = vec![0u32; rgba.size().product() as usize];
let mut world_map_political = vec![0u32; rgba.size().product() as usize];
let mut world_map_rgba_half_alpha = vec![0u32; rgba.size().product() as usize];
let mut world_map_topo = vec![0u32; rgba.size().product() as usize]; let mut world_map_topo = vec![0u32; rgba.size().product() as usize];
let mut map_config = common::terrain::map::MapConfig::orthographic( let mut map_config = common::terrain::map::MapConfig::orthographic(
map_size_lg, map_size_lg,
@ -341,121 +345,167 @@ impl Client {
&& pos.y < map_size.y as i32 && pos.y < map_size.y as i32
}; };
ping_stream.send(PingMsg::Ping)?; ping_stream.send(PingMsg::Ping)?;
fn sample_pos(map_config: &MapConfig, pos: Vec2<i32>, alt: &Grid<u32>, rgba: &Grid<u32>, map_size: &Vec2<u16>, map_size_lg: &common::terrain::MapSizeLg, max_height: f32) -> common::terrain::map::MapSample { fn sample_pos(
let rescale_height = |h: f32| h / max_height; map_config: &MapConfig,
let scale_height_big = |h: u32| (h >> 3) as f32 / 8191.0 * max_height; pos: Vec2<i32>,
let bounds_check = |pos: Vec2<i32>| { alt: &Grid<u32>,
pos.reduce_partial_min() >= 0 rgba: &Grid<u32>,
&& pos.x < map_size.x as i32 map_size: &Vec2<u16>,
&& pos.y < map_size.y as i32 map_size_lg: &common::terrain::MapSizeLg,
}; max_height: f32,
let MapConfig { ) -> common::terrain::map::MapSample {
gain, let rescale_height = |h: f32| h / max_height;
is_contours, let scale_height_big = |h: u32| (h >> 3) as f32 / 8191.0 * max_height;
is_height_map, let bounds_check = |pos: Vec2<i32>| {
is_political, pos.reduce_partial_min() >= 0
is_roads, && pos.x < map_size.x as i32
.. && pos.y < map_size.y as i32
} = *map_config; };
let mut is_contour_line = false; let MapConfig {
let mut is_border = false; gain,
let (rgba, alt, downhill_wpos) = if bounds_check(pos) { is_contours,
let posi = pos.y as usize * map_size.x as usize + pos.x as usize; is_height_map,
let [r, g, b, a] = rgba[pos].to_le_bytes(); is_political,
let is_water = r == 0 && b > 102 && g < 77; is_roads,
let alti = alt[pos]; rgba_alpha,
// Compute contours (chunks are assigned in the river code below) ..
let altj = rescale_height(scale_height_big(alti)); } = *map_config;
let contour_interval = 150.0; let mut is_contour_line = false;
let chunk_contour = (altj * gain / contour_interval) as u32; let mut is_border = false;
let (rgba, alt, downhill_wpos) = if bounds_check(pos) {
let posi = pos.y as usize * map_size.x as usize + pos.x as usize;
let [r, g, b, a] = rgba[pos].to_le_bytes();
let is_water = r == 0 && b > 102 && g < 77;
let alti = alt[pos];
// Compute contours (chunks are assigned in the river code below)
let altj = rescale_height(scale_height_big(alti));
let contour_interval = 150.0;
let chunk_contour = (altj * gain / contour_interval) as u32;
// Compute downhill. // Compute downhill.
let downhill = { let downhill = {
let mut best = -1; let mut best = -1;
let mut besth = alti; let mut besth = alti;
for nposi in neighbors(*map_size_lg, posi) { for nposi in neighbors(*map_size_lg, posi) {
let nbh = alt.raw()[nposi]; let nbh = alt.raw()[nposi];
let nalt = rescale_height(scale_height_big(nbh)); let nalt = rescale_height(scale_height_big(nbh));
let nchunk_contour = (nalt * gain / contour_interval) as u32; let nchunk_contour = (nalt * gain / contour_interval) as u32;
if !is_contour_line && chunk_contour > nchunk_contour { if !is_contour_line && chunk_contour > nchunk_contour {
is_contour_line = true; is_contour_line = true;
}
let [nr, ng, nb, _na] = rgba.raw()[nposi].to_le_bytes();
let n_is_water = nr == 0 && nb > 102 && ng < 77;
if !is_border && is_political && is_water && !n_is_water {
is_border = true;
}
if nbh < besth {
besth = nbh;
best = nposi as isize;
}
} }
best let [nr, ng, nb, _na] = rgba.raw()[nposi].to_le_bytes();
}; let n_is_water = nr == 0 && nb > 102 && ng < 77;
let downhill_wpos = if downhill < 0 {
None if !is_border && is_political && is_water && !n_is_water {
} else { is_border = true;
Some( }
Vec2::new(
(downhill as usize % map_size.x as usize) as i32, if nbh < besth {
(downhill as usize / map_size.x as usize) as i32, besth = nbh;
) * TerrainChunkSize::RECT_SIZE.map(|e| e as i32), best = nposi as isize;
) }
}; }
(Rgba::new(r, g, b, a), alti, downhill_wpos) best
} else {
(Rgba::zero(), 0, None)
}; };
let alt = f64::from(rescale_height(scale_height_big(alt))); let downhill_wpos = if downhill < 0 {
let wpos = pos * TerrainChunkSize::RECT_SIZE.map(|e| e as i32); None
let downhill_wpos = downhill_wpos
.unwrap_or(wpos + TerrainChunkSize::RECT_SIZE.map(|e| e as i32));
let is_path = rgba.r == 0x37 && rgba.g == 0x29 && rgba.b == 0x23;
let rgba = rgba.map(|e: u8| e as f64 / 255.0);
let rgba = if is_height_map {
if is_path {
// Path color is Rgb::new(0x37, 0x29, 0x23)
Rgba::new(0.9, 0.9, 0.63, 1.0)
} else if rgba.r == 0.0 && rgba.b > 0.4 && rgba.g < 0.3 {
// Water
Rgba::new(0.23, 0.47, 0.53, 0.5)
} else if is_contours && is_contour_line {
// Color contour lines
Rgba::new(0.15, 0.15, 0.15, 0.5)
} else {
// Color hill shading
let lightness = (alt + 0.2).min(1.0) as f64;
Rgba::new(lightness, 0.9 * lightness, 0.5 * lightness, 0.5)
}
} else if is_roads && is_path {
Rgba::new(0.9, 0.9, 0.63, 1.0)
} else if is_political {
if is_path {
Rgba::new(0.3, 0.3, 0.3, 1.0)
} else if is_border {
Rgba::new(0.0, 0.0, 0.0, 1.0)
} else {
Rgba::new(1.0, 0.9, 0.6, 1.0)
}
} else if is_contours && is_contour_line {
Rgba::new(0.15, 0.15, 0.15, 0.8)
} else { } else {
Rgba::new(rgba.r, rgba.g, rgba.b, 0.5) Some(
}.map(|e| (e * 255.0) as u8); Vec2::new(
common::terrain::map::MapSample { (downhill as usize % map_size.x as usize) as i32,
rgba, (downhill as usize / map_size.x as usize) as i32,
alt, ) * TerrainChunkSize::RECT_SIZE.map(|e| e as i32),
downhill_wpos, )
connections: None, };
is_path, (Rgba::new(r, g, b, a), alti, downhill_wpos)
} else {
(Rgba::zero(), 0, None)
};
let alt = f64::from(rescale_height(scale_height_big(alt)));
let wpos = pos * TerrainChunkSize::RECT_SIZE.map(|e| e as i32);
let downhill_wpos = downhill_wpos
.unwrap_or(wpos + TerrainChunkSize::RECT_SIZE.map(|e| e as i32));
let is_path = rgba.r == 0x37 && rgba.g == 0x29 && rgba.b == 0x23;
let rgba = rgba.map(|e: u8| e as f64 / 255.0);
let rgba = if is_height_map {
if is_path {
// Path color is Rgb::new(0x37, 0x29, 0x23)
Rgba::new(0.9, 0.9, 0.63, 1.0)
} else if rgba.r == 0.0 && rgba.b > 0.4 && rgba.g < 0.3 {
// Water
Rgba::new(0.23, 0.47, 0.53, 0.5)
} else if is_contours && is_contour_line {
// Color contour lines
Rgba::new(0.15, 0.15, 0.15, 0.5)
} else {
// Color hill shading
let lightness = (alt + 0.2).min(1.0) as f64;
Rgba::new(lightness, 0.9 * lightness, 0.5 * lightness, 0.5)
} }
} else if is_roads && is_path {
Rgba::new(0.9, 0.9, 0.63, 1.0)
} else if is_political {
if is_path {
Rgba::new(0.3, 0.3, 0.3, 1.0)
} else if is_border {
Rgba::new(0.0, 0.0, 0.0, 1.0)
} else {
Rgba::new(1.0, 0.9, 0.6, 1.0)
}
} else if is_contours && is_contour_line {
Rgba::new(0.15, 0.15, 0.15, 0.8)
} else {
Rgba::new(rgba.r, rgba.g, rgba.b, rgba_alpha)
}
.map(|e| (e * 255.0) as u8);
common::terrain::map::MapSample {
rgba,
alt,
downhill_wpos,
connections: None,
is_path,
}
} }
map_config.is_shaded = true; map_config.is_shaded = true;
map_config.rgba_alpha = 1.0;
map_config.generate(
|pos| {
sample_pos(
&map_config,
pos,
&alt,
&rgba,
&map_size,
&map_size_lg,
max_height,
)
},
|wpos| {
let pos = wpos.map2(TerrainChunkSize::RECT_SIZE, |e, f| e / f as i32);
rescale_height(if bounds_check(pos) {
scale_height_big(alt[pos])
} else {
0.0
})
},
|pos, (r, g, b, a)| {
world_map_rgba[pos.y * map_size.x as usize + pos.x] =
u32::from_le_bytes([r, g, b, a]);
},
);
map_config.is_political = true; map_config.is_political = true;
map_config.generate( map_config.generate(
|pos| sample_pos(&map_config, pos, &alt, &rgba, &map_size, &map_size_lg, max_height), |pos| {
sample_pos(
&map_config,
pos,
&alt,
&rgba,
&map_size,
&map_size_lg,
max_height,
)
},
|wpos| { |wpos| {
let pos = wpos.map2(TerrainChunkSize::RECT_SIZE, |e, f| e / f as i32); let pos = wpos.map2(TerrainChunkSize::RECT_SIZE, |e, f| e / f as i32);
rescale_height(if bounds_check(pos) { rescale_height(if bounds_check(pos) {
@ -471,9 +521,20 @@ impl Client {
); );
map_config.is_shaded = false; map_config.is_shaded = false;
map_config.rgba_alpha = 0.5;
map_config.is_political = false; map_config.is_political = false;
map_config.generate( map_config.generate(
|pos| sample_pos(&map_config, pos, &alt, &rgba, &map_size, &map_size_lg, max_height), |pos| {
sample_pos(
&map_config,
pos,
&alt,
&rgba,
&map_size,
&map_size_lg,
max_height,
)
},
|wpos| { |wpos| {
let pos = wpos.map2(TerrainChunkSize::RECT_SIZE, |e, f| e / f as i32); let pos = wpos.map2(TerrainChunkSize::RECT_SIZE, |e, f| e / f as i32);
rescale_height(if bounds_check(pos) { rescale_height(if bounds_check(pos) {
@ -483,7 +544,7 @@ impl Client {
}) })
}, },
|pos, (r, g, b, a)| { |pos, (r, g, b, a)| {
world_map_rgba[pos.y * map_size.x as usize + pos.x] = world_map_rgba_half_alpha[pos.y * map_size.x as usize + pos.x] =
u32::from_le_bytes([r, g, b, a]); u32::from_le_bytes([r, g, b, a]);
}, },
); );
@ -491,7 +552,17 @@ impl Client {
map_config.is_contours = true; map_config.is_contours = true;
map_config.is_roads = true; map_config.is_roads = true;
map_config.generate( map_config.generate(
|pos| sample_pos(&map_config, pos, &alt, &rgba, &map_size, &map_size_lg, max_height), |pos| {
sample_pos(
&map_config,
pos,
&alt,
&rgba,
&map_size,
&map_size_lg,
max_height,
)
},
|wpos| { |wpos| {
let pos = wpos.map2(TerrainChunkSize::RECT_SIZE, |e, f| e / f as i32); let pos = wpos.map2(TerrainChunkSize::RECT_SIZE, |e, f| e / f as i32);
rescale_height(if bounds_check(pos) { rescale_height(if bounds_check(pos) {
@ -525,9 +596,15 @@ impl Client {
let lod_base = rgba; let lod_base = rgba;
let lod_alt = alt; let lod_alt = alt;
let world_map_rgba_img = make_raw(&world_map_rgba)?; let world_map_rgba_img = make_raw(&world_map_rgba)?;
let world_map_topo_img = make_raw(&world_map_topo)?;
let world_map_political_img = make_raw(&world_map_political)?; let world_map_political_img = make_raw(&world_map_political)?;
let world_map_layers = vec!(world_map_political_img, world_map_rgba_img, world_map_topo_img); let world_map_rgba_half_alpha_img = make_raw(&world_map_rgba_half_alpha)?;
let world_map_topo_img = make_raw(&world_map_topo)?;
let world_map_layers = vec![
world_map_rgba_img,
world_map_political_img,
world_map_rgba_half_alpha_img,
world_map_topo_img,
];
let horizons = (west.0, west.1, east.0, east.1) let horizons = (west.0, west.1, east.0, east.1)
.into_par_iter() .into_par_iter()
.map(|(wa, wh, ea, eh)| u32::from_le_bytes([wa, wh, ea, eh])) .map(|(wa, wh, ea, eh)| u32::from_le_bytes([wa, wh, ea, eh]))

View File

@ -334,6 +334,10 @@ pub struct MapConfig<'a> {
/// ///
/// Defaults to false /// Defaults to false
pub is_roads: bool, pub is_roads: bool,
/// Alpha value for rgba. Handled by the sample_pos closure
///
/// Defaults to 1.0
pub rgba_alpha: f64,
} }
pub const QUADRANTS: usize = 4; pub const QUADRANTS: usize = 4;
@ -418,6 +422,7 @@ impl<'a> MapConfig<'a> {
is_height_map: false, is_height_map: false,
is_political: false, is_political: false,
is_roads: false, is_roads: false,
rgba_alpha: 1.0,
} }
} }
@ -736,4 +741,3 @@ impl<'a> MapConfig<'a> {
} }
} }
} }

View File

@ -336,6 +336,7 @@ image_ids! {
crosshair_bg_pressed: "voxygen.element.misc_bg.crosshair_bg_pressed", crosshair_bg_pressed: "voxygen.element.misc_bg.crosshair_bg_pressed",
// Map // Map
map_topo: "voxygen.element.map.topographic",
map_bg: "voxygen.element.misc_bg.map_bg", map_bg: "voxygen.element.misc_bg.map_bg",
map_frame: "voxygen.element.misc_bg.map_frame", map_frame: "voxygen.element.misc_bg.map_frame",
map_frame_art: "voxygen.element.misc_bg.map_frame_art", map_frame_art: "voxygen.element.misc_bg.map_frame_art",

View File

@ -40,6 +40,9 @@ widget_ids! {
member_indicators[], member_indicators[],
member_height_indicators[], member_height_indicators[],
map_settings_align, map_settings_align,
show_topo_map_img,
show_topo_map_box,
show_topo_map_text,
show_towns_img, show_towns_img,
show_towns_box, show_towns_box,
show_towns_text, show_towns_text,
@ -123,6 +126,7 @@ pub enum Event {
ShowDungeons(bool), ShowDungeons(bool),
ShowCaves(bool), ShowCaves(bool),
ShowTrees(bool), ShowTrees(bool),
ShowTopoMap(bool),
Close, Close,
RequestSiteInfo(SiteId), RequestSiteInfo(SiteId),
} }
@ -184,6 +188,7 @@ impl<'a> Widget for Map<'a> {
let show_castles = self.global_state.settings.interface.map_show_castles; let show_castles = self.global_state.settings.interface.map_show_castles;
let show_caves = self.global_state.settings.interface.map_show_caves; let show_caves = self.global_state.settings.interface.map_show_caves;
let show_trees = self.global_state.settings.interface.map_show_trees; let show_trees = self.global_state.settings.interface.map_show_trees;
let show_topo_map = self.global_state.settings.interface.map_show_topo_map;
let mut events = Vec::new(); let mut events = Vec::new();
let i18n = &self.localized_strings; let i18n = &self.localized_strings;
// Tooltips // Tooltips
@ -342,7 +347,7 @@ impl<'a> Widget for Map<'a> {
.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 { } else if show_topo_map {
Image::new(layer.none) Image::new(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)
@ -369,9 +374,44 @@ impl<'a> Widget for Map<'a> {
.top_right_with_margins_on(state.ids.frame, 55.0, 10.0) .top_right_with_margins_on(state.ids.frame, 55.0, 10.0)
.set(state.ids.map_settings_align, ui); .set(state.ids.map_settings_align, ui);
// Checkboxes // Checkboxes
// Show topographic map
Image::new(self.imgs.map_topo)
.top_left_with_margins_on(state.ids.map_settings_align, 5.0, 5.0)
.w_h(20.0, 20.0)
.set(state.ids.show_topo_map_img, ui);
if Button::image(if show_topo_map {
self.imgs.checkbox_checked
} else {
self.imgs.checkbox
})
.w_h(18.0, 18.0)
.hover_image(if show_topo_map {
self.imgs.checkbox_checked_mo
} else {
self.imgs.checkbox_mo
})
.press_image(if show_topo_map {
self.imgs.checkbox_checked
} else {
self.imgs.checkbox_press
})
.right_from(state.ids.show_topo_map_img, 10.0)
.set(state.ids.show_topo_map_box, ui)
.was_clicked()
{
events.push(Event::ShowTopoMap(!show_topo_map));
}
Text::new(i18n.get("hud.map.topo_map"))
.right_from(state.ids.show_topo_map_box, 10.0)
.font_size(self.fonts.cyri.scale(14))
.font_id(self.fonts.cyri.conrod_id)
.graphics_for(state.ids.show_topo_map_box)
.color(TEXT_COLOR)
.set(state.ids.show_topo_map_text, ui);
// Show difficulties // Show difficulties
Image::new(self.imgs.map_dif_6) Image::new(self.imgs.map_dif_6)
.top_left_with_margins_on(state.ids.map_settings_align, 5.0, 5.0) .down_from(state.ids.show_topo_map_img, 10.0)
.w_h(20.0, 20.0) .w_h(20.0, 20.0)
.set(state.ids.show_difficulty_img, ui); .set(state.ids.show_difficulty_img, ui);
if Button::image(if show_difficulty { if Button::image(if show_difficulty {

View File

@ -118,6 +118,7 @@ impl<'a> Widget for MiniMap<'a> {
const SCALE: f64 = 1.5; // TODO Make this a setting const SCALE: f64 = 1.5; // TODO Make this a setting
let show_minimap = self.global_state.settings.interface.minimap_show; let show_minimap = self.global_state.settings.interface.minimap_show;
let is_facing_north = self.global_state.settings.interface.minimap_face_north; let is_facing_north = self.global_state.settings.interface.minimap_face_north;
let show_topo_map = self.global_state.settings.interface.map_show_topo_map;
let orientation = if is_facing_north { let orientation = if is_facing_north {
Vec3::new(0.0, 1.0, 0.0) Vec3::new(0.0, 1.0, 0.0)
} else { } else {
@ -272,7 +273,7 @@ impl<'a> Widget for MiniMap<'a> {
.parent(state.ids.mmap_frame_bg) .parent(state.ids.mmap_frame_bg)
.source_rectangle(rect_src) .source_rectangle(rect_src)
.set(state.ids.map_layers[index], ui); .set(state.ids.map_layers[index], ui);
} else { } else if show_topo_map {
Image::new(world_map_rotation) Image::new(world_map_rotation)
.middle_of(state.ids.mmap_frame_bg) .middle_of(state.ids.mmap_frame_bg)
.w_h(map_size.x, map_size.y) .w_h(map_size.x, map_size.y)
@ -350,7 +351,7 @@ impl<'a> Widget for MiniMap<'a> {
SiteKind::Cave => Color::Rgba(1.0, 1.0, 1.0, 0.0), SiteKind::Cave => Color::Rgba(1.0, 1.0, 1.0, 0.0),
SiteKind::Tree => Color::Rgba(1.0, 1.0, 1.0, 0.0), SiteKind::Tree => Color::Rgba(1.0, 1.0, 1.0, 0.0),
})) }))
.parent(state.ids.map_layers[2]) .parent(state.ids.map_layers[3])
.set(state.ids.mmap_site_icons_bgs[i], ui); .set(state.ids.mmap_site_icons_bgs[i], ui);
Image::new(match &site.kind { Image::new(match &site.kind {
SiteKind::Town => self.imgs.mmap_site_town, SiteKind::Town => self.imgs.mmap_site_town,

View File

@ -374,6 +374,7 @@ pub enum Event {
ChangeAmbiance(f32), ChangeAmbiance(f32),
MapZoom(f64), MapZoom(f64),
MapDrag(Vec2<f64>), MapDrag(Vec2<f64>),
MapShowTopoMap(bool),
MapShowDifficulty(bool), MapShowDifficulty(bool),
MapShowTowns(bool), MapShowTowns(bool),
MapShowDungeons(bool), MapShowDungeons(bool),
@ -777,7 +778,7 @@ impl PromptDialogSettings {
pub struct Hud { pub struct Hud {
ui: Ui, ui: Ui,
ids: Ids, ids: Ids,
world_map_layers: (/* Id */ Vec<Rotations>, Vec2<u32>), world_map: (/* Id */ Vec<Rotations>, Vec2<u32>),
imgs: Imgs, imgs: Imgs,
item_imgs: ItemImgs, item_imgs: ItemImgs,
fonts: Fonts, fonts: Fonts,
@ -820,15 +821,11 @@ impl Hud {
// Load world map // Load world map
let mut layers = Vec::new(); let mut layers = Vec::new();
for layer in client.world_data().map_layers() { for layer in client.world_data().map_layers() {
layers.push(ui.add_graphic_with_rotations(Graphic::Image( layers.push(
Arc::clone(layer), ui.add_graphic_with_rotations(Graphic::Image(Arc::clone(layer), Some(water_color))),
Some(water_color), );
)));
} }
let world_map_layers = ( let world_map = (layers, client.world_data().chunk_size().map(|e| e as u32));
layers,
client.world_data().chunk_size().map(|e| e as u32),
);
// Load images. // Load images.
let imgs = Imgs::load(&mut ui).expect("Failed to load images!"); let imgs = Imgs::load(&mut ui).expect("Failed to load images!");
// Load rotation images. // Load rotation images.
@ -865,7 +862,7 @@ impl Hud {
Self { Self {
ui, ui,
imgs, imgs,
world_map_layers, world_map,
rot_imgs, rot_imgs,
item_imgs, item_imgs,
fonts, fonts,
@ -2233,7 +2230,7 @@ impl Hud {
client, client,
&self.imgs, &self.imgs,
&self.rot_imgs, &self.rot_imgs,
&self.world_map_layers, &self.world_map,
&self.fonts, &self.fonts,
camera.get_orientation(), camera.get_orientation(),
&global_state, &global_state,
@ -2786,7 +2783,7 @@ impl Hud {
client, client,
&self.imgs, &self.imgs,
&self.rot_imgs, &self.rot_imgs,
&self.world_map_layers, &self.world_map,
&self.fonts, &self.fonts,
self.pulse, self.pulse,
i18n, i18n,
@ -2801,6 +2798,9 @@ impl Hud {
self.show.want_grab = true; self.show.want_grab = true;
self.force_ungrab = false; self.force_ungrab = false;
}, },
map::Event::ShowTopoMap(map_show_topo_map) => {
events.push(Event::MapShowTopoMap(map_show_topo_map));
},
map::Event::ShowDifficulties(map_show_difficulties) => { map::Event::ShowDifficulties(map_show_difficulties) => {
events.push(Event::MapShowDifficulty(map_show_difficulties)); events.push(Event::MapShowDifficulty(map_show_difficulties));
}, },

View File

@ -1332,6 +1332,10 @@ impl PlayState for SessionState {
global_state.settings.interface.map_drag = map_drag; global_state.settings.interface.map_drag = map_drag;
global_state.settings.save_to_file_warn(); global_state.settings.save_to_file_warn();
}, },
HudEvent::MapShowTopoMap(map_show_topo_map) => {
global_state.settings.interface.map_show_topo_map = map_show_topo_map;
global_state.settings.save_to_file_warn();
},
HudEvent::MapShowDifficulty(map_show_difficulty) => { HudEvent::MapShowDifficulty(map_show_difficulty) => {
global_state.settings.interface.map_show_difficulty = map_show_difficulty; global_state.settings.interface.map_show_difficulty = map_show_difficulty;
global_state.settings.save_to_file_warn(); global_state.settings.save_to_file_warn();

View File

@ -444,6 +444,7 @@ pub struct InterfaceSettings {
pub ui_scale: ScaleMode, pub ui_scale: ScaleMode,
pub map_zoom: f64, pub map_zoom: f64,
pub map_drag: Vec2<f64>, pub map_drag: Vec2<f64>,
pub map_show_topo_map: bool,
pub map_show_difficulty: bool, pub map_show_difficulty: bool,
pub map_show_towns: bool, pub map_show_towns: bool,
pub map_show_dungeons: bool, pub map_show_dungeons: bool,
@ -451,7 +452,6 @@ pub struct InterfaceSettings {
pub loading_tips: bool, pub loading_tips: bool,
pub map_show_caves: bool, pub map_show_caves: bool,
pub map_show_trees: bool, pub map_show_trees: bool,
pub map_show_topo: bool,
pub minimap_show: bool, pub minimap_show: bool,
pub minimap_face_north: bool, pub minimap_face_north: bool,
} }
@ -477,6 +477,7 @@ impl Default for InterfaceSettings {
ui_scale: ScaleMode::RelativeToWindow([1920.0, 1080.0].into()), ui_scale: ScaleMode::RelativeToWindow([1920.0, 1080.0].into()),
map_zoom: 10.0, map_zoom: 10.0,
map_drag: Vec2 { x: 0.0, y: 0.0 }, map_drag: Vec2 { x: 0.0, y: 0.0 },
map_show_topo_map: false,
map_show_difficulty: true, map_show_difficulty: true,
map_show_towns: true, map_show_towns: true,
map_show_dungeons: true, map_show_dungeons: true,
@ -484,7 +485,6 @@ impl Default for InterfaceSettings {
loading_tips: true, loading_tips: true,
map_show_caves: true, map_show_caves: true,
map_show_trees: true, map_show_trees: true,
map_show_topo: false,
minimap_show: true, minimap_show: true,
minimap_face_north: false, minimap_face_north: false,
} }

View File

@ -91,9 +91,10 @@ fn main() {
} else { } else {
MapSample { MapSample {
alt: 0.0, alt: 0.0,
rgb: Rgb::new(0, 0, 0), rgba: Rgba::new(0, 0, 0, 255),
connections: None, connections: None,
downhill_wpos: (pos + 1) * TerrainChunkSize::RECT_SIZE.map(|e| e as i32), downhill_wpos: (pos + 1) * TerrainChunkSize::RECT_SIZE.map(|e| e as i32),
is_path: false,
} }
} }
}; };
@ -178,6 +179,11 @@ fn main() {
is_temperature, is_temperature,
is_humidity, is_humidity,
is_debug: true, is_debug: true,
is_contours: false,
is_height_map: false,
is_political: false,
is_roads: false,
rgba_alpha: 1.0,
}; };
if samples_changed { if samples_changed {