Theme

alex/beta-minecraft-rust

Minecraft Beta 1.7.3 Rewrite

BRANCH main
main
SNAPSHOT Draw terrain GPU-driven from packed per-section buffers with GPU occlusion culling, add a render distance slider (2-128) with a quad/disk shape, cut chunk bookkeeping at high render distances, and fix a light underflow at y=0
DOWNLOAD
Download file

root / crates / common / src / biome.rs

use std::sync::LazyLock;

use crate::world::Block;

#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum Biome {
    Rainforest,
    Swampland,
    SeasonalForest,
    Forest,
    Savanna,
    Shrubland,
    Taiga,
    Desert,
    Plains,
    IceDesert,
    Tundra,
    Hell,
    Sky,
}

static LOOKUP: LazyLock<[Biome; 4096]> = LazyLock::new(|| {
    std::array::from_fn(|i| Biome::classify((i % 64) as f32 / 63.0, (i / 64) as f32 / 63.0))
});

impl Biome {
    /// Port of `BiomeGenBase.getBiome`.
    fn classify(temperature: f32, rainfall: f32) -> Self {
        let rainfall = rainfall * temperature;
        if temperature < 0.1 {
            Self::Tundra
        } else if rainfall < 0.2 {
            if temperature < 0.5 {
                Self::Tundra
            } else if temperature < 0.95 {
                Self::Savanna
            } else {
                Self::Desert
            }
        } else if rainfall > 0.5 && temperature < 0.7 {
            Self::Swampland
        } else if temperature < 0.5 {
            Self::Taiga
        } else if temperature < 0.97 {
            if rainfall < 0.35 {
                Self::Shrubland
            } else {
                Self::Forest
            }
        } else if rainfall < 0.45 {
            Self::Plains
        } else if rainfall < 0.9 {
            Self::SeasonalForest
        } else {
            Self::Rainforest
        }
    }

    /// Port of `BiomeGenBase.getBiomeFromLookup`.
    pub fn lookup(temperature: f64, rainfall: f64) -> Self {
        let t = (temperature * 63.0) as usize;
        let r = (rainfall * 63.0) as usize;
        LOOKUP[t + r * 64]
    }

    /// `getEnableSnow`.
    pub fn snows(self) -> bool {
        matches!(self, Self::Taiga | Self::IceDesert | Self::Tundra)
    }

    /// `canSpawnLightningBolt`: it rains, and the rain is not snow.
    pub fn rains(self) -> bool {
        !self.snows()
            && !matches!(
                self,
                Self::Desert | Self::IceDesert | Self::Hell | Self::Sky
            )
    }

    pub fn top_block(self) -> Block {
        match self {
            Self::Desert | Self::IceDesert => Block::SAND,
            _ => Block::GRASS,
        }
    }

    pub fn filler_block(self) -> Block {
        match self {
            Self::Desert | Self::IceDesert => Block::SAND,
            _ => Block::DIRT,
        }
    }
}