From 1209f0393dde23584679d5e2083bfa2a28f1fc60 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 13 May 2019 14:58:01 +0100 Subject: [PATCH] Added figure colour to shader and health component Former-commit-id: 222c39bd401ad0a9707eb348d5640717004dbf96 --- common/src/comp/mod.rs | 2 ++ common/src/comp/phys.rs | 6 ++-- common/src/comp/stats.rs | 38 ++++++++++++++++++++++++ common/src/msg/ecs_packet.rs | 2 ++ common/src/state.rs | 1 + server/src/lib.rs | 2 ++ voxygen/shaders/figure.frag | 3 +- voxygen/shaders/figure.vert | 1 + voxygen/src/menu/char_selection/scene.rs | 2 +- voxygen/src/render/pipelines/figure.rs | 11 +++++-- voxygen/src/scene/figure.rs | 19 ++++++++---- 11 files changed, 74 insertions(+), 13 deletions(-) create mode 100644 common/src/comp/stats.rs diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs index e3c35e5ab8..a75e09c083 100644 --- a/common/src/comp/mod.rs +++ b/common/src/comp/mod.rs @@ -2,6 +2,7 @@ pub mod actor; pub mod agent; pub mod phys; pub mod player; +pub mod stats; // Reexports pub use actor::Actor; @@ -12,3 +13,4 @@ pub use actor::HumanoidBody; pub use actor::QuadrupedBody; pub use agent::{Agent, Control}; pub use player::Player; +pub use stats::Stats; diff --git a/common/src/comp/phys.rs b/common/src/comp/phys.rs index dd8b02ced3..67df6ac1ba 100644 --- a/common/src/comp/phys.rs +++ b/common/src/comp/phys.rs @@ -7,7 +7,7 @@ use vek::*; pub struct Pos(pub Vec3); impl Component for Pos { - type Storage = FlaggedStorage>; + type Storage = VecStorage; } // Vel @@ -16,7 +16,7 @@ impl Component for Pos { pub struct Vel(pub Vec3); impl Component for Vel { - type Storage = FlaggedStorage>; + type Storage = VecStorage; } // Dir @@ -25,7 +25,7 @@ impl Component for Vel { pub struct Dir(pub Vec3); impl Component for Dir { - type Storage = FlaggedStorage>; + type Storage = VecStorage; } // Dir diff --git a/common/src/comp/stats.rs b/common/src/comp/stats.rs new file mode 100644 index 0000000000..3b6e263af2 --- /dev/null +++ b/common/src/comp/stats.rs @@ -0,0 +1,38 @@ +use specs::{Component, FlaggedStorage, VecStorage}; + +#[derive(Copy, Clone, Debug, Serialize, Deserialize)] +pub struct Health { + pub current: u32, + pub maximum: u32, + pub last_change: Option<(i32, f64)>, +} + +impl Health { + pub fn change_by(&mut self, amount: i32, current_time: f64) { + self.current = (self.current as i32 + amount).max(0) as u32; + self.last_change = Some((amount, current_time)); + } +} + +#[derive(Copy, Clone, Debug, Serialize, Deserialize)] +pub struct Stats { + pub hp: Health, + pub xp: u32, +} + +impl Default for Stats { + fn default() -> Self { + Self { + hp: Health { + current: 100, + maximum: 100, + last_change: None, + }, + xp: 0, + } + } +} + +impl Component for Stats { + type Storage = FlaggedStorage>; +} diff --git a/common/src/msg/ecs_packet.rs b/common/src/msg/ecs_packet.rs index b7da55f0a8..74ffabacbf 100644 --- a/common/src/msg/ecs_packet.rs +++ b/common/src/msg/ecs_packet.rs @@ -11,6 +11,7 @@ sphynx::sum_type! { Dir(comp::phys::Dir), Actor(comp::Actor), Player(comp::Player), + Stats(comp::Stats), } } // Automatically derive From for Phantom for each variant Phantom::T(PhantomData) @@ -22,6 +23,7 @@ sphynx::sum_type! { Dir(PhantomData), Actor(PhantomData), Player(PhantomData), + Stats(PhantomData), } } impl sphynx::Packet for EcsPacket { diff --git a/common/src/state.rs b/common/src/state.rs index 509ca67ca7..e0054dfa69 100644 --- a/common/src/state.rs +++ b/common/src/state.rs @@ -97,6 +97,7 @@ impl State { // Register synced components ecs.register_synced::(); ecs.register_synced::(); + ecs.register_synced::(); // Register unsynched (or synced by other means) components ecs.register::(); diff --git a/server/src/lib.rs b/server/src/lib.rs index 1430a7f5e1..6fb89abf48 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -125,6 +125,7 @@ impl Server { .with(comp::phys::Dir(Vec3::unit_y())) .with(comp::AnimationHistory::new(comp::Animation::Idle)) .with(comp::Actor::Character { name, body }) + .with(comp::Stats::default()) } pub fn create_player_character( @@ -141,6 +142,7 @@ impl Server { body: comp::Body::Humanoid(body), }, ); + state.write_component(entity, comp::Stats::default()); state.write_component(entity, comp::phys::Pos(Vec3::new(0.0, 0.0, 64.0))); state.write_component(entity, comp::phys::Vel(Vec3::zero())); state.write_component(entity, comp::phys::Dir(Vec3::unit_y())); diff --git a/voxygen/shaders/figure.frag b/voxygen/shaders/figure.frag index 4a933ab4f7..9f35b6b04a 100644 --- a/voxygen/shaders/figure.frag +++ b/voxygen/shaders/figure.frag @@ -10,6 +10,7 @@ flat in uint f_bone_idx; layout (std140) uniform u_locals { mat4 model_mat; + vec4 model_col; }; struct BoneData { @@ -36,5 +37,5 @@ void main() { float sun_diffuse = dot(sun_dir, world_norm) * 0.5; - tgt_color = vec4(f_col * (ambient + sun_diffuse), 1.0); + tgt_color = model_col * vec4(f_col * (ambient + sun_diffuse), 1.0); } diff --git a/voxygen/shaders/figure.vert b/voxygen/shaders/figure.vert index 258f4f1f45..4db80ee7c4 100644 --- a/voxygen/shaders/figure.vert +++ b/voxygen/shaders/figure.vert @@ -10,6 +10,7 @@ in uint v_bone_idx; layout (std140) uniform u_locals { mat4 model_mat; + vec4 model_col; }; struct BoneData { diff --git a/voxygen/src/menu/char_selection/scene.rs b/voxygen/src/menu/char_selection/scene.rs index b295904796..7ff104e41f 100644 --- a/voxygen/src/menu/char_selection/scene.rs +++ b/voxygen/src/menu/char_selection/scene.rs @@ -100,7 +100,7 @@ impl Scene { self.figure_state.skeleton_mut().interpolate(&tgt_skeleton); self.figure_state - .update(renderer, Vec3::zero(), -Vec3::unit_y()); + .update(renderer, Vec3::zero(), -Vec3::unit_y(), Rgba::broadcast(1.0)); } pub fn render(&mut self, renderer: &mut Renderer, client: &Client) { diff --git a/voxygen/src/render/pipelines/figure.rs b/voxygen/src/render/pipelines/figure.rs index e7fc4436bb..d7036f5d3d 100644 --- a/voxygen/src/render/pipelines/figure.rs +++ b/voxygen/src/render/pipelines/figure.rs @@ -27,6 +27,7 @@ gfx_defines! { constant Locals { model_mat: [[f32; 4]; 4] = "model_mat", + model_col: [f32; 4] = "model_col", } constant BoneData { @@ -62,13 +63,17 @@ impl Vertex { } impl Locals { - pub fn new(model_mat: Mat4) -> Self { + pub fn new(model_mat: Mat4, col: Rgba) -> Self { Self { model_mat: arr_to_mat(model_mat.into_col_array()), + model_col: col.into_array(), } } - pub fn default() -> Self { - Self::new(Mat4::identity()) +} + +impl Default for Locals { + fn default() -> Self { + Self::new(Mat4::identity(), Rgba::broadcast(1.0)) } } diff --git a/voxygen/src/scene/figure.rs b/voxygen/src/scene/figure.rs index b93b72ab3b..d4e98dee22 100644 --- a/voxygen/src/scene/figure.rs +++ b/voxygen/src/scene/figure.rs @@ -316,13 +316,14 @@ impl FigureMgr { pub fn maintain(&mut self, renderer: &mut Renderer, client: &Client) { let time = client.state().get_time(); let ecs = client.state().ecs(); - for (entity, pos, vel, dir, actor, animation_history) in ( + for (entity, pos, vel, dir, actor, animation_history, stats) in ( &ecs.entities(), &ecs.read_storage::(), &ecs.read_storage::(), &ecs.read_storage::(), &ecs.read_storage::(), &ecs.read_storage::(), + ecs.read_storage::().maybe(), ) .join() { @@ -353,7 +354,7 @@ impl FigureMgr { state.skeleton.interpolate(&target_skeleton); - state.update(renderer, pos.0, dir.0); + state.update(renderer, pos.0, dir.0, Rgba::white()); }, Body::Quadruped(body) => { let state = self.quadruped_states.entry(entity).or_insert_with(|| { @@ -382,7 +383,15 @@ impl FigureMgr { state.skeleton.interpolate(&target_skeleton); - state.update(renderer, pos.0, dir.0); + // Change in health as color! + let col = stats + .and_then(|stats| stats.hp.last_change) + .map(|(change_by, change_time)| { + Rgba::new(1.0, 0.7, 0.7, 1.0) + }) + .unwrap_or(Rgba::broadcast(1.0)); + + state.update(renderer, pos.0, dir.0, col); }, }, // TODO: Non-character actors @@ -442,12 +451,12 @@ impl FigureState { } } - pub fn update(&mut self, renderer: &mut Renderer, pos: Vec3, dir: Vec3) { + pub fn update(&mut self, renderer: &mut Renderer, pos: Vec3, dir: Vec3, col: Rgba) { let mat = Mat4::::identity() * Mat4::translation_3d(pos) * Mat4::rotation_z(-dir.x.atan2(dir.y)); // + f32::consts::PI / 2.0); - let locals = FigureLocals::new(mat); + let locals = FigureLocals::new(mat, col); renderer.update_consts(&mut self.locals, &[locals]).unwrap(); renderer