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