2022-01-14 12:19:46 -05:00
|
|
|
use ::rltk::Point;
|
2022-01-10 10:21:19 -05:00
|
|
|
use ::specs::prelude::*;
|
|
|
|
use rltk::DistanceAlg;
|
|
|
|
|
|
|
|
use super::{LightSource, Map, Position, Viewshed};
|
2022-01-14 12:19:46 -05:00
|
|
|
use crate::colors;
|
2022-01-10 10:21:19 -05:00
|
|
|
|
|
|
|
pub struct LightingSystem {}
|
|
|
|
|
|
|
|
impl<'a> System<'a> for LightingSystem {
|
|
|
|
#[allow(clippy::type_complexity)]
|
|
|
|
type SystemData = (
|
|
|
|
WriteExpect<'a, Map>,
|
|
|
|
ReadStorage<'a, Viewshed>,
|
|
|
|
ReadStorage<'a, Position>,
|
|
|
|
ReadStorage<'a, LightSource>,
|
|
|
|
);
|
|
|
|
|
|
|
|
fn run(&mut self, data: Self::SystemData) {
|
|
|
|
let (mut map, viewshed, positions, lighting) = data;
|
|
|
|
|
|
|
|
if map.outdoors {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for l in map.light.iter_mut() {
|
2022-01-14 12:19:46 -05:00
|
|
|
*l = colors::BLACK;
|
2022-01-10 10:21:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
for (viewshed, pos, light) in (&viewshed, &positions, &lighting).join() {
|
|
|
|
let light_point = Point::from(*pos);
|
|
|
|
let range_f = light.range as f32;
|
|
|
|
|
|
|
|
for t in viewshed.visible_tiles.iter() {
|
|
|
|
if t.x > 0 && t.x < map.width && t.y > 0 && t.y < map.height {
|
|
|
|
let idx = map.xy_idx(t.x, t.y);
|
|
|
|
let distance = DistanceAlg::Pythagoras.distance2d(light_point, *t);
|
|
|
|
let intensity = (range_f - distance) / range_f;
|
|
|
|
|
|
|
|
map.light[idx] = map.light[idx] + (light.color * intensity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|