mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Topographic map
This commit is contained in:
@ -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 = false
|
incremental = true
|
||||||
# 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
|
||||||
|
@ -34,7 +34,7 @@ use common::{
|
|||||||
outcome::Outcome,
|
outcome::Outcome,
|
||||||
recipe::RecipeBook,
|
recipe::RecipeBook,
|
||||||
resources::{DeltaTime, PlayerEntity, TimeOfDay},
|
resources::{DeltaTime, PlayerEntity, TimeOfDay},
|
||||||
terrain::{block::Block, 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,
|
||||||
@ -112,21 +112,22 @@ pub struct WorldData {
|
|||||||
/// map data (e.g. with shadow map data or river data), but at present
|
/// map data (e.g. with shadow map data or river data), but at present
|
||||||
/// we opt not to do this.
|
/// we opt not to do this.
|
||||||
///
|
///
|
||||||
/// The second element of the tuple is the world size (as a 2D grid,
|
/// The first two elements of the tuple are the regular and topographic maps
|
||||||
/// in chunks), and the third element holds the minimum height for any land
|
/// respectively. The third element of the tuple is the world size (as a 2D
|
||||||
/// chunk (i.e. the sea level) in its x coordinate, and the maximum land
|
/// grid, in chunks), and the fourth element holds the minimum height for
|
||||||
/// height above this height (i.e. the max height) in its y coordinate.
|
/// any land chunk (i.e. the sea level) in its x coordinate, and the maximum
|
||||||
map: (Arc<DynamicImage>, Vec2<u16>, Vec2<f32>),
|
/// land height above this height (i.e. the max height) in its y coordinate.
|
||||||
|
map: (Arc<DynamicImage>, Arc<DynamicImage>, Vec2<u16>, Vec2<f32>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorldData {
|
impl WorldData {
|
||||||
pub fn chunk_size(&self) -> Vec2<u16> { self.map.1 }
|
pub fn chunk_size(&self) -> Vec2<u16> { self.map.2 }
|
||||||
|
|
||||||
pub fn map_image(&self) -> &Arc<DynamicImage> { &self.map.0 }
|
pub fn map_image(&self) -> &Arc<DynamicImage> { &self.map.0 }
|
||||||
|
|
||||||
pub fn min_chunk_alt(&self) -> f32 { self.map.2.x }
|
pub fn map_topo_image(&self) -> &Arc<DynamicImage> { &self.map.1 }
|
||||||
|
|
||||||
pub fn max_chunk_alt(&self) -> f32 { self.map.2.y }
|
pub fn max_chunk_alt(&self) -> f32 { self.map.3.y }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SiteInfoRich {
|
pub struct SiteInfoRich {
|
||||||
@ -324,6 +325,7 @@ impl Client {
|
|||||||
|
|
||||||
// Redraw map (with shadows this time).
|
// Redraw map (with shadows this time).
|
||||||
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_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,
|
||||||
core::ops::RangeInclusive::new(0.0, max_height),
|
core::ops::RangeInclusive::new(0.0, max_height),
|
||||||
@ -336,18 +338,40 @@ 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)?;
|
||||||
map_config.generate(
|
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 {
|
||||||
|pos| {
|
let rescale_height = |h: f32| h / max_height;
|
||||||
|
let scale_height_big = |h: u32| (h >> 3) as f32 / 8191.0 * max_height;
|
||||||
|
let bounds_check = |pos: Vec2<i32>| {
|
||||||
|
pos.reduce_partial_min() >= 0
|
||||||
|
&& pos.x < map_size.x as i32
|
||||||
|
&& pos.y < map_size.y as i32
|
||||||
|
};
|
||||||
|
let MapConfig {
|
||||||
|
gain,
|
||||||
|
is_contours,
|
||||||
|
is_hill_shaded,
|
||||||
|
..
|
||||||
|
} = *map_config;
|
||||||
|
let mut is_contour_line = false;
|
||||||
let (rgba, alt, downhill_wpos) = if bounds_check(pos) {
|
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 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 [r, g, b, a] = rgba[pos].to_le_bytes();
|
||||||
let alti = alt[pos];
|
let alti = alt[pos];
|
||||||
|
// Compute contours (chunks are assigned in the river code below)
|
||||||
|
let altj = rescale_height(scale_height_big(alti));
|
||||||
|
let chunk_contour = (altj * gain / 100.0) 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 nchunk_contour = (nalt * gain / 100.0) as u32;
|
||||||
|
if chunk_contour > nchunk_contour {
|
||||||
|
is_contour_line = true;
|
||||||
|
}
|
||||||
if nbh < besth {
|
if nbh < besth {
|
||||||
besth = nbh;
|
besth = nbh;
|
||||||
best = nposi as isize;
|
best = nposi as isize;
|
||||||
@ -369,17 +393,43 @@ impl Client {
|
|||||||
} else {
|
} else {
|
||||||
(Rgba::zero(), 0, None)
|
(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 wpos = pos * TerrainChunkSize::RECT_SIZE.map(|e| e as i32);
|
||||||
let downhill_wpos = downhill_wpos
|
let downhill_wpos = downhill_wpos
|
||||||
.unwrap_or(wpos + TerrainChunkSize::RECT_SIZE.map(|e| e as i32));
|
.unwrap_or(wpos + TerrainChunkSize::RECT_SIZE.map(|e| e as i32));
|
||||||
let alt = rescale_height(scale_height_big(alt));
|
let is_path = rgba.r == 0x37 && rgba.g == 0x29 && rgba.b == 0x23;
|
||||||
|
let rgb = Rgb::from(rgba).map(|e: u8| e as f64 / 255.0);
|
||||||
|
let rgb = if is_hill_shaded {
|
||||||
|
if is_path {
|
||||||
|
// Path color is Rgb::new(0x37, 0x29, 0x23)
|
||||||
|
Rgb::new(0.9, 0.9, 0.63)
|
||||||
|
} else if rgb.r == 0.0 && rgb.b > 0.4 && rgb.g < 0.3 {
|
||||||
|
// Water
|
||||||
|
Rgb::new(0.23, 0.47, 0.53)
|
||||||
|
} else if is_contours && is_contour_line {
|
||||||
|
// Color contour lines
|
||||||
|
Rgb::new(0.15, 0.15, 0.15)
|
||||||
|
} else {
|
||||||
|
// Color hill shading
|
||||||
|
let lightness = (alt + 0.2).min(1.0) as f64;
|
||||||
|
Rgb::new(lightness, 0.9 * lightness, 0.5 * lightness)
|
||||||
|
}
|
||||||
|
} else if is_contours && is_contour_line {
|
||||||
|
// Color contour lines
|
||||||
|
Rgb::new(0.15, 0.15, 0.15)
|
||||||
|
} else {
|
||||||
|
rgb
|
||||||
|
}.map(|e| (e * 255.0) as u8);
|
||||||
common::terrain::map::MapSample {
|
common::terrain::map::MapSample {
|
||||||
rgb: Rgb::from(rgba),
|
rgb,
|
||||||
alt: f64::from(alt),
|
alt,
|
||||||
downhill_wpos,
|
downhill_wpos,
|
||||||
connections: None,
|
connections: None,
|
||||||
|
is_path,
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
map_config.generate(
|
||||||
|
|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) {
|
||||||
@ -393,6 +443,26 @@ impl Client {
|
|||||||
u32::from_le_bytes([r, g, b, a]);
|
u32::from_le_bytes([r, g, b, a]);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Generate topographic map
|
||||||
|
map_config.is_hill_shaded = true;
|
||||||
|
map_config.is_contours = true;
|
||||||
|
map_config.is_shaded = false;
|
||||||
|
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_topo[pos.y * map_size.x as usize + pos.x] =
|
||||||
|
u32::from_le_bytes([r, g, b, a]);
|
||||||
|
},
|
||||||
|
);
|
||||||
ping_stream.send(PingMsg::Ping)?;
|
ping_stream.send(PingMsg::Ping)?;
|
||||||
let make_raw = |rgba| -> Result<_, Error> {
|
let make_raw = |rgba| -> Result<_, Error> {
|
||||||
let mut raw = vec![0u8; 4 * world_map_rgba.len()];
|
let mut raw = vec![0u8; 4 * world_map_rgba.len()];
|
||||||
@ -413,6 +483,7 @@ impl Client {
|
|||||||
let lod_base = rgba;
|
let lod_base = rgba;
|
||||||
let lod_alt = alt;
|
let lod_alt = alt;
|
||||||
let world_map_img = make_raw(&world_map_rgba)?;
|
let world_map_img = make_raw(&world_map_rgba)?;
|
||||||
|
let world_map_topo_img = make_raw(&world_map_topo)?;
|
||||||
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]))
|
||||||
@ -426,7 +497,7 @@ impl Client {
|
|||||||
lod_base,
|
lod_base,
|
||||||
lod_alt,
|
lod_alt,
|
||||||
Grid::from_raw(map_size.map(|e| e as i32), lod_horizon),
|
Grid::from_raw(map_size.map(|e| e as i32), lod_horizon),
|
||||||
(world_map_img, map_size, map_bounds),
|
(world_map_img, world_map_topo_img, map_size, map_bounds),
|
||||||
world_map.sites,
|
world_map.sites,
|
||||||
recipe_book,
|
recipe_book,
|
||||||
max_group_size,
|
max_group_size,
|
||||||
|
@ -317,6 +317,16 @@ pub struct MapConfig<'a> {
|
|||||||
///
|
///
|
||||||
/// Defaults to false.
|
/// Defaults to false.
|
||||||
pub is_debug: bool,
|
pub is_debug: bool,
|
||||||
|
/// If true, contour lines are drawn on top of the base rbg
|
||||||
|
///
|
||||||
|
/// Defaults to false.
|
||||||
|
pub is_contours: bool,
|
||||||
|
/// If true, hill shading is applied to the terrain and all the
|
||||||
|
/// colors are different. Is incompatible with humidity/temperature/shaded
|
||||||
|
/// maps.
|
||||||
|
///
|
||||||
|
/// Defaults to false
|
||||||
|
pub is_hill_shaded: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const QUADRANTS: usize = 4;
|
pub const QUADRANTS: usize = 4;
|
||||||
@ -366,6 +376,8 @@ pub struct MapSample {
|
|||||||
/// Connections at each index correspond to the same index in
|
/// Connections at each index correspond to the same index in
|
||||||
/// NEIGHBOR_DELTA.
|
/// NEIGHBOR_DELTA.
|
||||||
pub connections: Option<[Option<Connection>; 8]>,
|
pub connections: Option<[Option<Connection>; 8]>,
|
||||||
|
/// If the chunk contains a path
|
||||||
|
pub is_path: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> MapConfig<'a> {
|
impl<'a> MapConfig<'a> {
|
||||||
@ -395,6 +407,8 @@ impl<'a> MapConfig<'a> {
|
|||||||
is_temperature: false,
|
is_temperature: false,
|
||||||
is_humidity: false,
|
is_humidity: false,
|
||||||
is_debug: false,
|
is_debug: false,
|
||||||
|
is_contours: false,
|
||||||
|
is_hill_shaded: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,7 +446,6 @@ impl<'a> MapConfig<'a> {
|
|||||||
scale,
|
scale,
|
||||||
light_direction,
|
light_direction,
|
||||||
horizons,
|
horizons,
|
||||||
|
|
||||||
is_shaded,
|
is_shaded,
|
||||||
// is_debug,
|
// is_debug,
|
||||||
..
|
..
|
||||||
@ -712,3 +725,4 @@ impl<'a> MapConfig<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@ const SHOW_ECONOMY: bool = false; // turn this display off (for 0.9) until we ha
|
|||||||
pub struct Map<'a> {
|
pub struct Map<'a> {
|
||||||
client: &'a Client,
|
client: &'a Client,
|
||||||
world_map: &'a (img_ids::Rotations, Vec2<u32>),
|
world_map: &'a (img_ids::Rotations, Vec2<u32>),
|
||||||
|
world_map_topo: &'a (img_ids::Rotations, Vec2<u32>),
|
||||||
imgs: &'a Imgs,
|
imgs: &'a Imgs,
|
||||||
fonts: &'a Fonts,
|
fonts: &'a Fonts,
|
||||||
#[conrod(common_builder)]
|
#[conrod(common_builder)]
|
||||||
@ -89,6 +90,7 @@ impl<'a> Map<'a> {
|
|||||||
imgs: &'a Imgs,
|
imgs: &'a Imgs,
|
||||||
rot_imgs: &'a ImgsRot,
|
rot_imgs: &'a ImgsRot,
|
||||||
world_map: &'a (img_ids::Rotations, Vec2<u32>),
|
world_map: &'a (img_ids::Rotations, Vec2<u32>),
|
||||||
|
world_map_topo: &'a (img_ids::Rotations, Vec2<u32>),
|
||||||
fonts: &'a Fonts,
|
fonts: &'a Fonts,
|
||||||
pulse: f32,
|
pulse: f32,
|
||||||
localized_strings: &'a Localization,
|
localized_strings: &'a Localization,
|
||||||
@ -99,6 +101,7 @@ impl<'a> Map<'a> {
|
|||||||
imgs,
|
imgs,
|
||||||
rot_imgs,
|
rot_imgs,
|
||||||
world_map,
|
world_map,
|
||||||
|
world_map_topo,
|
||||||
client,
|
client,
|
||||||
fonts,
|
fonts,
|
||||||
common: widget::CommonBuilder::default(),
|
common: widget::CommonBuilder::default(),
|
||||||
@ -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
|
||||||
@ -271,7 +276,7 @@ impl<'a> Widget for Map<'a> {
|
|||||||
.parent(state.ids.bg)
|
.parent(state.ids.bg)
|
||||||
.set(state.ids.grid, ui);
|
.set(state.ids.grid, ui);
|
||||||
// Map Image
|
// Map Image
|
||||||
let (world_map, worldsize) = self.world_map;
|
let (world_map, worldsize) = if !show_topo_map { self.world_map } else { self.world_map_topo };
|
||||||
|
|
||||||
// Coordinates
|
// Coordinates
|
||||||
let player_pos = self
|
let player_pos = self
|
||||||
@ -539,6 +544,40 @@ impl<'a> Widget for Map<'a> {
|
|||||||
{
|
{
|
||||||
events.push(Event::ShowTrees(!show_trees));
|
events.push(Event::ShowTrees(!show_trees));
|
||||||
}
|
}
|
||||||
|
Text::new(i18n.get("hud.map.trees"))
|
||||||
|
.right_from(state.ids.show_trees_box, 10.0)
|
||||||
|
.font_size(self.fonts.cyri.scale(14))
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.graphics_for(state.ids.show_trees_box)
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.set(state.ids.show_trees_text, ui);
|
||||||
|
// Topographical Map
|
||||||
|
Image::new(self.imgs.mmap_site_tree)
|
||||||
|
.down_from(state.ids.show_caves_img, 10.0)
|
||||||
|
.w_h(20.0, 20.0)
|
||||||
|
.set(state.ids.show_trees_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_trees_img, 10.0)
|
||||||
|
.set(state.ids.show_trees_box, ui)
|
||||||
|
.was_clicked()
|
||||||
|
{
|
||||||
|
events.push(Event::ShowTopoMap(!show_topo_map));
|
||||||
|
}
|
||||||
Text::new(i18n.get("hud.map.trees"))
|
Text::new(i18n.get("hud.map.trees"))
|
||||||
.right_from(state.ids.show_trees_box, 10.0)
|
.right_from(state.ids.show_trees_box, 10.0)
|
||||||
.font_size(self.fonts.cyri.scale(14))
|
.font_size(self.fonts.cyri.scale(14))
|
||||||
|
@ -48,6 +48,7 @@ pub struct MiniMap<'a> {
|
|||||||
imgs: &'a Imgs,
|
imgs: &'a Imgs,
|
||||||
rot_imgs: &'a ImgsRot,
|
rot_imgs: &'a ImgsRot,
|
||||||
world_map: &'a (img_ids::Rotations, Vec2<u32>),
|
world_map: &'a (img_ids::Rotations, Vec2<u32>),
|
||||||
|
world_map_topo: &'a (img_ids::Rotations, Vec2<u32>),
|
||||||
fonts: &'a Fonts,
|
fonts: &'a Fonts,
|
||||||
#[conrod(common_builder)]
|
#[conrod(common_builder)]
|
||||||
common: widget::CommonBuilder,
|
common: widget::CommonBuilder,
|
||||||
@ -61,6 +62,7 @@ impl<'a> MiniMap<'a> {
|
|||||||
imgs: &'a Imgs,
|
imgs: &'a Imgs,
|
||||||
rot_imgs: &'a ImgsRot,
|
rot_imgs: &'a ImgsRot,
|
||||||
world_map: &'a (img_ids::Rotations, Vec2<u32>),
|
world_map: &'a (img_ids::Rotations, Vec2<u32>),
|
||||||
|
world_map_topo: &'a (img_ids::Rotations, Vec2<u32>),
|
||||||
fonts: &'a Fonts,
|
fonts: &'a Fonts,
|
||||||
ori: Vec3<f32>,
|
ori: Vec3<f32>,
|
||||||
global_state: &'a GlobalState,
|
global_state: &'a GlobalState,
|
||||||
@ -70,6 +72,7 @@ impl<'a> MiniMap<'a> {
|
|||||||
imgs,
|
imgs,
|
||||||
rot_imgs,
|
rot_imgs,
|
||||||
world_map,
|
world_map,
|
||||||
|
world_map_topo,
|
||||||
fonts,
|
fonts,
|
||||||
common: widget::CommonBuilder::default(),
|
common: widget::CommonBuilder::default(),
|
||||||
ori,
|
ori,
|
||||||
@ -140,7 +143,8 @@ impl<'a> Widget for MiniMap<'a> {
|
|||||||
.set(state.ids.mmap_frame_bg, ui);
|
.set(state.ids.mmap_frame_bg, ui);
|
||||||
|
|
||||||
// Map size in chunk coords
|
// Map size in chunk coords
|
||||||
let (world_map, worldsize) = self.world_map;
|
let show_topo_map = self.global_state.settings.interface.map_show_topo_map;
|
||||||
|
let (world_map, worldsize) = if !show_topo_map { self.world_map } else { self.world_map_topo };
|
||||||
|
|
||||||
// Zoom Buttons
|
// Zoom Buttons
|
||||||
|
|
||||||
|
@ -250,6 +250,7 @@ widget_ids! {
|
|||||||
chat,
|
chat,
|
||||||
map,
|
map,
|
||||||
world_map,
|
world_map,
|
||||||
|
world_map_topo,
|
||||||
character_window,
|
character_window,
|
||||||
popup,
|
popup,
|
||||||
minimap,
|
minimap,
|
||||||
@ -380,6 +381,7 @@ pub enum Event {
|
|||||||
MapShowCastles(bool),
|
MapShowCastles(bool),
|
||||||
MapShowCaves(bool),
|
MapShowCaves(bool),
|
||||||
MapShowTrees(bool),
|
MapShowTrees(bool),
|
||||||
|
MapShowTopo(bool),
|
||||||
AdjustWindowSize([u16; 2]),
|
AdjustWindowSize([u16; 2]),
|
||||||
ChangeFullscreenMode(FullScreenSettings),
|
ChangeFullscreenMode(FullScreenSettings),
|
||||||
ToggleParticlesEnabled(bool),
|
ToggleParticlesEnabled(bool),
|
||||||
@ -778,6 +780,7 @@ pub struct Hud {
|
|||||||
ui: Ui,
|
ui: Ui,
|
||||||
ids: Ids,
|
ids: Ids,
|
||||||
world_map: (/* Id */ Rotations, Vec2<u32>),
|
world_map: (/* Id */ Rotations, Vec2<u32>),
|
||||||
|
world_map_topo: (/* Id */ Rotations, Vec2<u32>),
|
||||||
imgs: Imgs,
|
imgs: Imgs,
|
||||||
item_imgs: ItemImgs,
|
item_imgs: ItemImgs,
|
||||||
fonts: Fonts,
|
fonts: Fonts,
|
||||||
@ -825,6 +828,14 @@ impl Hud {
|
|||||||
)),
|
)),
|
||||||
client.world_data().chunk_size().map(|e| e as u32),
|
client.world_data().chunk_size().map(|e| e as u32),
|
||||||
);
|
);
|
||||||
|
// Load world topo map
|
||||||
|
let world_map_topo = (
|
||||||
|
ui.add_graphic_with_rotations(Graphic::Image(
|
||||||
|
Arc::clone(client.world_data().map_topo_image()),
|
||||||
|
Some(water_color),
|
||||||
|
)),
|
||||||
|
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.
|
||||||
@ -862,6 +873,7 @@ impl Hud {
|
|||||||
ui,
|
ui,
|
||||||
imgs,
|
imgs,
|
||||||
world_map,
|
world_map,
|
||||||
|
world_map_topo,
|
||||||
rot_imgs,
|
rot_imgs,
|
||||||
item_imgs,
|
item_imgs,
|
||||||
fonts,
|
fonts,
|
||||||
@ -2230,6 +2242,7 @@ impl Hud {
|
|||||||
&self.imgs,
|
&self.imgs,
|
||||||
&self.rot_imgs,
|
&self.rot_imgs,
|
||||||
&self.world_map,
|
&self.world_map,
|
||||||
|
&self.world_map_topo,
|
||||||
&self.fonts,
|
&self.fonts,
|
||||||
camera.get_orientation(),
|
camera.get_orientation(),
|
||||||
&global_state,
|
&global_state,
|
||||||
@ -2783,6 +2796,7 @@ impl Hud {
|
|||||||
&self.imgs,
|
&self.imgs,
|
||||||
&self.rot_imgs,
|
&self.rot_imgs,
|
||||||
&self.world_map,
|
&self.world_map,
|
||||||
|
&self.world_map_topo,
|
||||||
&self.fonts,
|
&self.fonts,
|
||||||
self.pulse,
|
self.pulse,
|
||||||
i18n,
|
i18n,
|
||||||
@ -2821,6 +2835,9 @@ impl Hud {
|
|||||||
map::Event::ShowTrees(map_show_trees) => {
|
map::Event::ShowTrees(map_show_trees) => {
|
||||||
events.push(Event::MapShowTrees(map_show_trees));
|
events.push(Event::MapShowTrees(map_show_trees));
|
||||||
},
|
},
|
||||||
|
map::Event::ShowTopoMap(map_show_topo_map) => {
|
||||||
|
events.push(Event::MapShowTopo(map_show_topo_map));
|
||||||
|
},
|
||||||
map::Event::RequestSiteInfo(id) => {
|
map::Event::RequestSiteInfo(id) => {
|
||||||
events.push(Event::RequestSiteInfo(id));
|
events.push(Event::RequestSiteInfo(id));
|
||||||
},
|
},
|
||||||
|
@ -1356,6 +1356,10 @@ impl PlayState for SessionState {
|
|||||||
global_state.settings.interface.map_show_trees = map_show_trees;
|
global_state.settings.interface.map_show_trees = map_show_trees;
|
||||||
global_state.settings.save_to_file_warn();
|
global_state.settings.save_to_file_warn();
|
||||||
},
|
},
|
||||||
|
HudEvent::MapShowTopo(map_show_topo) => {
|
||||||
|
global_state.settings.interface.map_show_topo_map = map_show_topo;
|
||||||
|
global_state.settings.save_to_file_warn();
|
||||||
|
},
|
||||||
HudEvent::RequestSiteInfo(id) => {
|
HudEvent::RequestSiteInfo(id) => {
|
||||||
let mut client = self.client.borrow_mut();
|
let mut client = self.client.borrow_mut();
|
||||||
client.request_site_economy(id);
|
client.request_site_economy(id);
|
||||||
|
@ -451,6 +451,7 @@ 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_map: bool,
|
||||||
pub minimap_show: bool,
|
pub minimap_show: bool,
|
||||||
pub minimap_face_north: bool,
|
pub minimap_face_north: bool,
|
||||||
}
|
}
|
||||||
@ -483,6 +484,7 @@ 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_map: false,
|
||||||
minimap_show: true,
|
minimap_show: true,
|
||||||
minimap_face_north: false,
|
minimap_face_north: false,
|
||||||
}
|
}
|
||||||
|
@ -260,5 +260,6 @@ pub fn sample_pos(
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
|
is_path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user