From 5cdfb26e0d840a261c8ca048df5e19ddb56c864f Mon Sep 17 00:00:00 2001
From: Joshua Barretto <joshua.s.barretto@gmail.com>
Date: Sun, 21 Jul 2019 17:50:13 +0100
Subject: [PATCH] Added LightEmitter component

---
 common/src/comp/mod.rs       |  2 ++
 common/src/comp/visual.rs    | 21 +++++++++++++++++++++
 common/src/msg/ecs_packet.rs |  2 ++
 common/src/state.rs          |  1 +
 common/src/sys/controller.rs |  6 +++---
 server/src/lib.rs            |  2 +-
 voxygen/src/scene/mod.rs     | 16 ++++++++++++----
 7 files changed, 42 insertions(+), 8 deletions(-)
 create mode 100644 common/src/comp/visual.rs

diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs
index 655177b0ee..25321f555d 100644
--- a/common/src/comp/mod.rs
+++ b/common/src/comp/mod.rs
@@ -8,6 +8,7 @@ mod inventory;
 mod phys;
 mod player;
 mod stats;
+mod visual;
 
 // Reexports
 pub use action_state::ActionState;
@@ -22,3 +23,4 @@ pub use inventory::{item, Inventory};
 pub use phys::{ForceUpdate, Ori, Pos, Vel};
 pub use player::Player;
 pub use stats::{Dying, HealthSource, Stats};
+pub use visual::LightEmitter;
diff --git a/common/src/comp/visual.rs b/common/src/comp/visual.rs
new file mode 100644
index 0000000000..df0102b46d
--- /dev/null
+++ b/common/src/comp/visual.rs
@@ -0,0 +1,21 @@
+use specs::{Component, FlaggedStorage, VecStorage};
+use vek::*;
+
+#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
+pub struct LightEmitter {
+    pub col: Rgb<f32>,
+    pub strength: f32,
+}
+
+impl Default for LightEmitter {
+    fn default() -> Self {
+        Self {
+            col: Rgb::one(),
+            strength: 250.0,
+        }
+    }
+}
+
+impl Component for LightEmitter {
+    type Storage = FlaggedStorage<Self, VecStorage<Self>>;
+}
diff --git a/common/src/msg/ecs_packet.rs b/common/src/msg/ecs_packet.rs
index d1d7d25dae..b2f3d8bbbe 100644
--- a/common/src/msg/ecs_packet.rs
+++ b/common/src/msg/ecs_packet.rs
@@ -24,6 +24,7 @@ sphynx::sum_type! {
         Player(comp::Player),
         CanBuild(comp::CanBuild),
         Stats(comp::Stats),
+        LightEmitter(comp::LightEmitter),
     }
 }
 // Automatically derive From<T> for EcsCompPhantom
@@ -38,6 +39,7 @@ sphynx::sum_type! {
         Player(PhantomData<comp::Player>),
         CanBuild(PhantomData<comp::CanBuild>),
         Stats(PhantomData<comp::Stats>),
+        LightEmitter(PhantomData<comp::LightEmitter>),
     }
 }
 impl sphynx::CompPacket for EcsCompPacket {
diff --git a/common/src/state.rs b/common/src/state.rs
index 103c70cb5e..06c6d49fe4 100644
--- a/common/src/state.rs
+++ b/common/src/state.rs
@@ -130,6 +130,7 @@ impl State {
         ecs.register_synced::<comp::Player>();
         ecs.register_synced::<comp::Stats>();
         ecs.register_synced::<comp::CanBuild>();
+        ecs.register_synced::<comp::LightEmitter>();
 
         // Register components synced by other means
         ecs.register::<comp::Pos>();
diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs
index a4f6fcc357..e9ae987024 100644
--- a/common/src/sys/controller.rs
+++ b/common/src/sys/controller.rs
@@ -9,7 +9,7 @@ pub struct Sys;
 impl<'a> System<'a> for Sys {
     type SystemData = (
         Entities<'a>,
-        ReadStorage<'a, Controller>,
+        WriteStorage<'a, Controller>,
         ReadStorage<'a, Stats>,
         ReadStorage<'a, Vel>,
         WriteStorage<'a, ActionState>,
@@ -26,7 +26,7 @@ impl<'a> System<'a> for Sys {
         &mut self,
         (
             entities,
-            controllers,
+            mut controllers,
             stats,
             velocities,
             mut action_states,
@@ -41,7 +41,7 @@ impl<'a> System<'a> for Sys {
     ) {
         for (entity, controller, stats, vel, mut a) in (
             &entities,
-            &controllers,
+            &mut controllers,
             &stats,
             &velocities,
             // Although this is changed, it is only kept for this system
diff --git a/server/src/lib.rs b/server/src/lib.rs
index b7c2389c68..e9e6bb5909 100644
--- a/server/src/lib.rs
+++ b/server/src/lib.rs
@@ -172,7 +172,7 @@ impl Server {
             .with(comp::Vel(Vec3::zero()))
             .with(comp::Ori(Vec3::unit_y()))
             .with(comp::Body::Object(object))
-            //.with(comp::Stats::new("Objecty McObjectface".to_string()))
+            .with(comp::LightEmitter::default())
             .with(comp::ActionState::default())
             .with(comp::ForceUpdate)
     }
diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs
index 68e2460b6b..9aee0f750e 100644
--- a/voxygen/src/scene/mod.rs
+++ b/voxygen/src/scene/mod.rs
@@ -138,14 +138,22 @@ impl Scene {
         self.loaded_distance = (0.98 * self.loaded_distance + 0.02 * loaded_distance).max(0.01);
 
         // Update light constants
-        let mut lights = (&client.state().ecs().read_storage::<comp::Pos>(),)
+        let mut lights = (
+            &client.state().ecs().read_storage::<comp::Pos>(),
+            &client.state().ecs().read_storage::<comp::LightEmitter>(),
+        )
             .join()
-            .filter(|(pos,)| {
+            .filter(|(pos, _)| {
                 (pos.0.distance_squared(player_pos) as f32)
                     < self.loaded_distance.powf(2.0) + LIGHT_DIST_RADIUS
             })
-            .map(|(pos,)| pos.0)
-            .map(|pos| Light::new(pos + Vec3::unit_z(), Rgb::broadcast(1.0), 100.0)) // TODO: Don't add 1 to z!
+            .map(|(pos, light_emitter)| {
+                Light::new(
+                    pos.0 + Vec3::unit_z(),
+                    light_emitter.col,
+                    light_emitter.strength,
+                )
+            }) // TODO: Don't add 1 to z!
             .collect::<Vec<_>>();
         lights.sort_by_key(|light| {
             Vec3::from(Vec4::from(light.pos)).distance_squared(player_pos) as i32