veloren_world/
all.rs

1use crate::{
2    IndexRef,
3    util::{math::close, sampler::Sampler},
4};
5use common::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 self {
84            ForestKind::Palm => Some(0.35..1.8),
85            ForestKind::Swamp => Some(0.5..1.8),
86            _ => None,
87        }
88    }
89
90    /// The relative rate at which this tree appears under ideal conditions
91    pub fn ideal_proclivity(&self) -> f32 {
92        match self {
93            ForestKind::Palm => 0.4,
94            ForestKind::Acacia => 0.6,
95            ForestKind::Baobab => 0.2,
96            ForestKind::Oak => 1.0,
97            ForestKind::Chestnut => 0.3,
98            ForestKind::Cedar => 0.3,
99            ForestKind::Pine => 1.0,
100            ForestKind::Redwood => 2.5,
101            ForestKind::Frostpine => 1.0,
102            ForestKind::Birch => 0.65,
103            ForestKind::Mangrove => 2.0,
104            ForestKind::Swamp => 1.0,
105            ForestKind::Dead => 0.01,
106            ForestKind::Mapletree => 0.65,
107            ForestKind::Cherry => 12.0,
108            ForestKind::AutumnTree => 125.0,
109            _ => 0.0,
110        }
111    }
112
113    pub fn shrub_density_factor(&self) -> f32 {
114        match self {
115            ForestKind::Palm => 0.2,
116            ForestKind::Acacia => 0.3,
117            ForestKind::Baobab => 0.2,
118            ForestKind::Oak => 0.4,
119            ForestKind::Chestnut => 0.3,
120            ForestKind::Cedar => 0.3,
121            ForestKind::Pine => 0.5,
122            ForestKind::Frostpine => 0.3,
123            ForestKind::Birch => 0.65,
124            ForestKind::Mangrove => 1.0,
125            ForestKind::Swamp => 0.4,
126            ForestKind::Mapletree => 0.4,
127            ForestKind::Cherry => 0.3,
128            ForestKind::AutumnTree => 0.4,
129            _ => 1.0,
130        }
131    }
132
133    pub fn leaf_block(&self) -> StructureBlock {
134        match self {
135            ForestKind::Palm => StructureBlock::PalmLeavesOuter,
136            ForestKind::Acacia => StructureBlock::Acacia,
137            ForestKind::Baobab => StructureBlock::Baobab,
138            ForestKind::Oak => StructureBlock::TemperateLeaves,
139            ForestKind::Chestnut => StructureBlock::Chestnut,
140            ForestKind::Cedar => StructureBlock::PineLeaves,
141            ForestKind::Pine => StructureBlock::PineLeaves,
142            ForestKind::Redwood => StructureBlock::PineLeaves,
143            ForestKind::Birch => StructureBlock::TemperateLeaves,
144            ForestKind::Mangrove => StructureBlock::Mangrove,
145            ForestKind::Giant => StructureBlock::TemperateLeaves,
146            ForestKind::Swamp => StructureBlock::TemperateLeaves,
147            ForestKind::Frostpine => StructureBlock::FrostpineLeaves,
148            ForestKind::Dead => StructureBlock::TemperateLeaves,
149            ForestKind::Mapletree => StructureBlock::MapleLeaves,
150            ForestKind::Cherry => StructureBlock::CherryLeaves,
151            ForestKind::AutumnTree => StructureBlock::AutumnLeaves,
152        }
153    }
154
155    pub fn proclivity(&self, env: &Environment) -> f32 {
156        self.ideal_proclivity()
157            * close(env.humid, self.humid_range())
158            * close(env.temp, self.temp_range())
159            * self.near_water_range().map_or(1.0, |near_water_range| {
160                close(env.near_water, near_water_range)
161            })
162    }
163}
164
165pub fn leaf_color(
166    index: IndexRef,
167    seed: u32,
168    lerp: f32,
169    sblock: &StructureBlock,
170) -> Option<Rgb<u8>> {
171    let ranges = sblock
172        .elim_case_pure(&index.colors.block.structure_blocks)
173        .as_ref()
174        .map(Vec::as_slice)
175        .unwrap_or(&[]);
176
177    ranges
178        .get(crate::util::RandomPerm::new(seed).get(seed) as usize % ranges.len())
179        .map(|range| {
180            Rgb::<f32>::lerp(
181                Rgb::<u8>::from(range.start).map(f32::from),
182                Rgb::<u8>::from(range.end).map(f32::from),
183                lerp,
184            )
185            .map(|e| e as u8)
186        })
187}
188
189/// Not currently used with trees generated by the tree layer, needs to be
190/// reworked
191pub struct TreeAttr {
192    pub pos: Vec2<i32>,
193    pub seed: u32,
194    pub scale: f32,
195    pub forest_kind: ForestKind,
196    pub inhabited: bool,
197}