Skip to content

Commit

Permalink
Base evaporation rate on ReceivedLight, not weather (Leafwing-Studi…
Browse files Browse the repository at this point in the history
…os#847)

* Base evaporation rate on ReceivedLight, not weather

* Clippy

* Add light component to mocked tiles to fix failing test
  • Loading branch information
alice-i-cecile authored May 6, 2023
1 parent 6bf39ce commit fd044ac
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 30 deletions.
11 changes: 0 additions & 11 deletions emergence_lib/src/simulation/weather.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,6 @@ impl Weather {
}
}

/// The relative rate of evaporation for this kind of weather.
///
/// The evaporation rate of [`Weather::Clear`] is defined to be 1.0.
pub(crate) fn evaporation_rate(self) -> f32 {
match self {
Self::Clear => 1.,
Self::Cloudy => 0.5,
Self::Rainy => 0.1,
}
}

/// The relative rate of precipitation for this kind of weather.
///
/// The precipitation rate of [`Weather::Clear`] is defined to be 0.0.
Expand Down
54 changes: 35 additions & 19 deletions emergence_lib/src/water/water_dynamics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use bevy::{prelude::*, utils::HashMap};

use crate::{
asset_management::manifest::Id,
light::{shade::ReceivedLight, Illuminance},
simulation::{
geometry::{Height, MapGeometry, TilePos, Volume},
time::InGameTime,
Expand All @@ -12,38 +13,49 @@ use crate::{
terrain::terrain_manifest::{Terrain, TerrainManifest},
};

use super::{FlowVelocity, WaterConfig, WaterTable};
use super::{FlowVelocity, WaterConfig, WaterDepth, WaterTable};

/// Evaporates water from surface water.
pub(super) fn evaporation(
mut water_table: ResMut<WaterTable>,
terrain_query: Query<&Id<Terrain>>,
terrain_query: Query<(&TilePos, &ReceivedLight, &Id<Terrain>)>,
terrain_manifest: Res<TerrainManifest>,
water_config: Res<WaterConfig>,
map_geometry: Res<MapGeometry>,
in_game_time: Res<InGameTime>,
fixed_time: Res<FixedTime>,
current_weather: Res<CurrentWeather>,
) {
let evaporation_per_second = water_config.evaporation_rate.0 / in_game_time.seconds_per_day();
let elapsed_time = fixed_time.period.as_secs_f32();

let evaporation_rate =
evaporation_per_second * elapsed_time * current_weather.get().evaporation_rate();
let evaporation_rate = evaporation_per_second * elapsed_time;

for tile_pos in map_geometry.valid_tile_positions() {
// Surface water evaporation
let total_evaporated = if water_table.surface_water_depth(tile_pos) > Height::ZERO {
Volume(evaporation_rate)
} else {
let terrain_entity = map_geometry.get_terrain(tile_pos).unwrap();
let terrain_id = *terrain_query.get(terrain_entity).unwrap();
let evaporation_ratio = terrain_manifest.get(terrain_id).water_evaporation_rate;

Volume(evaporation_rate * evaporation_ratio)
};
for (&tile_pos, received_light, terrain_id) in terrain_query.iter() {
let mut evaporation_this_tile =
Volume(evaporation_rate * received_light.evaporation_ratio());

water_table.remove(tile_pos, total_evaporated);
if matches!(
water_table.water_depth(tile_pos),
WaterDepth::Underground(..)
) {
let terrain_data = terrain_manifest.get(*terrain_id);
evaporation_this_tile = evaporation_this_tile * terrain_data.water_evaporation_rate;
}

water_table.remove(tile_pos, evaporation_this_tile);
}
}

impl ReceivedLight {
/// The rate at which water evaporates from tiles with this amount of light.
///
/// This is a multiplier on the evaporation rate.
/// [`Illuminance::BrightlyLit`] should always have a value of 1.0.
fn evaporation_ratio(&self) -> f32 {
match self.0 {
Illuminance::Dark => 0.2,
Illuminance::DimlyLit => 0.5,
Illuminance::BrightlyLit => 1.0,
}
}
}

Expand Down Expand Up @@ -382,7 +394,11 @@ mod tests {
{
let terrain_entity = app
.world
.spawn((Id::<Terrain>::from_name("test".to_string()), tile_pos))
.spawn((
Id::<Terrain>::from_name("test".to_string()),
tile_pos,
ReceivedLight::default(),
))
.id();
map_geometry.add_terrain(tile_pos, terrain_entity)
}
Expand Down

0 comments on commit fd044ac

Please sign in to comment.