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 / world / weather.rs

//! Rain and thunder: the weather timers and strengths of `World` and `WorldInfo`.

use crate::JavaRandom;

#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Weather {
    pub raining: bool,
    pub rain_time: i32,
    pub thundering: bool,
    pub thunder_time: i32,
    pub rain: f32,
    pub previous_rain: f32,
    pub thunder: f32,
    pub previous_thunder: f32,
}

impl Weather {
    /// The saved state with the strengths of `World.calculateInitialWeather`.
    pub fn new(raining: bool, rain_time: i32, thundering: bool, thunder_time: i32) -> Self {
        Self {
            raining,
            rain_time,
            thundering,
            thunder_time,
            rain: if raining { 1.0 } else { 0.0 },
            thunder: if raining && thundering { 1.0 } else { 0.0 },
            ..Self::default()
        }
    }

    /// `getRainStrength`.
    pub fn rain_strength(&self, partial: f32) -> f32 {
        self.previous_rain + (self.rain - self.previous_rain) * partial
    }

    /// `getWeightedThunderStrength`: thunder only counts as far as it rains.
    pub fn thunder_strength(&self, partial: f32) -> f32 {
        (self.previous_thunder + (self.thunder - self.previous_thunder) * partial)
            * self.rain_strength(partial)
    }

    /// `World.isRaining`.
    pub fn is_raining(&self) -> bool {
        f64::from(self.rain_strength(1.0)) > 0.2
    }

    /// `World.isThundering`.
    pub fn is_thundering(&self) -> bool {
        f64::from(self.thunder_strength(1.0)) > 0.9
    }

    /// The timers of `World.updateWeather`, which flip rain and thunder when they run out.
    pub fn advance(&mut self, random: &mut JavaRandom) {
        Self::count_down(&mut self.thunder_time, &mut self.thundering, 3_600, random);
        Self::count_down(&mut self.rain_time, &mut self.raining, 12_000, random);
        self.fade();
    }

    fn count_down(time: &mut i32, on: &mut bool, min_duration: i32, random: &mut JavaRandom) {
        if *time > 0 {
            *time -= 1;
            *on ^= *time <= 0;
        } else if *on {
            *time = random.next_int(12_000) + min_duration;
        } else {
            *time = random.next_int(168_000) + 12_000;
        }
    }

    /// The strengths following the flags by 0.01 per tick (`WorldClient.updateWeather`).
    pub fn fade(&mut self) {
        let step = |strength: f32, on: bool| {
            let delta = if on { 0.01 } else { -0.01 };
            ((f64::from(strength) + delta) as f32).clamp(0.0, 1.0)
        };
        self.previous_rain = self.rain;
        self.rain = step(self.rain, self.raining);
        self.previous_thunder = self.thunder;
        self.thunder = step(self.thunder, self.thundering);
    }

    /// `World.clearWeather`, after a night was slept through.
    pub fn clear(&mut self) {
        self.rain_time = 0;
        self.raining = false;
        self.thunder_time = 0;
        self.thundering = false;
    }
}