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
11pub 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 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}