also add contributors to /pumpkin command Co-Authored-By: Fyor <90567841+fyordev@users.noreply.github.com> Co-Authored-By: MartV0 <34748938+martv0@users.noreply.github.com> Co-Authored-By: FabseGP <fabsegp@fabseman.space>
96 lines
2.8 KiB
Rust
96 lines
2.8 KiB
Rust
use std::sync::LazyLock;
|
|
|
|
use serde::Deserialize;
|
|
|
|
use crate::{noise::simplex::OctaveSimplexNoiseSampler, random::legacy_rand::LegacyRand};
|
|
|
|
pub static TEMPERATURE_NOISE: LazyLock<OctaveSimplexNoiseSampler> = LazyLock::new(|| {
|
|
let mut rand = LegacyRand::from_seed(1234);
|
|
OctaveSimplexNoiseSampler::new(&mut rand, &[0])
|
|
});
|
|
|
|
pub static FROZEN_OCEAN_NOISE: LazyLock<OctaveSimplexNoiseSampler> = LazyLock::new(|| {
|
|
let mut rand = LegacyRand::from_seed(3456);
|
|
OctaveSimplexNoiseSampler::new(&mut rand, &[-2, -1, 0])
|
|
});
|
|
|
|
pub static FOLIAGE_NOISE: LazyLock<OctaveSimplexNoiseSampler> = LazyLock::new(|| {
|
|
let mut rand = LegacyRand::from_seed(2345);
|
|
OctaveSimplexNoiseSampler::new(&mut rand, &[0])
|
|
});
|
|
|
|
#[derive(Clone, Deserialize, Copy, Hash, PartialEq, Eq, Debug)]
|
|
#[serde(rename_all = "UPPERCASE")]
|
|
pub enum TemperatureModifier {
|
|
None,
|
|
Frozen,
|
|
}
|
|
|
|
impl TemperatureModifier {
|
|
pub fn convert_temperature(&self, x: f64, z: f64, temperature: f32) -> f32 {
|
|
match self {
|
|
Self::None => temperature,
|
|
Self::Frozen => {
|
|
let frozen_ocean_sample =
|
|
FROZEN_OCEAN_NOISE.sample(x * 0.05, z * 0.05, false) * 7.0;
|
|
let foliage_sample = FOLIAGE_NOISE.sample(x * 0.2, z * 0.2, false);
|
|
|
|
let threshold = frozen_ocean_sample + foliage_sample;
|
|
if threshold < 0.3 {
|
|
let foliage_sample = FOLIAGE_NOISE.sample(x * 0.09, z * 0.09, false);
|
|
if foliage_sample < 0.8 {
|
|
return 0.2f32;
|
|
}
|
|
}
|
|
|
|
temperature
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct Weather {
|
|
#[expect(dead_code)]
|
|
has_precipitation: bool,
|
|
temperature: f32,
|
|
temperature_modifier: TemperatureModifier,
|
|
#[expect(dead_code)]
|
|
downfall: f32,
|
|
}
|
|
|
|
impl Weather {
|
|
#[must_use]
|
|
pub const fn new(
|
|
has_precipitation: bool,
|
|
temperature: f32,
|
|
temperature_modifier: TemperatureModifier,
|
|
downfall: f32,
|
|
) -> Self {
|
|
Self {
|
|
has_precipitation,
|
|
temperature,
|
|
temperature_modifier,
|
|
downfall,
|
|
}
|
|
}
|
|
|
|
/// This is an expensive function and should be cached
|
|
pub fn compute_temperature(&self, x: f64, y: i32, z: f64, sea_level: i32) -> f32 {
|
|
let modified_temperature =
|
|
self.temperature_modifier
|
|
.convert_temperature(x, z, self.temperature);
|
|
let offset_sea_level = sea_level + 17;
|
|
|
|
if y > offset_sea_level {
|
|
let temperature_noise =
|
|
(TEMPERATURE_NOISE.sample(x / 8.0, z / 8.0, false) * 8.0) as f32;
|
|
|
|
modified_temperature
|
|
- (temperature_noise + y as f32 - offset_sea_level as f32) * 0.05f32 / 40.0f32
|
|
} else {
|
|
modified_temperature
|
|
}
|
|
}
|
|
}
|