veloren_world/
land.rs

1use crate::{
2    ColumnSample, IndexRef,
3    column::ColumnGen,
4    sim::{self, SimChunk},
5    util::Sampler,
6};
7use common::{terrain::TerrainChunkSize, vol::RectVolSize};
8use vek::*;
9
10/// A wrapper type that may contain a reference to a generated world. If not,
11/// default values will be provided.
12pub struct Land<'a> {
13    sim: Option<&'a sim::WorldSim>,
14}
15
16impl<'a> Land<'a> {
17    pub fn empty() -> Self { Self { sim: None } }
18
19    pub fn size(&self) -> Vec2<u32> { self.sim.map_or(Vec2::one(), |s| s.get_size()) }
20
21    pub fn from_sim(sim: &'a sim::WorldSim) -> Self { Self { sim: Some(sim) } }
22
23    pub fn get_interpolated<T>(&self, wpos: Vec2<i32>, f: impl FnMut(&SimChunk) -> T) -> T
24    where
25        T: Copy + Default + std::ops::Add<Output = T> + std::ops::Mul<f32, Output = T>,
26    {
27        self.sim
28            .and_then(|sim| sim.get_interpolated(wpos, f))
29            .unwrap_or_default()
30    }
31
32    /// See `WorldSim::get_surface_alt_approx`.
33    pub fn get_surface_alt_approx(&self, wpos: Vec2<i32>) -> f32 {
34        self.sim
35            .map(|sim| sim.get_surface_alt_approx(wpos))
36            .unwrap_or(0.0)
37    }
38
39    pub fn get_alt_approx(&self, wpos: Vec2<i32>) -> f32 {
40        self.sim
41            .and_then(|sim| sim.get_alt_approx(wpos))
42            .unwrap_or(0.0)
43    }
44
45    pub fn get_downhill(&self, wpos: Vec2<i32>) -> Vec2<i32> {
46        self.sim
47            .and_then(|sim| sim.get_wpos(wpos))
48            .and_then(|c| c.downhill)
49            .unwrap_or(Vec2::zero())
50    }
51
52    pub fn get_gradient_approx(&self, wpos: Vec2<i32>) -> f32 {
53        self.sim
54            .and_then(|sim| sim.get_gradient_approx(self.wpos_chunk_pos(wpos)))
55            .unwrap_or(0.0)
56    }
57
58    pub fn wpos_chunk_pos(&self, wpos: Vec2<i32>) -> Vec2<i32> {
59        wpos.map2(TerrainChunkSize::RECT_SIZE, |e, sz| e.div_euclid(sz as i32))
60    }
61
62    pub fn get_chunk(&self, chunk_pos: Vec2<i32>) -> Option<&sim::SimChunk> {
63        self.sim.and_then(|sim| sim.get(chunk_pos))
64    }
65
66    pub fn get_chunk_wpos(&self, wpos: Vec2<i32>) -> Option<&sim::SimChunk> {
67        self.sim.and_then(|sim| sim.get_wpos(wpos))
68    }
69
70    pub fn get_nearest_path(
71        &self,
72        wpos: Vec2<i32>,
73    ) -> Option<(f32, Vec2<f32>, sim::Path, Vec2<f32>)> {
74        self.sim.and_then(|sim| sim.get_nearest_path(wpos))
75    }
76
77    pub fn column_sample<'sample>(
78        &'sample self,
79        wpos: Vec2<i32>,
80        index: IndexRef<'sample>,
81    ) -> Option<ColumnSample<'sample>> {
82        self.sim
83            .and_then(|sim| ColumnGen::new(sim).get((wpos, index, None)))
84    }
85}