use bevy::prelude::*;
use bevy_flora::{FloraSeason, FloraWetness, FloraWind, GustFront};
use crate::climate::{SeasonState, SurfaceWeathering, Weather};
use crate::plugin::{ElementsSystems, ensure_core};
use crate::wind::{WindGust, WindState};
pub const FLORA_FULL_WIND_MS: f32 = 20.0;
pub struct ElementsFloraPlugin;
impl Plugin for ElementsFloraPlugin {
fn build(&self, app: &mut App) {
ensure_core(app);
app.add_systems(
Update,
(drive_wind, drive_season).after(ElementsSystems::Readback),
);
}
}
fn drive_wind(
wind: Res<WindState>,
weather: Res<Weather>,
time: Res<Time>,
mut gusts: MessageReader<WindGust>,
flora: Option<ResMut<FloraWind>>,
) {
let Some(mut flora) = flora else {
gusts.clear();
return;
};
let mut next = *flora;
next.direction = wind.prevailing;
next.strength = (wind.speed_10m / FLORA_FULL_WIND_MS).clamp(0.0, 1.0);
next.turbulence = weather.gustiness;
next.gust_strength = ((wind.gust_factor - 1.0) / 0.5).clamp(0.0, 1.0);
for gust in gusts.read() {
next.launch_gust(
GustFront {
origin: gust.origin,
direction: gust.direction,
speed: gust.speed,
width: gust.width,
strength: gust.strength / FLORA_FULL_WIND_MS,
start: 0.0,
},
&time,
);
}
flora.set_if_neq(next);
}
fn drive_season(
season: Option<Res<SeasonState>>,
ground: Option<Res<SurfaceWeathering>>,
flora_season: Option<ResMut<FloraSeason>>,
wetness: Option<ResMut<FloraWetness>>,
) {
let snow = ground.as_ref().map_or(0.0, |g| g.snow_cover);
if let (Some(season), Some(mut flora_season)) = (season, flora_season) {
flora_season.set_if_neq(FloraSeason {
autumn: season.autumn,
leaf_fall: season.leaf_fall,
snow,
blossom: season.blossom,
});
}
if let (Some(ground), Some(mut wetness)) = (ground, wetness) {
wetness.set_if_neq(FloraWetness(ground.wetness));
}
}