Add lighting system
This commit is contained in:
parent
f3ccf50b91
commit
6f9aa54896
@ -285,6 +285,12 @@ pub struct OtherLevelPosition {
|
||||
pub depth: i32,
|
||||
}
|
||||
|
||||
#[derive(Component, Serialize, Deserialize, Clone)]
|
||||
pub struct LightSource {
|
||||
pub color: RGB,
|
||||
pub range: i32,
|
||||
}
|
||||
|
||||
// Serialization helper code. We need to implement ConvertSaveLoad for each type that contains an
|
||||
// Entity.
|
||||
|
||||
|
45
src/lighting_system.rs
Normal file
45
src/lighting_system.rs
Normal file
@ -0,0 +1,45 @@
|
||||
use ::rltk::{Point, RGB};
|
||||
use ::specs::prelude::*;
|
||||
use rltk::DistanceAlg;
|
||||
|
||||
use super::{LightSource, Map, Position, Viewshed};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
let black = RGB::from_f32(0., 0., 0.);
|
||||
for l in map.light.iter_mut() {
|
||||
*l = black;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@ mod gamesystem;
|
||||
mod gui;
|
||||
mod hunger_system;
|
||||
mod inventory_system;
|
||||
mod lighting_system;
|
||||
mod map;
|
||||
pub mod map_builders;
|
||||
mod map_indexing_system;
|
||||
@ -38,6 +39,7 @@ pub use game_log::GameLog;
|
||||
use gui::{show_cheat_mode, CheatMenuResult};
|
||||
use hunger_system::HungerSystem;
|
||||
use inventory_system::{ItemCollectionSystem, ItemDropSystem, ItemRemoveSystem, ItemUseSystem};
|
||||
use lighting_system::LightingSystem;
|
||||
pub use map::*;
|
||||
use map_indexing_system::MapIndexingSystem;
|
||||
use melee_combat_system::MeleeCombatSystem;
|
||||
@ -152,6 +154,9 @@ impl State {
|
||||
let mut particles = ParticleSpawnSystem {};
|
||||
particles.run_now(&self.ecs);
|
||||
|
||||
let mut lighting = LightingSystem {};
|
||||
lighting.run_now(&self.ecs);
|
||||
|
||||
self.ecs.maintain();
|
||||
}
|
||||
}
|
||||
@ -468,6 +473,7 @@ fn main() -> ::rltk::BError {
|
||||
InBackpack,
|
||||
InflictsDamage,
|
||||
Item,
|
||||
LightSource,
|
||||
LootTable,
|
||||
MagicMapper,
|
||||
MeleeWeapon,
|
||||
|
@ -8,6 +8,7 @@ use ::rltk::{Algorithm2D, BaseMap, Point, SmallVec};
|
||||
use ::serde::{Deserialize, Serialize};
|
||||
use ::specs::prelude::*;
|
||||
pub use dungeon::*;
|
||||
use rltk::RGB;
|
||||
pub use themes::*;
|
||||
pub use tiletype::{tile_opaque, tile_walkable, TileType};
|
||||
|
||||
@ -25,6 +26,8 @@ pub struct Map {
|
||||
pub bloodstains: HashSet<usize>,
|
||||
pub view_blocked: HashSet<usize>,
|
||||
pub name: String,
|
||||
pub outdoors: bool,
|
||||
pub light: Vec<RGB>,
|
||||
|
||||
#[serde(skip_serializing)]
|
||||
#[serde(skip_deserializing)]
|
||||
@ -74,6 +77,8 @@ impl Map {
|
||||
bloodstains: HashSet::new(),
|
||||
view_blocked: HashSet::new(),
|
||||
name: name.to_string(),
|
||||
outdoors: true,
|
||||
light: vec![RGB::from_f32(0., 0., 0.); map_tile_count],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,9 @@ pub fn tile_glyph(idx: usize, map: &Map) -> (FontCharType, RGB, RGB) {
|
||||
if !map.visible_tiles[idx] {
|
||||
fg = fg.to_greyscale();
|
||||
bg = RGB::from_f32(0., 0., 0.);
|
||||
} else if !map.outdoors {
|
||||
fg = fg * map.light[idx];
|
||||
bg = bg * map.light[idx];
|
||||
}
|
||||
|
||||
(glyph, fg, bg)
|
||||
|
@ -4,7 +4,7 @@ use super::{
|
||||
AreaStartingPosition, BuilderChain, BuilderMap, CullUnreachable, DistantExit,
|
||||
DrunkardsWalkBuilder, MetaMapBuilder, VoronoiSpawning, XStart, YStart,
|
||||
};
|
||||
use crate::map::{self, TileType};
|
||||
use crate::map::TileType;
|
||||
|
||||
pub fn limestone_cavern_builder(
|
||||
new_depth: i32,
|
||||
@ -82,5 +82,6 @@ impl CaveDecorator {
|
||||
}
|
||||
|
||||
build_data.take_snapshot();
|
||||
build_data.map.outdoors = false;
|
||||
}
|
||||
}
|
||||
|
@ -80,6 +80,7 @@ pub fn save_game(ecs: &mut World) {
|
||||
InBackpack,
|
||||
InflictsDamage,
|
||||
Item,
|
||||
LightSource,
|
||||
LootTable,
|
||||
MagicMapper,
|
||||
MeleeWeapon,
|
||||
@ -184,6 +185,7 @@ pub fn load_game(ecs: &mut World) {
|
||||
InBackpack,
|
||||
InflictsDamage,
|
||||
Item,
|
||||
LightSource,
|
||||
LootTable,
|
||||
MagicMapper,
|
||||
MeleeWeapon,
|
||||
|
@ -50,6 +50,10 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
|
||||
xp: 0,
|
||||
level: 1,
|
||||
})
|
||||
.with(LightSource {
|
||||
color: RGB::from_f32(1.0, 1.0, 0.5),
|
||||
range: 8,
|
||||
})
|
||||
.marked::<SimpleMarker<SerializeMe>>()
|
||||
.build();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user