use super::{Biome, BlockColor, Color, Colorf};
fn color_vec_unscaled(color: Color) -> Colorf {
Colorf::from_array(color.0.map(f32::from))
}
fn color_vec(color: Color) -> Colorf {
color_vec_unscaled(color) / 255.0
}
fn color_from_params(colors: &[Colorf; 3], biome: &Biome, depth: f32) -> Colorf {
let temp = (biome.temp() - f32::max((depth - 64.0) / 600.0, 0.0)).clamp(0.0, 1.0);
let downfall = biome.downfall().clamp(0.0, 1.0) * temp;
colors[0] + temp * colors[1] + downfall * colors[2]
}
trait BiomeExt {
fn grass_color(&self, depth: f32) -> Colorf;
fn foliage_color(&self, depth: f32) -> Colorf;
fn water_color(&self) -> Colorf;
}
impl BiomeExt for Biome {
fn grass_color(&self, depth: f32) -> Colorf {
use super::BiomeGrassColorModifier::*;
const GRASS_COLORS: [Colorf; 3] = [
Colorf::new(0.502, 0.706, 0.592), Colorf::new(0.247, 0.012, -0.259), Colorf::new(-0.471, 0.086, -0.133), ];
const DARK_FOREST_GRASS_COLOR: Colorf = Colorf::new(0.157, 0.204, 0.039); const SWAMP_GRASS_COLOR: Colorf = Colorf::new(0.416, 0.439, 0.224);
let regular_color = || {
self.grass_color
.map(color_vec)
.unwrap_or_else(|| color_from_params(&GRASS_COLORS, self, depth))
};
match self.grass_color_modifier {
Some(DarkForest) => 0.5 * (regular_color() + DARK_FOREST_GRASS_COLOR),
Some(Swamp) => SWAMP_GRASS_COLOR,
None => regular_color(),
}
}
fn foliage_color(&self, depth: f32) -> Colorf {
const FOLIAGE_COLORS: [Colorf; 3] = [
Colorf::new(0.376, 0.631, 0.482), Colorf::new(0.306, 0.012, -0.317), Colorf::new(-0.580, 0.106, -0.165), ];
self.foliage_color
.map(color_vec)
.unwrap_or_else(|| color_from_params(&FOLIAGE_COLORS, self, depth))
}
fn water_color(&self) -> Colorf {
const DEFAULT_WATER_COLOR: Colorf = Colorf::new(0.247, 0.463, 0.894);
self.water_color
.map(color_vec)
.unwrap_or(DEFAULT_WATER_COLOR)
}
}
const BIRCH_COLOR: Colorf = Colorf::new(0.502, 0.655, 0.333); const EVERGREEN_COLOR: Colorf = Colorf::new(0.380, 0.600, 0.380);
pub fn needs_biome(block: BlockColor) -> bool {
use super::BlockFlag::*;
block.is(Grass) || block.is(Foliage) || block.is(Water)
}
pub fn block_color(block: BlockColor, biome: Option<&Biome>, depth: f32) -> Colorf {
use super::BlockFlag::*;
let get_biome = || biome.expect("needs biome to determine block color");
let mut color = color_vec_unscaled(block.color);
if block.is(Grass) {
color *= get_biome().grass_color(depth);
}
if block.is(Foliage) {
color *= get_biome().foliage_color(depth);
}
if block.is(Birch) {
color *= BIRCH_COLOR;
}
if block.is(Spruce) {
color *= EVERGREEN_COLOR;
}
if block.is(Water) {
color *= get_biome().water_color();
}
color * (0.5 + 0.005 * depth)
}