veloren_world/
all.rs

1use crate::{
2    IndexRef,
3    util::{math::close, sampler::Sampler},
4};
5use common::{match_some, terrain::structure::StructureBlock};
6use std::ops::Range;
7use strum::EnumIter;
8use vek::*;
9
10#[derive(Copy, Clone, Debug, EnumIter)]
11pub enum ForestKind {
12    Palm,
13    Acacia,
14    Baobab,
15    Oak,
16    Chestnut,
17    Cedar,
18    Pine,
19    Redwood,
20    Birch,
21    Mangrove,
22    Giant,
23    Swamp,
24    Frostpine,
25    Dead,
26    Mapletree,
27    Cherry,
28    AutumnTree,
29}
30
31pub struct Environment {
32    pub humid: f32,
33    pub temp: f32,
34    pub near_water: f32,
35}
36
37impl ForestKind {
38    pub fn humid_range(&self) -> Range<f32> {
39        match self {
40            ForestKind::Palm => 0.25..1.4,
41            ForestKind::Acacia => 0.05..0.55,
42            ForestKind::Baobab => 0.2..0.6,
43            ForestKind::Oak => 0.35..1.5,
44            ForestKind::Chestnut => 0.35..1.5,
45            ForestKind::Cedar => 0.275..1.45,
46            ForestKind::Pine => 0.2..1.4,
47            ForestKind::Redwood => 0.6..1.0,
48            ForestKind::Frostpine => 0.2..1.4,
49            ForestKind::Birch => 0.0..0.6,
50            ForestKind::Mangrove => 0.5..1.3,
51            ForestKind::Swamp => 0.5..1.1,
52            ForestKind::Dead => 0.0..1.5,
53            ForestKind::Mapletree => 0.65..1.25,
54            ForestKind::Cherry => 0.45..0.75,
55            ForestKind::AutumnTree => 0.25..0.65,
56            _ => 0.0..0.0,
57        }
58    }
59
60    pub fn temp_range(&self) -> Range<f32> {
61        match self {
62            ForestKind::Palm => 0.4..1.6,
63            ForestKind::Acacia => 0.3..1.6,
64            ForestKind::Baobab => 0.4..0.9,
65            ForestKind::Oak => -0.35..0.45,
66            ForestKind::Chestnut => -0.35..0.45,
67            ForestKind::Cedar => -0.65..0.15,
68            ForestKind::Pine => -0.85..-0.2,
69            ForestKind::Redwood => -0.5..-0.3,
70            ForestKind::Frostpine => -1.8..-0.8,
71            ForestKind::Birch => -0.7..0.25,
72            ForestKind::Mangrove => 0.35..1.6,
73            ForestKind::Swamp => -0.6..0.8,
74            ForestKind::Dead => -1.5..1.0,
75            ForestKind::Mapletree => -0.15..0.25,
76            ForestKind::Cherry => -0.10..0.15,
77            ForestKind::AutumnTree => -0.45..0.05,
78            _ => 0.0..0.0,
79        }
80    }
81
82    pub fn near_water_range(&self) -> Option<Range<f32>> {
83        match_some!(self,
84            ForestKind::Palm => 0.35..1.8,
85            ForestKind::Swamp => 0.5..1.8,
86        )
87    }
88
89    /// The relative rate at which this tree appears under ideal conditions
90    pub fn ideal_proclivity(&self) -> f32 {
91        match self {
92            ForestKind::Palm => 0.4,
93            ForestKind::Acacia => 0.6,
94            ForestKind::Baobab => 0.2,
95            ForestKind::Oak => 1.0,
96            ForestKind::Chestnut => 0.3,
97            ForestKind::Cedar => 0.3,
98            ForestKind::Pine => 1.0,
99            ForestKind::Redwood => 2.5,
100            ForestKind::Frostpine => 1.0,
101            ForestKind::Birch => 0.65,
102            ForestKind::Mangrove => 2.0,
103            ForestKind::Swamp => 1.0,
104            ForestKind::Dead => 0.01,
105            ForestKind::Mapletree => 0.65,
106            ForestKind::Cherry => 12.0,
107            ForestKind::AutumnTree => 125.0,
108            _ => 0.0,
109        }
110    }
111
112    pub fn shrub_density_factor(&self) -> f32 {
113        match self {
114            ForestKind::Palm => 0.2,
115            ForestKind::Acacia => 0.3,
116            ForestKind::Baobab => 0.2,
117            ForestKind::Oak => 0.4,
118            ForestKind::Chestnut => 0.3,
119            ForestKind::Cedar => 0.3,
120            ForestKind::Pine => 0.5,
121            ForestKind::Frostpine => 0.3,
122            ForestKind::Birch => 0.65,
123            ForestKind::Mangrove => 1.0,
124            ForestKind::Swamp => 0.4,
125            ForestKind::Mapletree => 0.4,
126            ForestKind::Cherry => 0.3,
127            ForestKind::AutumnTree => 0.4,
128            _ => 1.0,
129        }
130    }
131
132    pub fn leaf_block(&self) -> StructureBlock {
133        match self {
134            ForestKind::Palm => StructureBlock::PalmLeavesOuter,
135            ForestKind::Acacia => StructureBlock::Acacia,
136            ForestKind::Baobab => StructureBlock::Baobab,
137            ForestKind::Oak => StructureBlock::TemperateLeaves,
138            ForestKind::Chestnut => StructureBlock::Chestnut,
139            ForestKind::Cedar => StructureBlock::PineLeaves,
140            ForestKind::Pine => StructureBlock::PineLeaves,
141            ForestKind::Redwood => StructureBlock::PineLeaves,
142            ForestKind::Birch => StructureBlock::TemperateLeaves,
143            ForestKind::Mangrove => StructureBlock::Mangrove,
144            ForestKind::Giant => StructureBlock::TemperateLeaves,
145            ForestKind::Swamp => StructureBlock::TemperateLeaves,
146            ForestKind::Frostpine => StructureBlock::FrostpineLeaves,
147            ForestKind::Dead => StructureBlock::TemperateLeaves,
148            ForestKind::Mapletree => StructureBlock::MapleLeaves,
149            ForestKind::Cherry => StructureBlock::CherryLeaves,
150            ForestKind::AutumnTree => StructureBlock::AutumnLeaves,
151        }
152    }
153
154    pub fn proclivity(&self, env: &Environment) -> f32 {
155        self.ideal_proclivity()
156            * close(env.humid, self.humid_range())
157            * close(env.temp, self.temp_range())
158            * self.near_water_range().map_or(1.0, |near_water_range| {
159                close(env.near_water, near_water_range)
160            })
161    }
162}
163
164pub fn leaf_color(
165    index: IndexRef,
166    seed: u32,
167    lerp: f32,
168    sblock: &StructureBlock,
169) -> Option<Rgb<u8>> {
170    let ranges = sblock
171        .elim_case_pure(&index.colors.block.structure_blocks)
172        .as_ref()
173        .map(Vec::as_slice)
174        .unwrap_or(&[]);
175
176    ranges
177        .get(crate::util::RandomPerm::new(seed).get(seed) as usize % ranges.len())
178        .map(|range| {
179            Rgb::<f32>::lerp(
180                Rgb::<u8>::from(range.start).map(f32::from),
181                Rgb::<u8>::from(range.end).map(f32::from),
182                lerp,
183            )
184            .map(|e| e as u8)
185        })
186}
187
188/// Not currently used with trees generated by the tree layer, needs to be
189/// reworked
190pub struct TreeAttr {
191    pub pos: Vec2<i32>,
192    pub seed: u32,
193    pub scale: f32,
194    pub forest_kind: ForestKind,
195    pub inhabited: bool,
196}