alex/beta-minecraft-rust
Minecraft Beta 1.7.3 Rewrite
BRANCH 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
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;
}
}