veloren_world/
land.rs

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