From 4e7f8c686a0b6880de54b3ed3ea42a728f60c0ce Mon Sep 17 00:00:00 2001 From: CapsizeGlimmer <5827660-CapsizeGlimmer@users.noreply.gitlab.com> Date: Mon, 4 May 2020 15:15:31 +0000 Subject: [PATCH] Equipped lanterns now provide an illumination effect. --- CHANGELOG.md | 1 + assets/common/items/lantern/black_0.ron | 9 +- assets/common/items/lantern/blue_0.ron | 12 +++ assets/common/items/lantern/green_0.ron | 9 +- assets/common/items/lantern/red_0.ron | 12 +++ .../voxygen/element/icons/lantern_blue-0.png | 3 + .../voxygen/element/icons/lantern_red-0.png | 3 + assets/voxygen/i18n/en.ron | 1 + assets/voxygen/item_image_manifest.ron | 10 ++- assets/voxygen/voxel/armor/lantern/blue-0.vox | 3 + assets/voxygen/voxel/armor/lantern/red-0.vox | 3 + .../voxel/humanoid_lantern_manifest.ron | 12 ++- client/src/lib.rs | 5 ++ common/src/assets/mod.rs | 2 +- common/src/comp/controller.rs | 1 + common/src/comp/inventory/item/mod.rs | 27 +++++- common/src/comp/inventory/mod.rs | 10 +++ common/src/comp/inventory/test.rs | 4 +- common/src/comp/mod.rs | 2 +- common/src/comp/visual.rs | 27 +++++- common/src/event.rs | 1 + common/src/state.rs | 4 + common/src/sys/controller.rs | 3 + server/src/cmd.rs | 85 +++++++++---------- server/src/events/entity_creation.rs | 3 +- server/src/events/entity_manipulation.rs | 4 + server/src/events/interaction.rs | 37 ++++++++ server/src/events/inventory_manip.rs | 37 ++++++-- server/src/events/mod.rs | 3 +- server/src/state_ext.rs | 1 - voxygen/src/anim/biped_large/mod.rs | 50 ++++++----- voxygen/src/anim/bird_medium/mod.rs | 42 ++++----- voxygen/src/anim/bird_small/mod.rs | 42 ++++----- voxygen/src/anim/character/mod.rs | 54 +++++++----- voxygen/src/anim/critter/mod.rs | 42 ++++----- voxygen/src/anim/dragon/mod.rs | 42 ++++----- voxygen/src/anim/fish_medium/mod.rs | 42 ++++----- voxygen/src/anim/fish_small/mod.rs | 42 ++++----- voxygen/src/anim/fixture/mod.rs | 42 ++++----- voxygen/src/anim/golem/mod.rs | 46 +++++----- voxygen/src/anim/mod.rs | 2 +- voxygen/src/anim/object/mod.rs | 41 ++++----- voxygen/src/anim/quadruped_medium/mod.rs | 42 ++++----- voxygen/src/anim/quadruped_small/mod.rs | 42 ++++----- voxygen/src/controller.rs | 3 + voxygen/src/hud/item_imgs.rs | 6 +- voxygen/src/scene/figure/load.rs | 29 ++++--- voxygen/src/scene/figure/mod.rs | 75 ++++++++++++++-- voxygen/src/scene/mod.rs | 13 +-- voxygen/src/session.rs | 3 + voxygen/src/settings.rs | 4 + voxygen/src/window.rs | 2 + 52 files changed, 689 insertions(+), 351 deletions(-) create mode 100644 assets/common/items/lantern/blue_0.ron create mode 100644 assets/common/items/lantern/red_0.ron create mode 100644 assets/voxygen/element/icons/lantern_blue-0.png create mode 100644 assets/voxygen/element/icons/lantern_red-0.png create mode 100644 assets/voxygen/voxel/armor/lantern/blue-0.vox create mode 100644 assets/voxygen/voxel/armor/lantern/red-0.vox diff --git a/CHANGELOG.md b/CHANGELOG.md index 63ee5cbffc..62097b5c4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Player now starts with a lantern. Equipping/unequipping a lantern has the same effect as the `/lantern` command - Added music system - Added zoomable and rotatable minimap - Added rotating orientation marker to main-map diff --git a/assets/common/items/lantern/black_0.ron b/assets/common/items/lantern/black_0.ron index cabb197911..e9e67e729b 100644 --- a/assets/common/items/lantern/black_0.ron +++ b/assets/common/items/lantern/black_0.ron @@ -1,5 +1,12 @@ Item( name: "Black Lantern", description: "Used by city guards.", - kind: Lantern(Black0), + kind: Lantern( + ( + kind: Black0, + color: (r: 255, g: 190, b: 75), + strength_thousandths: 3000, + flicker_thousandths: 300, + ), + ), ) diff --git a/assets/common/items/lantern/blue_0.ron b/assets/common/items/lantern/blue_0.ron new file mode 100644 index 0000000000..08b0ced767 --- /dev/null +++ b/assets/common/items/lantern/blue_0.ron @@ -0,0 +1,12 @@ +Item( + name: "Cool Blue Lantern", + description: "This lantern is surprisingly cold when lit.", + kind: Lantern( + ( + kind: Blue0, + color: (r: 64, g: 127, b: 153), + strength_thousandths: 4000, + flicker_thousandths: 250, + ), + ), +) diff --git a/assets/common/items/lantern/green_0.ron b/assets/common/items/lantern/green_0.ron index ea7d5cbcc7..2b8bdccc01 100644 --- a/assets/common/items/lantern/green_0.ron +++ b/assets/common/items/lantern/green_0.ron @@ -1,5 +1,12 @@ Item( name: "Lime Zest Lantern", description: "It has an opening that could fit a ring...", - kind: Lantern(Green0), + kind: Lantern( + ( + kind: Green0, + color: (r: 192, g: 255, b: 76), + strength_thousandths: 4000, + flicker_thousandths: 500, + ), + ), ) diff --git a/assets/common/items/lantern/red_0.ron b/assets/common/items/lantern/red_0.ron new file mode 100644 index 0000000000..24da319e43 --- /dev/null +++ b/assets/common/items/lantern/red_0.ron @@ -0,0 +1,12 @@ +Item( + name: "Red Lantern", + description: "Caution: contents hot", + kind: Lantern( + ( + kind: Red0, + color: (r: 255, g: 127, b: 51), + strength_thousandths: 3500, + flicker_thousandths: 1000, + ), + ), +) diff --git a/assets/voxygen/element/icons/lantern_blue-0.png b/assets/voxygen/element/icons/lantern_blue-0.png new file mode 100644 index 0000000000..160cfd1996 --- /dev/null +++ b/assets/voxygen/element/icons/lantern_blue-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:819bf7f4f33eff3d1f0ca26d4eb5218e5f146aecc3c05199987b83bdd2657008 +size 1248 diff --git a/assets/voxygen/element/icons/lantern_red-0.png b/assets/voxygen/element/icons/lantern_red-0.png new file mode 100644 index 0000000000..95eaf78064 --- /dev/null +++ b/assets/voxygen/element/icons/lantern_red-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45271d0c26b56ac4cf9a0442ef46e0d2047d6f40b3cb1085c953faebde05fc6b +size 1252 diff --git a/assets/voxygen/i18n/en.ron b/assets/voxygen/i18n/en.ron index b846ba0039..866108d34b 100644 --- a/assets/voxygen/i18n/en.ron +++ b/assets/voxygen/i18n/en.ron @@ -316,6 +316,7 @@ Enjoy your stay in the World of Veloren."#, "gameinput.climb": "Climb", "gameinput.climbdown": "Climb Down", "gameinput.wallleap": "Wall Leap", + "gameinput.togglelantern": "Toggle Lantern", "gameinput.mount": "Mount", "gameinput.enter": "Enter", "gameinput.command": "Command", diff --git a/assets/voxygen/item_image_manifest.ron b/assets/voxygen/item_image_manifest.ron index 17e2998392..491f6db100 100644 --- a/assets/voxygen/item_image_manifest.ron +++ b/assets/voxygen/item_image_manifest.ron @@ -56,10 +56,16 @@ ), // Lanterns Lantern(Black0): Png( - "element.icons.lantern_black-0", + "element.icons.lantern_black-0", ), Lantern(Green0): Png( - "element.icons.lantern_green-0", + "element.icons.lantern_green-0", + ), + Lantern(Blue0): Png( + "element.icons.lantern_blue-0", + ), + Lantern(Red0): Png( + "element.icons.lantern_red-0", ), // Farming Equipment Tool(Farming(Broom)): VoxTrans( diff --git a/assets/voxygen/voxel/armor/lantern/blue-0.vox b/assets/voxygen/voxel/armor/lantern/blue-0.vox new file mode 100644 index 0000000000..8012f31a8f --- /dev/null +++ b/assets/voxygen/voxel/armor/lantern/blue-0.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:54692b8a8fe500c7bb352033f06696123924fab78e3cf1e3a08ed610cef36de9 +size 1384 diff --git a/assets/voxygen/voxel/armor/lantern/red-0.vox b/assets/voxygen/voxel/armor/lantern/red-0.vox new file mode 100644 index 0000000000..2cfc2142e7 --- /dev/null +++ b/assets/voxygen/voxel/armor/lantern/red-0.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d168ab7baea56575aa7542305691a932d80ba449079076ef166c2490cd53844 +size 1384 diff --git a/assets/voxygen/voxel/humanoid_lantern_manifest.ron b/assets/voxygen/voxel/humanoid_lantern_manifest.ron index 2ad5c02a5b..09069ef96b 100644 --- a/assets/voxygen/voxel/humanoid_lantern_manifest.ron +++ b/assets/voxygen/voxel/humanoid_lantern_manifest.ron @@ -7,10 +7,18 @@ Green0: ( vox_spec: ("armor.lantern.green-0", (-2.0, -2.0, -7.0)), color: None - ), + ), Black0: ( vox_spec: ("armor.lantern.black-0", (-2.0, -2.0, -7.0)), color: None - ), + ), + Red0: ( + vox_spec: ("armor.lantern.red-0", (-2.0, -2.0, -7.0)), + color: None + ), + Blue0: ( + vox_spec: ("armor.lantern.blue-0", (-2.0, -2.0, -7.0)), + color: None + ), }, )) diff --git a/client/src/lib.rs b/client/src/lib.rs index 1e4aea04b6..5f9b4b594a 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -274,6 +274,11 @@ impl Client { } } + pub fn toggle_lantern(&mut self) { + self.postbox + .send_message(ClientMsg::ControlEvent(ControlEvent::ToggleLantern)); + } + pub fn is_mounted(&self) -> bool { self.state .ecs() diff --git a/common/src/assets/mod.rs b/common/src/assets/mod.rs index 62f255895e..b7a3e63627 100644 --- a/common/src/assets/mod.rs +++ b/common/src/assets/mod.rs @@ -167,7 +167,7 @@ pub fn load_cloned(specifier: &str) -> Result(specifier: &str) -> Arc { load(specifier).unwrap_or_else(|err| { panic!( - "Failed loading essential asset: {} (error={})", + "Failed loading essential asset: {} (error={:?})", specifier, err ) }) diff --git a/common/src/comp/controller.rs b/common/src/comp/controller.rs index 6daf98e1cf..5090f219c1 100644 --- a/common/src/comp/controller.rs +++ b/common/src/comp/controller.rs @@ -18,6 +18,7 @@ pub enum InventoryManip { #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub enum ControlEvent { + ToggleLantern, Mount(Uid), Unmount, InventoryManip(InventoryManip), diff --git a/common/src/comp/inventory/item/mod.rs b/common/src/comp/inventory/item/mod.rs index 294c6e947a..1f223e3ea8 100644 --- a/common/src/comp/inventory/item/mod.rs +++ b/common/src/comp/inventory/item/mod.rs @@ -13,6 +13,7 @@ use rand::seq::SliceRandom; use specs::{Component, FlaggedStorage}; use specs_idvs::IDVStorage; use std::{fs::File, io::BufReader}; +use vek::Rgb; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum Consumable { @@ -39,11 +40,33 @@ pub enum Ingredient { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[repr(u32)] -pub enum Lantern { +pub enum LanternKind { Black0 = 1, Green0 = 2, + Red0 = 3, + Blue0 = 4, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct Lantern { + pub kind: LanternKind, + color: Rgb, + strength_thousandths: u32, + flicker_thousandths: u32, +} + +pub const ALL_LANTERNS: [LanternKind; 4] = [ + LanternKind::Black0, + LanternKind::Green0, + LanternKind::Red0, + LanternKind::Blue0, +]; + +impl Lantern { + pub fn strength(&self) -> f32 { self.strength_thousandths as f32 / 1000_f32 } + + pub fn color(&self) -> Rgb { self.color.map(|c| c as f32 / 255.0) } } -pub const ALL_LANTERNS: [Lantern; 2] = [Lantern::Black0, Lantern::Green0]; fn default_amount() -> u32 { 1 } diff --git a/common/src/comp/inventory/mod.rs b/common/src/comp/inventory/mod.rs index e7e126ed96..66c63636a8 100644 --- a/common/src/comp/inventory/mod.rs +++ b/common/src/comp/inventory/mod.rs @@ -3,6 +3,7 @@ pub mod slot; use crate::assets; use item::{Consumable, Item, ItemKind}; +use rand::{seq::SliceRandom, thread_rng}; use specs::{Component, FlaggedStorage, HashMapStorage}; use specs_idvs::IDVStorage; use std::ops::Not; @@ -304,6 +305,15 @@ impl Default for Inventory { }; inventory.push(assets::load_expect_cloned("common.items.cheese")); inventory.push(assets::load_expect_cloned("common.items.apple")); + let mut rng = thread_rng(); + let starter_lantern = [ + "common.items.lantern.black_0", + "common.items.lantern.red_0", + "common.items.lantern.blue_0", + ] + .choose(&mut rng) + .unwrap(); + inventory.push(assets::load_expect_cloned(starter_lantern)); inventory } } diff --git a/common/src/comp/inventory/test.rs b/common/src/comp/inventory/test.rs index 51498159c2..ae84f71ff5 100644 --- a/common/src/comp/inventory/test.rs +++ b/common/src/comp/inventory/test.rs @@ -6,9 +6,9 @@ lazy_static! { assets::load_expect_cloned("common.items.debug.possess") ]; } -/// The `Default` inventory should contain two items +/// The `Default` inventory should contain 3 items: cheese, apple, lantern #[test] -fn create_default_count() { assert_eq!(Inventory::default().count(), 2) } +fn create_default_count() { assert_eq!(Inventory::default().count(), 3) } /// Attempting to push into a full inventory should return the same item. #[test] diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs index 8e721fed78..2659d08650 100644 --- a/common/src/comp/mod.rs +++ b/common/src/comp/mod.rs @@ -39,4 +39,4 @@ pub use phys::{Collider, ForceUpdate, Gravity, Mass, Ori, PhysicsState, Pos, Sca pub use player::Player; pub use projectile::Projectile; pub use stats::{Exp, HealthChange, HealthSource, Level, Stats}; -pub use visual::LightEmitter; +pub use visual::{LightAnimation, LightEmitter}; diff --git a/common/src/comp/visual.rs b/common/src/comp/visual.rs index e192e0f44d..29cd1efd30 100644 --- a/common/src/comp/visual.rs +++ b/common/src/comp/visual.rs @@ -4,17 +4,19 @@ use vek::*; #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct LightEmitter { - pub offset: Vec3, pub col: Rgb, pub strength: f32, + pub flicker: f32, + pub animated: bool, } impl Default for LightEmitter { fn default() -> Self { Self { - offset: Vec3::zero(), col: Rgb::one(), strength: 1.0, + flicker: 0.0, + animated: false, } } } @@ -22,3 +24,24 @@ impl Default for LightEmitter { impl Component for LightEmitter { type Storage = FlaggedStorage>; } + +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct LightAnimation { + pub offset: Vec3, + pub col: Rgb, + pub strength: f32, +} + +impl Default for LightAnimation { + fn default() -> Self { + Self { + offset: Vec3::zero(), + col: Rgb::zero(), + strength: 0.0, + } + } +} + +impl Component for LightAnimation { + type Storage = FlaggedStorage>; +} diff --git a/common/src/event.rs b/common/src/event.rs index 6721107fd7..924d92ef84 100644 --- a/common/src/event.rs +++ b/common/src/event.rs @@ -86,6 +86,7 @@ pub enum ServerEvent { entity: EcsEntity, vel: Vec3, }, + ToggleLantern(EcsEntity), Mount(EcsEntity, EcsEntity), Unmount(EcsEntity), Possess(Uid, Uid), diff --git a/common/src/state.rs b/common/src/state.rs index 5812399cd7..3e1fb9d8c6 100644 --- a/common/src/state.rs +++ b/common/src/state.rs @@ -135,6 +135,10 @@ impl State { ecs.register::(); ecs.register::(); + // Register client-local components + // TODO: only register on the client + ecs.register::(); + // Register server-local components // TODO: only register on the server ecs.register::>(); diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs index ceb49f9e9c..12c5ed8444 100644 --- a/common/src/sys/controller.rs +++ b/common/src/sys/controller.rs @@ -74,6 +74,9 @@ impl<'a> System<'a> for Sys { } }, ControlEvent::Unmount => server_emitter.emit(ServerEvent::Unmount(entity)), + ControlEvent::ToggleLantern => { + server_emitter.emit(ServerEvent::ToggleLantern(entity)) + }, ControlEvent::InventoryManip(manip) => { *character_state = CharacterState::Idle; server_emitter.emit(ServerEvent::InventoryManip(entity, manip)) diff --git a/server/src/cmd.rs b/server/src/cmd.rs index f8df738d0a..9439c85259 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -202,9 +202,9 @@ lazy_static! { ), ChatCommand::new( "lantern", - "{}", - "/lantern : adds/remove light near player", - false, + "{} {} {} {}", + "/lantern [ ]: Change your lantern's strength and color", + true, handle_lantern, ), ChatCommand::new( @@ -847,6 +847,7 @@ fn handle_light( scan_fmt_some!(&args, action.arg_fmt, f32, f32, f32, f32, f32, f32, f32); let mut light_emitter = comp::LightEmitter::default(); + let mut light_offset_opt = None; if let (Some(r), Some(g), Some(b)) = (opt_r, opt_g, opt_b) { let r = r.max(0.0).min(1.0); @@ -855,7 +856,11 @@ fn handle_light( light_emitter.col = Rgb::new(r, g, b) }; if let (Some(x), Some(y), Some(z)) = (opt_x, opt_y, opt_z) { - light_emitter.offset = Vec3::new(x, y, z) + light_offset_opt = Some(comp::LightAnimation { + offset: Vec3::new(x, y, z), + col: light_emitter.col, + strength: 0.0, + }) }; if let Some(s) = opt_s { light_emitter.strength = s.max(0.0) @@ -867,14 +872,18 @@ fn handle_light( .get(target) .copied(); if let Some(pos) = pos { - server + let builder = server .state .ecs_mut() .create_entity_synced() .with(pos) .with(comp::ForceUpdate) - .with(light_emitter) - .build(); + .with(light_emitter); + if let Some(light_offset) = light_offset_opt { + builder.with(light_offset).build(); + } else { + builder.build(); + } server.notify_client(client, ServerMsg::private(format!("Spawned object."))); } else { server.notify_client(client, ServerMsg::private(format!("You have no position!"))); @@ -888,57 +897,39 @@ fn handle_lantern( args: String, action: &ChatCommand, ) { - let opt_s = scan_fmt_some!(&args, action.arg_fmt, f32); - - if server - .state - .read_storage::() - .get(target) - .is_some() - { - if let Some(s) = opt_s { - if let Some(light) = server - .state - .ecs() - .write_storage::() - .get_mut(target) - { - light.strength = s.max(0.1).min(10.0); + if let (Some(s), r, g, b) = scan_fmt_some!(&args, action.arg_fmt, f32, f32, f32, f32) { + if let Some(light) = server + .state + .ecs() + .write_storage::() + .get_mut(target) + { + light.strength = s.max(0.1).min(10.0); + if let (Some(r), Some(g), Some(b)) = (r, g, b) { + light.col = ( + r.max(0.0).min(1.0), + g.max(0.0).min(1.0), + b.max(0.0).min(1.0), + ) + .into(); + server.notify_client( + client, + ServerMsg::private(String::from("You adjusted flame strength and color.")), + ); + } else { server.notify_client( client, ServerMsg::private(String::from("You adjusted flame strength.")), ); } } else { - server - .state - .ecs() - .write_storage::() - .remove(target); server.notify_client( client, - ServerMsg::private(String::from("You put out the lantern.")), + ServerMsg::private(String::from("Please equip a lantern first")), ); } } else { - let _ = server - .state - .ecs() - .write_storage::() - .insert(target, comp::LightEmitter { - offset: Vec3::new(0.5, 0.2, 0.8), - col: Rgb::new(1.0, 0.75, 0.3), - strength: if let Some(s) = opt_s { - s.max(0.0).min(10.0) - } else { - 3.0 - }, - }); - - server.notify_client( - client, - ServerMsg::private(String::from("You lit your lantern.")), - ); + server.notify_client(client, ServerMsg::private(String::from(action.help_string))); } } diff --git a/server/src/events/entity_creation.rs b/server/src/events/entity_creation.rs index 77987794ab..1c9bf9f821 100644 --- a/server/src/events/entity_creation.rs +++ b/server/src/events/entity_creation.rs @@ -79,9 +79,10 @@ pub fn handle_create_waypoint(server: &mut Server, pos: Vec3) { .state .create_object(Pos(pos), comp::object::Body::CampfireLit) .with(LightEmitter { - offset: Vec3::unit_z() * 0.5, col: Rgb::new(1.0, 0.65, 0.2), strength: 2.0, + flicker: 1.0, + animated: true, }) .with(WaypointArea::default()) .build(); diff --git a/server/src/events/entity_manipulation.rs b/server/src/events/entity_manipulation.rs index 8523af441d..4a8bb74206 100644 --- a/server/src/events/entity_manipulation.rs +++ b/server/src/events/entity_manipulation.rs @@ -86,6 +86,10 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc .insert(entity, comp::ForceUpdate) .err() .map(|err| error!("Failed to insert ForceUpdate on dead client: {:?}", err)); + state + .ecs() + .write_storage::() + .remove(entity); state .ecs() .write_storage::() diff --git a/server/src/events/interaction.rs b/server/src/events/interaction.rs index 9f34e6d8ed..df6cf3ab35 100644 --- a/server/src/events/interaction.rs +++ b/server/src/events/interaction.rs @@ -11,6 +11,43 @@ use common::{ use log::error; use specs::{world::WorldExt, Entity as EcsEntity}; +pub fn handle_lantern(server: &mut Server, entity: EcsEntity) { + let ecs = server.state_mut().ecs(); + if ecs + .read_storage::() + .get(entity) + .map_or(false, |light| light.strength > 0.0) + { + server + .state_mut() + .ecs() + .write_storage::() + .remove(entity); + } else { + let lantern_opt = ecs + .read_storage::() + .get(entity) + .and_then(|loadout| loadout.lantern.as_ref()) + .and_then(|item| { + if let comp::item::ItemKind::Lantern(l) = item.kind { + Some(l) + } else { + None + } + }); + if let Some(lantern) = lantern_opt { + let _ = ecs + .write_storage::() + .insert(entity, comp::LightEmitter { + col: lantern.color(), + strength: lantern.strength(), + flicker: 1.0, + animated: true, + }); + } + } +} + pub fn handle_mount(server: &mut Server, mounter: EcsEntity, mountee: EcsEntity) { let state = server.state_mut(); diff --git a/server/src/events/inventory_manip.rs b/server/src/events/inventory_manip.rs index 2228af5424..0333cff3e9 100644 --- a/server/src/events/inventory_manip.rs +++ b/server/src/events/inventory_manip.rs @@ -11,9 +11,24 @@ use common::{ }; use log::error; use rand::Rng; -use specs::{join::Join, world::WorldExt, Builder, Entity as EcsEntity}; +use specs::{join::Join, world::WorldExt, Builder, Entity as EcsEntity, WriteStorage}; use vek::Vec3; +pub fn swap_lantern( + storage: &mut WriteStorage, + entity: EcsEntity, + lantern: &item::Lantern, +) { + if let Some(light) = storage.get_mut(entity) { + light.strength = lantern.strength(); + light.col = lantern.color(); + } +} + +pub fn snuff_lantern(storage: &mut WriteStorage, entity: EcsEntity) { + storage.remove(entity); +} + pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::InventoryManip) { let state = server.state_mut(); let mut dropped_items = Vec::new(); @@ -101,12 +116,19 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv let event = match slot { Slot::Inventory(slot) => { use item::ItemKind; - // Check if item is equipable - if inventory.get(slot).map_or(false, |i| match &i.kind { - ItemKind::Tool(_) | ItemKind::Armor { .. } | ItemKind::Lantern(_) => true, - _ => false, - }) { + let (is_equippable, lantern_opt) = + inventory + .get(slot) + .map_or((false, None), |i| match &i.kind { + ItemKind::Tool(_) | ItemKind::Armor { .. } => (true, None), + ItemKind::Lantern(lantern) => (true, Some(lantern)), + _ => (false, None), + }); + if is_equippable { if let Some(loadout) = state.ecs().write_storage().get_mut(entity) { + if let Some(lantern) = lantern_opt { + swap_lantern(&mut state.ecs().write_storage(), entity, lantern); + } slot::equip(slot, inventory, loadout); Some(comp::InventoryUpdateEvent::Used) } else { @@ -191,6 +213,9 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv }, Slot::Equip(slot) => { if let Some(loadout) = state.ecs().write_storage().get_mut(entity) { + if slot == slot::EquipSlot::Lantern { + snuff_lantern(&mut state.ecs().write_storage(), entity); + } slot::unequip(slot, inventory, loadout); Some(comp::InventoryUpdateEvent::Used) } else { diff --git a/server/src/events/mod.rs b/server/src/events/mod.rs index 22607c185a..1f9ab9ff0e 100644 --- a/server/src/events/mod.rs +++ b/server/src/events/mod.rs @@ -6,7 +6,7 @@ use entity_creation::{ use entity_manipulation::{ handle_damage, handle_destroy, handle_explosion, handle_land_on_ground, handle_respawn, }; -use interaction::{handle_mount, handle_possess, handle_unmount}; +use interaction::{handle_lantern, handle_mount, handle_possess, handle_unmount}; use inventory_manip::handle_inventory; use player::{handle_client_disconnect, handle_exit_ingame}; use specs::{Entity as EcsEntity, WorldExt}; @@ -63,6 +63,7 @@ impl Server { ServerEvent::LandOnGround { entity, vel } => { handle_land_on_ground(&self, entity, vel) }, + ServerEvent::ToggleLantern(entity) => handle_lantern(self, entity), ServerEvent::Mount(mounter, mountee) => handle_mount(self, mounter, mountee), ServerEvent::Unmount(mounter) => handle_unmount(self, mounter), ServerEvent::Possess(possessor_uid, possesse_uid) => { diff --git a/server/src/state_ext.rs b/server/src/state_ext.rs index 519fdcb44b..744248ce9a 100644 --- a/server/src/state_ext.rs +++ b/server/src/state_ext.rs @@ -127,7 +127,6 @@ impl StateExt for State { z_max: 0.9, }) .with(comp::Gravity(1.0)) - //.with(comp::LightEmitter::default()) } /// Build a projectile diff --git a/voxygen/src/anim/biped_large/mod.rs b/voxygen/src/anim/biped_large/mod.rs index c7b2888e83..5ff549c924 100644 --- a/voxygen/src/anim/biped_large/mod.rs +++ b/voxygen/src/anim/biped_large/mod.rs @@ -8,6 +8,7 @@ pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation}; use super::{Bone, Skeleton}; use crate::render::FigureBoneData; use common::comp::{self}; +use vek::Vec3; #[derive(Clone)] pub struct BipedLargeSkeleton { @@ -49,7 +50,7 @@ impl Skeleton for BipedLargeSkeleton { fn bone_count(&self) -> usize { 11 } - fn compute_matrices(&self) -> [FigureBoneData; 16] { + fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3) { let upper_torso_mat = self.upper_torso.compute_base_matrix(); let shoulder_l_mat = self.shoulder_l.compute_base_matrix(); let shoulder_r_mat = self.shoulder_r.compute_base_matrix(); @@ -57,26 +58,33 @@ impl Skeleton for BipedLargeSkeleton { let leg_r_mat = self.leg_r.compute_base_matrix(); let torso_mat = self.torso.compute_base_matrix(); - [ - FigureBoneData::new(torso_mat * upper_torso_mat * self.head.compute_base_matrix()), - FigureBoneData::new(torso_mat * upper_torso_mat), - FigureBoneData::new( - torso_mat * upper_torso_mat * self.lower_torso.compute_base_matrix(), - ), - FigureBoneData::new(torso_mat * upper_torso_mat * shoulder_l_mat), - FigureBoneData::new(torso_mat * upper_torso_mat * shoulder_r_mat), - FigureBoneData::new(torso_mat * upper_torso_mat * self.hand_l.compute_base_matrix()), - FigureBoneData::new(torso_mat * upper_torso_mat * self.hand_r.compute_base_matrix()), - FigureBoneData::new(torso_mat * upper_torso_mat * leg_l_mat), - FigureBoneData::new(torso_mat * upper_torso_mat * leg_r_mat), - FigureBoneData::new(self.foot_l.compute_base_matrix()), - FigureBoneData::new(self.foot_r.compute_base_matrix()), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - ] + ( + [ + FigureBoneData::new(torso_mat * upper_torso_mat * self.head.compute_base_matrix()), + FigureBoneData::new(torso_mat * upper_torso_mat), + FigureBoneData::new( + torso_mat * upper_torso_mat * self.lower_torso.compute_base_matrix(), + ), + FigureBoneData::new(torso_mat * upper_torso_mat * shoulder_l_mat), + FigureBoneData::new(torso_mat * upper_torso_mat * shoulder_r_mat), + FigureBoneData::new( + torso_mat * upper_torso_mat * self.hand_l.compute_base_matrix(), + ), + FigureBoneData::new( + torso_mat * upper_torso_mat * self.hand_r.compute_base_matrix(), + ), + FigureBoneData::new(torso_mat * upper_torso_mat * leg_l_mat), + FigureBoneData::new(torso_mat * upper_torso_mat * leg_r_mat), + FigureBoneData::new(self.foot_l.compute_base_matrix()), + FigureBoneData::new(self.foot_r.compute_base_matrix()), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + ], + Vec3::default(), + ) } fn interpolate(&mut self, target: &Self, dt: f32) { diff --git a/voxygen/src/anim/bird_medium/mod.rs b/voxygen/src/anim/bird_medium/mod.rs index d5fab6015e..576dd70c8f 100644 --- a/voxygen/src/anim/bird_medium/mod.rs +++ b/voxygen/src/anim/bird_medium/mod.rs @@ -8,6 +8,7 @@ pub use self::{fly::FlyAnimation, idle::IdleAnimation, run::RunAnimation}; use super::{Bone, Skeleton}; use crate::render::FigureBoneData; use common::comp::{self}; +use vek::Vec3; #[derive(Clone, Default)] pub struct BirdMediumSkeleton { @@ -29,27 +30,30 @@ impl Skeleton for BirdMediumSkeleton { fn bone_count(&self) -> usize { 7 } - fn compute_matrices(&self) -> [FigureBoneData; 16] { + fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3) { let torso_mat = self.torso.compute_base_matrix(); - [ - FigureBoneData::new(torso_mat * self.head.compute_base_matrix()), - FigureBoneData::new(torso_mat), - FigureBoneData::new(torso_mat * self.tail.compute_base_matrix()), - FigureBoneData::new(torso_mat * self.wing_l.compute_base_matrix()), - FigureBoneData::new(torso_mat * self.wing_r.compute_base_matrix()), - FigureBoneData::new(self.leg_l.compute_base_matrix()), - FigureBoneData::new(self.leg_r.compute_base_matrix()), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - ] + ( + [ + FigureBoneData::new(torso_mat * self.head.compute_base_matrix()), + FigureBoneData::new(torso_mat), + FigureBoneData::new(torso_mat * self.tail.compute_base_matrix()), + FigureBoneData::new(torso_mat * self.wing_l.compute_base_matrix()), + FigureBoneData::new(torso_mat * self.wing_r.compute_base_matrix()), + FigureBoneData::new(self.leg_l.compute_base_matrix()), + FigureBoneData::new(self.leg_r.compute_base_matrix()), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + ], + Vec3::default(), + ) } fn interpolate(&mut self, target: &Self, dt: f32) { diff --git a/voxygen/src/anim/bird_small/mod.rs b/voxygen/src/anim/bird_small/mod.rs index de36727d8d..2bbf379cb2 100644 --- a/voxygen/src/anim/bird_small/mod.rs +++ b/voxygen/src/anim/bird_small/mod.rs @@ -8,6 +8,7 @@ pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation}; use super::{Bone, Skeleton}; use crate::render::FigureBoneData; use common::comp::{self}; +use vek::Vec3; #[derive(Clone)] pub struct BirdSmallSkeleton { @@ -33,27 +34,30 @@ impl Skeleton for BirdSmallSkeleton { fn bone_count(&self) -> usize { 4 } - fn compute_matrices(&self) -> [FigureBoneData; 16] { + fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3) { let torso_mat = self.torso.compute_base_matrix(); - [ - FigureBoneData::new(self.head.compute_base_matrix() * torso_mat), - FigureBoneData::new(torso_mat), - FigureBoneData::new(self.wing_l.compute_base_matrix() * torso_mat), - FigureBoneData::new(self.wing_r.compute_base_matrix() * torso_mat), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - ] + ( + [ + FigureBoneData::new(self.head.compute_base_matrix() * torso_mat), + FigureBoneData::new(torso_mat), + FigureBoneData::new(self.wing_l.compute_base_matrix() * torso_mat), + FigureBoneData::new(self.wing_r.compute_base_matrix() * torso_mat), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + ], + Vec3::default(), + ) } fn interpolate(&mut self, target: &Self, dt: f32) { diff --git a/voxygen/src/anim/character/mod.rs b/voxygen/src/anim/character/mod.rs index a3ff928ea7..5a9bff96af 100644 --- a/voxygen/src/anim/character/mod.rs +++ b/voxygen/src/anim/character/mod.rs @@ -31,6 +31,7 @@ pub use self::{ use super::{Bone, Skeleton}; use crate::render::FigureBoneData; use common::comp; +use vek::{Vec3, Vec4}; #[derive(Clone, Default)] pub struct CharacterSkeleton { @@ -64,7 +65,7 @@ impl Skeleton for CharacterSkeleton { fn bone_count(&self) -> usize { 15 } - fn compute_matrices(&self) -> [FigureBoneData; 16] { + fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3) { let chest_mat = self.chest.compute_base_matrix(); let torso_mat = self.torso.compute_base_matrix(); let l_hand_mat = self.l_hand.compute_base_matrix(); @@ -76,26 +77,37 @@ impl Skeleton for CharacterSkeleton { let second_mat = self.second.compute_base_matrix(); let shorts_mat = self.shorts.compute_base_matrix(); let head_mat = self.head.compute_base_matrix(); - [ - FigureBoneData::new(torso_mat * chest_mat * head_mat), - FigureBoneData::new(torso_mat * chest_mat), - FigureBoneData::new(torso_mat * chest_mat * self.belt.compute_base_matrix()), - FigureBoneData::new(torso_mat * chest_mat * self.back.compute_base_matrix()), - FigureBoneData::new(torso_mat * chest_mat * shorts_mat), - FigureBoneData::new(torso_mat * chest_mat * control_mat * l_control_mat * l_hand_mat), - FigureBoneData::new(torso_mat * chest_mat * control_mat * r_control_mat * r_hand_mat), - FigureBoneData::new(torso_mat * self.l_foot.compute_base_matrix()), - FigureBoneData::new(torso_mat * self.r_foot.compute_base_matrix()), - FigureBoneData::new(torso_mat * chest_mat * self.l_shoulder.compute_base_matrix()), - FigureBoneData::new(torso_mat * chest_mat * self.r_shoulder.compute_base_matrix()), - FigureBoneData::new(torso_mat * self.glider.compute_base_matrix()), - FigureBoneData::new(torso_mat * chest_mat * control_mat * l_control_mat * main_mat), - FigureBoneData::new(torso_mat * chest_mat * control_mat * r_control_mat * second_mat), - FigureBoneData::new( - torso_mat * chest_mat * shorts_mat * self.lantern.compute_base_matrix(), - ), - FigureBoneData::default(), - ] + + let lantern_final_mat = + torso_mat * chest_mat * shorts_mat * self.lantern.compute_base_matrix(); + + ( + [ + FigureBoneData::new(torso_mat * chest_mat * head_mat), + FigureBoneData::new(torso_mat * chest_mat), + FigureBoneData::new(torso_mat * chest_mat * self.belt.compute_base_matrix()), + FigureBoneData::new(torso_mat * chest_mat * self.back.compute_base_matrix()), + FigureBoneData::new(torso_mat * chest_mat * shorts_mat), + FigureBoneData::new( + torso_mat * chest_mat * control_mat * l_control_mat * l_hand_mat, + ), + FigureBoneData::new( + torso_mat * chest_mat * control_mat * r_control_mat * r_hand_mat, + ), + FigureBoneData::new(torso_mat * self.l_foot.compute_base_matrix()), + FigureBoneData::new(torso_mat * self.r_foot.compute_base_matrix()), + FigureBoneData::new(torso_mat * chest_mat * self.l_shoulder.compute_base_matrix()), + FigureBoneData::new(torso_mat * chest_mat * self.r_shoulder.compute_base_matrix()), + FigureBoneData::new(torso_mat * self.glider.compute_base_matrix()), + FigureBoneData::new(torso_mat * chest_mat * control_mat * l_control_mat * main_mat), + FigureBoneData::new( + torso_mat * chest_mat * control_mat * r_control_mat * second_mat, + ), + FigureBoneData::new(lantern_final_mat), + FigureBoneData::default(), + ], + (lantern_final_mat * Vec4::new(0.0, 0.0, 0.0, 1.0)).xyz(), + ) } fn interpolate(&mut self, target: &Self, dt: f32) { diff --git a/voxygen/src/anim/critter/mod.rs b/voxygen/src/anim/critter/mod.rs index bce32cf380..56d40c2cd2 100644 --- a/voxygen/src/anim/critter/mod.rs +++ b/voxygen/src/anim/critter/mod.rs @@ -8,6 +8,7 @@ pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation}; use super::{Bone, Skeleton}; use crate::render::FigureBoneData; use common::comp::{self}; +use vek::Vec3; #[derive(Clone, Default)] pub struct CritterSkeleton { @@ -34,25 +35,28 @@ impl Skeleton for CritterSkeleton { fn bone_count(&self) -> usize { 5 } - fn compute_matrices(&self) -> [FigureBoneData; 16] { - [ - FigureBoneData::new(self.head.compute_base_matrix()), - FigureBoneData::new(self.chest.compute_base_matrix()), - FigureBoneData::new(self.feet_f.compute_base_matrix()), - FigureBoneData::new(self.feet_b.compute_base_matrix()), - FigureBoneData::new(self.tail.compute_base_matrix()), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - ] + fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3) { + ( + [ + FigureBoneData::new(self.head.compute_base_matrix()), + FigureBoneData::new(self.chest.compute_base_matrix()), + FigureBoneData::new(self.feet_f.compute_base_matrix()), + FigureBoneData::new(self.feet_b.compute_base_matrix()), + FigureBoneData::new(self.tail.compute_base_matrix()), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + ], + Vec3::default(), + ) } fn interpolate(&mut self, target: &Self, dt: f32) { diff --git a/voxygen/src/anim/dragon/mod.rs b/voxygen/src/anim/dragon/mod.rs index 86bd013b9b..67cf9c5317 100644 --- a/voxygen/src/anim/dragon/mod.rs +++ b/voxygen/src/anim/dragon/mod.rs @@ -8,6 +8,7 @@ pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation}; use super::{Bone, Skeleton}; use crate::render::FigureBoneData; use common::comp::{self}; +use vek::Vec3; #[derive(Clone)] pub struct DragonSkeleton { @@ -51,30 +52,33 @@ impl Skeleton for DragonSkeleton { fn bone_count(&self) -> usize { 13 } - fn compute_matrices(&self) -> [FigureBoneData; 16] { + fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3) { let chest_front_mat = self.chest_front.compute_base_matrix(); let wing_in_l_mat = self.wing_in_l.compute_base_matrix(); let wing_in_r_mat = self.wing_in_r.compute_base_matrix(); let tail_front_mat = self.tail_front.compute_base_matrix(); - [ - FigureBoneData::new(self.head.compute_base_matrix() * chest_front_mat), - FigureBoneData::new(chest_front_mat), - FigureBoneData::new(self.chest_rear.compute_base_matrix() * chest_front_mat), - FigureBoneData::new(tail_front_mat), - FigureBoneData::new(self.tail_rear.compute_base_matrix() * tail_front_mat), - FigureBoneData::new(wing_in_l_mat), - FigureBoneData::new(wing_in_r_mat), - FigureBoneData::new(self.wing_out_l.compute_base_matrix() * wing_in_l_mat), - FigureBoneData::new(self.wing_out_r.compute_base_matrix() * wing_in_r_mat), - FigureBoneData::new(self.foot_fl.compute_base_matrix()), - FigureBoneData::new(self.foot_fr.compute_base_matrix()), - FigureBoneData::new(self.foot_bl.compute_base_matrix()), - FigureBoneData::new(self.foot_br.compute_base_matrix()), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - ] + ( + [ + FigureBoneData::new(self.head.compute_base_matrix() * chest_front_mat), + FigureBoneData::new(chest_front_mat), + FigureBoneData::new(self.chest_rear.compute_base_matrix() * chest_front_mat), + FigureBoneData::new(tail_front_mat), + FigureBoneData::new(self.tail_rear.compute_base_matrix() * tail_front_mat), + FigureBoneData::new(wing_in_l_mat), + FigureBoneData::new(wing_in_r_mat), + FigureBoneData::new(self.wing_out_l.compute_base_matrix() * wing_in_l_mat), + FigureBoneData::new(self.wing_out_r.compute_base_matrix() * wing_in_r_mat), + FigureBoneData::new(self.foot_fl.compute_base_matrix()), + FigureBoneData::new(self.foot_fr.compute_base_matrix()), + FigureBoneData::new(self.foot_bl.compute_base_matrix()), + FigureBoneData::new(self.foot_br.compute_base_matrix()), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + ], + Vec3::default(), + ) } fn interpolate(&mut self, target: &Self, dt: f32) { diff --git a/voxygen/src/anim/fish_medium/mod.rs b/voxygen/src/anim/fish_medium/mod.rs index f7f8519a2a..8853f40f57 100644 --- a/voxygen/src/anim/fish_medium/mod.rs +++ b/voxygen/src/anim/fish_medium/mod.rs @@ -8,6 +8,7 @@ pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation}; use super::{Bone, Skeleton}; use crate::render::FigureBoneData; use common::comp::{self}; +use vek::Vec3; #[derive(Clone)] pub struct FishMediumSkeleton { @@ -37,28 +38,31 @@ impl Skeleton for FishMediumSkeleton { fn bone_count(&self) -> usize { 6 } - fn compute_matrices(&self) -> [FigureBoneData; 16] { + fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3) { let torso_mat = self.torso.compute_base_matrix(); let rear_mat = self.rear.compute_base_matrix(); - [ - FigureBoneData::new(self.head.compute_base_matrix() * torso_mat), - FigureBoneData::new(torso_mat), - FigureBoneData::new(rear_mat * torso_mat), - FigureBoneData::new(self.tail.compute_base_matrix() * rear_mat), - FigureBoneData::new(self.fin_l.compute_base_matrix() * rear_mat), - FigureBoneData::new(self.fin_r.compute_base_matrix() * rear_mat), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - ] + ( + [ + FigureBoneData::new(self.head.compute_base_matrix() * torso_mat), + FigureBoneData::new(torso_mat), + FigureBoneData::new(rear_mat * torso_mat), + FigureBoneData::new(self.tail.compute_base_matrix() * rear_mat), + FigureBoneData::new(self.fin_l.compute_base_matrix() * rear_mat), + FigureBoneData::new(self.fin_r.compute_base_matrix() * rear_mat), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + ], + Vec3::default(), + ) } fn interpolate(&mut self, target: &Self, dt: f32) { diff --git a/voxygen/src/anim/fish_small/mod.rs b/voxygen/src/anim/fish_small/mod.rs index 1b3618b892..0912647f5c 100644 --- a/voxygen/src/anim/fish_small/mod.rs +++ b/voxygen/src/anim/fish_small/mod.rs @@ -8,6 +8,7 @@ pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation}; use super::{Bone, Skeleton}; use crate::render::FigureBoneData; use common::comp::{self}; +use vek::Vec3; #[derive(Clone)] pub struct FishSmallSkeleton { @@ -29,27 +30,30 @@ impl Skeleton for FishSmallSkeleton { fn bone_count(&self) -> usize { 2 } - fn compute_matrices(&self) -> [FigureBoneData; 16] { + fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3) { let torso_mat = self.torso.compute_base_matrix(); - [ - FigureBoneData::new(torso_mat), - FigureBoneData::new(self.tail.compute_base_matrix() * torso_mat), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - ] + ( + [ + FigureBoneData::new(torso_mat), + FigureBoneData::new(self.tail.compute_base_matrix() * torso_mat), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + ], + Vec3::default(), + ) } fn interpolate(&mut self, target: &Self, dt: f32) { diff --git a/voxygen/src/anim/fixture/mod.rs b/voxygen/src/anim/fixture/mod.rs index b3426286df..ae34c70e01 100644 --- a/voxygen/src/anim/fixture/mod.rs +++ b/voxygen/src/anim/fixture/mod.rs @@ -1,5 +1,6 @@ use super::Skeleton; use crate::render::FigureBoneData; +use vek::Vec3; #[derive(Clone)] pub struct FixtureSkeleton; @@ -15,25 +16,28 @@ impl Skeleton for FixtureSkeleton { fn bone_count(&self) -> usize { 1 } - fn compute_matrices(&self) -> [FigureBoneData; 16] { - [ - FigureBoneData::new(vek::Mat4::identity()), // <-- This is actually a bone! - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - ] + fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3) { + ( + [ + FigureBoneData::new(vek::Mat4::identity()), // <-- This is actually a bone! + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + ], + Vec3::default(), + ) } fn interpolate(&mut self, _target: &Self, _dt: f32) {} diff --git a/voxygen/src/anim/golem/mod.rs b/voxygen/src/anim/golem/mod.rs index e493186a11..fceda8c230 100644 --- a/voxygen/src/anim/golem/mod.rs +++ b/voxygen/src/anim/golem/mod.rs @@ -8,6 +8,7 @@ pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation}; use super::{Bone, Skeleton}; use crate::render::FigureBoneData; use common::comp::{self}; +use vek::Vec3; #[derive(Clone)] pub struct GolemSkeleton { @@ -45,7 +46,7 @@ impl GolemSkeleton { impl Skeleton for GolemSkeleton { type Attr = SkeletonAttr; - fn compute_matrices(&self) -> [FigureBoneData; 16] { + fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3) { let upper_torso_mat = self.upper_torso.compute_base_matrix(); let shoulder_l_mat = self.shoulder_l.compute_base_matrix(); let shoulder_r_mat = self.shoulder_r.compute_base_matrix(); @@ -54,24 +55,31 @@ impl Skeleton for GolemSkeleton { let torso_mat = self.torso.compute_base_matrix(); let foot_l_mat = self.foot_l.compute_base_matrix(); let foot_r_mat = self.foot_r.compute_base_matrix(); - [ - FigureBoneData::new(torso_mat * upper_torso_mat * self.head.compute_base_matrix()), - FigureBoneData::new(torso_mat * upper_torso_mat), - FigureBoneData::new(torso_mat * upper_torso_mat * shoulder_l_mat), - FigureBoneData::new(torso_mat * upper_torso_mat * shoulder_r_mat), - FigureBoneData::new(torso_mat * upper_torso_mat * self.hand_l.compute_base_matrix()), - FigureBoneData::new(torso_mat * upper_torso_mat * self.hand_r.compute_base_matrix()), - FigureBoneData::new(foot_l_mat * leg_l_mat), - FigureBoneData::new(foot_r_mat * leg_r_mat), - FigureBoneData::new(foot_l_mat), - FigureBoneData::new(foot_r_mat), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - ] + ( + [ + FigureBoneData::new(torso_mat * upper_torso_mat * self.head.compute_base_matrix()), + FigureBoneData::new(torso_mat * upper_torso_mat), + FigureBoneData::new(torso_mat * upper_torso_mat * shoulder_l_mat), + FigureBoneData::new(torso_mat * upper_torso_mat * shoulder_r_mat), + FigureBoneData::new( + torso_mat * upper_torso_mat * self.hand_l.compute_base_matrix(), + ), + FigureBoneData::new( + torso_mat * upper_torso_mat * self.hand_r.compute_base_matrix(), + ), + FigureBoneData::new(foot_l_mat * leg_l_mat), + FigureBoneData::new(foot_r_mat * leg_r_mat), + FigureBoneData::new(foot_l_mat), + FigureBoneData::new(foot_r_mat), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + ], + Vec3::default(), + ) } fn interpolate(&mut self, target: &Self, dt: f32) { diff --git a/voxygen/src/anim/mod.rs b/voxygen/src/anim/mod.rs index b5f3484e4b..3682db6374 100644 --- a/voxygen/src/anim/mod.rs +++ b/voxygen/src/anim/mod.rs @@ -54,7 +54,7 @@ pub trait Skeleton: Send + Sync + 'static { fn bone_count(&self) -> usize { 16 } - fn compute_matrices(&self) -> [FigureBoneData; 16]; + fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3); /// Change the current skeleton to be more like `target`. fn interpolate(&mut self, target: &Self, dt: f32); diff --git a/voxygen/src/anim/object/mod.rs b/voxygen/src/anim/object/mod.rs index 1b552d0485..71dff4052d 100644 --- a/voxygen/src/anim/object/mod.rs +++ b/voxygen/src/anim/object/mod.rs @@ -17,25 +17,28 @@ impl Skeleton for ObjectSkeleton { fn bone_count(&self) -> usize { 1 } - fn compute_matrices(&self) -> [FigureBoneData; 16] { - [ - FigureBoneData::new(Mat4::scaling_3d(Vec3::broadcast(SCALE))), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - FigureBoneData::new(vek::Mat4::identity()), - ] + fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3) { + ( + [ + FigureBoneData::new(Mat4::scaling_3d(Vec3::broadcast(SCALE))), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + FigureBoneData::new(vek::Mat4::identity()), + ], + Vec3::default(), + ) } fn interpolate(&mut self, _target: &Self, _dt: f32) {} diff --git a/voxygen/src/anim/quadruped_medium/mod.rs b/voxygen/src/anim/quadruped_medium/mod.rs index a23e8f1793..aca8b0990d 100644 --- a/voxygen/src/anim/quadruped_medium/mod.rs +++ b/voxygen/src/anim/quadruped_medium/mod.rs @@ -8,6 +8,7 @@ pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation}; use super::{Bone, Skeleton}; use crate::render::FigureBoneData; use common::comp::{self}; +use vek::Vec3; #[derive(Clone, Default)] pub struct QuadrupedMediumSkeleton { @@ -33,29 +34,32 @@ impl Skeleton for QuadrupedMediumSkeleton { fn bone_count(&self) -> usize { 11 } - fn compute_matrices(&self) -> [FigureBoneData; 16] { + fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3) { let ears_mat = self.ears.compute_base_matrix(); let head_upper_mat = self.head_upper.compute_base_matrix(); let head_lower_mat = self.head_lower.compute_base_matrix(); let torso_mid_mat = self.torso_mid.compute_base_matrix(); - [ - FigureBoneData::new(head_upper_mat), - FigureBoneData::new(head_upper_mat * head_lower_mat), - FigureBoneData::new(head_upper_mat * self.jaw.compute_base_matrix()), - FigureBoneData::new(torso_mid_mat * self.tail.compute_base_matrix()), - FigureBoneData::new(self.torso_back.compute_base_matrix()), - FigureBoneData::new(torso_mid_mat), - FigureBoneData::new(head_upper_mat * ears_mat), - FigureBoneData::new(self.foot_lf.compute_base_matrix()), - FigureBoneData::new(self.foot_rf.compute_base_matrix()), - FigureBoneData::new(self.foot_lb.compute_base_matrix()), - FigureBoneData::new(self.foot_rb.compute_base_matrix()), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - ] + ( + [ + FigureBoneData::new(head_upper_mat), + FigureBoneData::new(head_upper_mat * head_lower_mat), + FigureBoneData::new(head_upper_mat * self.jaw.compute_base_matrix()), + FigureBoneData::new(torso_mid_mat * self.tail.compute_base_matrix()), + FigureBoneData::new(self.torso_back.compute_base_matrix()), + FigureBoneData::new(torso_mid_mat), + FigureBoneData::new(head_upper_mat * ears_mat), + FigureBoneData::new(self.foot_lf.compute_base_matrix()), + FigureBoneData::new(self.foot_rf.compute_base_matrix()), + FigureBoneData::new(self.foot_lb.compute_base_matrix()), + FigureBoneData::new(self.foot_rb.compute_base_matrix()), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + ], + Vec3::default(), + ) } fn interpolate(&mut self, target: &Self, dt: f32) { diff --git a/voxygen/src/anim/quadruped_small/mod.rs b/voxygen/src/anim/quadruped_small/mod.rs index 3e17cce90c..7b2770c077 100644 --- a/voxygen/src/anim/quadruped_small/mod.rs +++ b/voxygen/src/anim/quadruped_small/mod.rs @@ -8,6 +8,7 @@ pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation}; use super::{Bone, Skeleton}; use crate::render::FigureBoneData; use common::comp::{self}; +use vek::Vec3; #[derive(Clone, Default)] pub struct QuadrupedSmallSkeleton { @@ -28,25 +29,28 @@ impl Skeleton for QuadrupedSmallSkeleton { fn bone_count(&self) -> usize { 6 } - fn compute_matrices(&self) -> [FigureBoneData; 16] { - [ - FigureBoneData::new(self.head.compute_base_matrix()), - FigureBoneData::new(self.chest.compute_base_matrix()), - FigureBoneData::new(self.leg_lf.compute_base_matrix()), - FigureBoneData::new(self.leg_rf.compute_base_matrix()), - FigureBoneData::new(self.leg_lb.compute_base_matrix()), - FigureBoneData::new(self.leg_rb.compute_base_matrix()), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - FigureBoneData::default(), - ] + fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3) { + ( + [ + FigureBoneData::new(self.head.compute_base_matrix()), + FigureBoneData::new(self.chest.compute_base_matrix()), + FigureBoneData::new(self.leg_lf.compute_base_matrix()), + FigureBoneData::new(self.leg_rf.compute_base_matrix()), + FigureBoneData::new(self.leg_lb.compute_base_matrix()), + FigureBoneData::new(self.leg_rb.compute_base_matrix()), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + ], + Vec3::default(), + ) } fn interpolate(&mut self, target: &Self, dt: f32) { diff --git a/voxygen/src/controller.rs b/voxygen/src/controller.rs index a0a47836c3..42f60cb3e3 100644 --- a/voxygen/src/controller.rs +++ b/voxygen/src/controller.rs @@ -106,6 +106,9 @@ impl From<&crate::settings::GamepadSettings> for ControllerSettings { /*map.entry(settings.game_buttons.wall_leap) .or_default() .push(GameInput::WallLeap);*/ + map.entry(settings.game_buttons.toggle_lantern) + .or_default() + .push(GameInput::ToggleLantern); map.entry(settings.game_buttons.mount) .or_default() .push(GameInput::Mount); diff --git a/voxygen/src/hud/item_imgs.rs b/voxygen/src/hud/item_imgs.rs index 3c76f58087..eb75d086d3 100644 --- a/voxygen/src/hud/item_imgs.rs +++ b/voxygen/src/hud/item_imgs.rs @@ -4,7 +4,7 @@ use common::{ comp::item::{ armor::Armor, tool::{Tool, ToolKind}, - Consumable, Ingredient, Item, ItemKind, Lantern, Utility, + Consumable, Ingredient, Item, ItemKind, Lantern, LanternKind, Utility, }, figure::Segment, }; @@ -20,7 +20,7 @@ use vek::*; #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum ItemKey { Tool(ToolKind), - Lantern(Lantern), + Lantern(LanternKind), Armor(Armor), Utility(Utility), Consumable(Consumable), @@ -31,7 +31,7 @@ impl From<&Item> for ItemKey { fn from(item: &Item) -> Self { match &item.kind { ItemKind::Tool(Tool { kind, .. }) => ItemKey::Tool(kind.clone()), - ItemKind::Lantern(kind) => ItemKey::Lantern(kind.clone()), + ItemKind::Lantern(Lantern { kind, .. }) => ItemKey::Lantern(kind.clone()), ItemKind::Armor { kind, .. } => ItemKey::Armor(kind.clone()), ItemKind::Utility { kind, .. } => ItemKey::Utility(kind.clone()), ItemKind::Consumable { kind, .. } => ItemKey::Consumable(kind.clone()), diff --git a/voxygen/src/scene/figure/load.rs b/voxygen/src/scene/figure/load.rs index c3a223cf6d..17876a8dfb 100644 --- a/voxygen/src/scene/figure/load.rs +++ b/voxygen/src/scene/figure/load.rs @@ -12,7 +12,7 @@ use common::{ item::{ armor::{Armor, Back, Belt, Chest, Foot, Hand, Head, Pants, Shoulder, Tabard}, tool::{Tool, ToolKind}, - ItemKind, Lantern, + ItemKind, Lantern, LanternKind, }, object, quadruped_medium::{BodyType as QMBodyType, Species as QMSpecies}, @@ -259,7 +259,7 @@ pub struct HumArmorFootSpec(ArmorVoxSpecMap); #[derive(Serialize, Deserialize)] pub struct HumMainWeaponSpec(HashMap); #[derive(Serialize, Deserialize)] -pub struct HumArmorLanternSpec(ArmorVoxSpecMap); +pub struct HumArmorLanternSpec(ArmorVoxSpecMap); #[derive(Serialize, Deserialize)] pub struct HumArmorHeadSpec(ArmorVoxSpecMap); #[derive(Serialize, Deserialize)] @@ -810,18 +810,19 @@ impl HumArmorLanternSpec { loadout: &Loadout, generate_mesh: impl FnOnce(&Segment, Vec3) -> Mesh, ) -> Mesh { - let spec = - if let Some(ItemKind::Lantern(lantern)) = loadout.lantern.as_ref().map(|i| &i.kind) { - match self.0.map.get(&lantern) { - Some(spec) => spec, - None => { - error!("No lantern specification exists for {:?}", lantern); - return load_mesh("not_found", Vec3::new(-4.0, -3.5, 2.0), generate_mesh); - }, - } - } else { - &self.0.default - }; + let spec = if let Some(ItemKind::Lantern(Lantern { kind, .. })) = + loadout.lantern.as_ref().map(|i| &i.kind) + { + match self.0.map.get(&kind) { + Some(spec) => spec, + None => { + error!("No lantern specification exists for {:?}", kind); + return load_mesh("not_found", Vec3::new(-4.0, -3.5, 2.0), generate_mesh); + }, + } + } else { + &self.0.default + }; let mut lantern_segment = color_segment( graceful_load_mat_segment(&spec.vox_spec.0), diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index 26f8d5ab90..b38e202b6d 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -21,10 +21,10 @@ use crate::{ }; use common::{ comp::{ - item::ItemKind, Body, CharacterState, Last, Loadout, Ori, PhysicsState, Pos, Scale, Stats, - Vel, + item::ItemKind, Body, CharacterState, Last, LightAnimation, LightEmitter, Loadout, Ori, + PhysicsState, Pos, Scale, Stats, Vel, }, - state::State, + state::{DeltaTime, State}, states::triple_strike, terrain::TerrainChunk, vol::RectRasterableVol, @@ -108,6 +108,61 @@ impl FigureMgr { self.golem_model_cache.clean(tick); } + pub fn update_lighting(&mut self, scene_data: &SceneData) { + let ecs = scene_data.state.ecs(); + for (entity, light_emitter) in (&ecs.entities(), &ecs.read_storage::()).join() + { + // Add LightAnimation for objects with a LightEmitter + let mut anim_storage = ecs.write_storage::(); + if let None = anim_storage.get_mut(entity) { + let anim = LightAnimation { + offset: Vec3::zero(), + col: light_emitter.col, + strength: 0.0, + }; + let _ = anim_storage.insert(entity, anim); + } + } + let dt = ecs.fetch::().0; + for (entity, waypoint, light_emitter_opt, light_anim) in ( + &ecs.entities(), + ecs.read_storage::().maybe(), + ecs.read_storage::().maybe(), + &mut ecs.write_storage::(), + ) + .join() + { + let (target_col, target_strength, flicker, animated) = + if let Some(emitter) = light_emitter_opt { + ( + emitter.col, + emitter.strength, + emitter.flicker, + emitter.animated, + ) + } else { + (Rgb::zero(), 0.0, 0.0, true) + }; + if let Some(_) = waypoint { + light_anim.offset = Vec3::unit_z() * 0.5; + } + if let Some(state) = self.character_states.get(&entity) { + light_anim.offset = state.lantern_offset; + } + if animated { + let flicker = (rand::random::() - 0.5) * flicker / dt.sqrt(); + // Close gap between current and target strength by 95% per second + let delta = 0.05_f32.powf(dt); + light_anim.strength = + light_anim.strength * delta + (target_strength + flicker) * (1.0 - delta); + light_anim.col = light_anim.col * delta + target_col * (1.0 - delta) + } else { + light_anim.strength = target_strength; + light_anim.col = target_col; + } + } + } + pub fn maintain(&mut self, renderer: &mut Renderer, scene_data: &SceneData, camera: &Camera) { let state = scene_data.state; let time = state.get_time(); @@ -1463,6 +1518,9 @@ impl FigureMgr { } } + // Update lighting (lanterns) for figures + self.update_lighting(scene_data); + // Clear states that have deleted entities. self.character_states .retain(|entity, _| ecs.entities().is_alive(*entity)); @@ -1932,6 +1990,7 @@ impl FigureMgr { pub struct FigureState { bone_consts: Consts, locals: Consts, + lantern_offset: Vec3, state_time: f64, skeleton: S, last_ori: Vec3, @@ -1941,11 +2000,11 @@ pub struct FigureState { impl FigureState { pub fn new(renderer: &mut Renderer, skeleton: S) -> Self { + let (bone_consts, lantern_offset) = skeleton.compute_matrices(); Self { - bone_consts: renderer - .create_consts(&skeleton.compute_matrices()) - .unwrap(), + bone_consts: renderer.create_consts(&bone_consts).unwrap(), locals: renderer.create_consts(&[FigureLocals::default()]).unwrap(), + lantern_offset, state_time: 0.0, skeleton, last_ori: Vec3::zero(), @@ -1984,12 +2043,14 @@ impl FigureState { let locals = FigureLocals::new(mat, col, is_player); renderer.update_consts(&mut self.locals, &[locals]).unwrap(); + let (new_bone_consts, lantern_offset) = self.skeleton.compute_matrices(); renderer .update_consts( &mut self.bone_consts, - &self.skeleton.compute_matrices()[0..self.skeleton.bone_count()], + &new_bone_consts[0..self.skeleton.bone_count()], ) .unwrap(); + self.lantern_offset = lantern_offset; } pub fn locals(&self) -> &Consts { &self.locals } diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index 8641f2127e..369ac89678 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -270,14 +270,17 @@ impl Scene { .ecs() .read_storage::() .maybe(), - &scene_data.state.ecs().read_storage::(), + &scene_data + .state + .ecs() + .read_storage::(), ) .join() .filter(|(pos, _, _, _)| { (pos.0.distance_squared(player_pos) as f32) < self.loaded_distance.powf(2.0) + LIGHT_DIST_RADIUS }) - .map(|(pos, ori, interpolated, light_emitter)| { + .map(|(pos, ori, interpolated, light_anim)| { // Use interpolated values if they are available let (pos, ori) = interpolated.map_or((pos.0, ori.map(|o| o.0)), |i| (i.pos, Some(i.ori))); @@ -289,9 +292,9 @@ impl Scene { } }; Light::new( - pos + (rot * light_emitter.offset), - light_emitter.col, - light_emitter.strength, + pos + (rot * light_anim.offset), + light_anim.col, + light_anim.strength, ) }) .collect::>(); diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index eb04196759..b8ab4cd0bc 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -331,6 +331,9 @@ impl PlayState for SessionState { self.client.borrow_mut().swap_loadout(); } } + Event::InputUpdate(GameInput::ToggleLantern, true) => { + self.client.borrow_mut().toggle_lantern(); + }, Event::InputUpdate(GameInput::Mount, true) => { let mut client = self.client.borrow_mut(); if client.is_mounted() { diff --git a/voxygen/src/settings.rs b/voxygen/src/settings.rs index cd55b2e556..fcf8e24204 100644 --- a/voxygen/src/settings.rs +++ b/voxygen/src/settings.rs @@ -120,6 +120,7 @@ impl ControlSettings { GameInput::Climb => KeyMouse::Key(VirtualKeyCode::Space), GameInput::ClimbDown => KeyMouse::Key(VirtualKeyCode::LControl), //GameInput::WallLeap => MIDDLE_CLICK_KEY, + GameInput::ToggleLantern => KeyMouse::Key(VirtualKeyCode::G), GameInput::Mount => KeyMouse::Key(VirtualKeyCode::F), GameInput::Map => KeyMouse::Key(VirtualKeyCode::M), GameInput::Bag => KeyMouse::Key(VirtualKeyCode::B), @@ -175,6 +176,7 @@ impl Default for ControlSettings { GameInput::Climb, GameInput::ClimbDown, //GameInput::WallLeap, + GameInput::ToggleLantern, GameInput::Mount, GameInput::Enter, GameInput::Command, @@ -275,6 +277,7 @@ pub mod con_settings { pub climb: Button, pub climb_down: Button, //pub wall_leap: Button, + pub toggle_lantern: Button, pub mount: Button, pub map: Button, pub bag: Button, @@ -361,6 +364,7 @@ pub mod con_settings { climb: Button::Simple(GilButton::South), climb_down: Button::Simple(GilButton::Unknown), //wall_leap: Button::Simple(GilButton::Unknown), + toggle_lantern: Button::Simple(GilButton::East), mount: Button::Simple(GilButton::North), map: Button::Simple(GilButton::DPadRight), bag: Button::Simple(GilButton::DPadDown), diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs index c43ab6a05f..d2356aec47 100644 --- a/voxygen/src/window.rs +++ b/voxygen/src/window.rs @@ -38,6 +38,7 @@ pub enum GameInput { Climb, ClimbDown, //WallLeap, + ToggleLantern, Mount, Enter, Command, @@ -78,6 +79,7 @@ impl GameInput { GameInput::Climb => "gameinput.climb", GameInput::ClimbDown => "gameinput.climbdown", //GameInput::WallLeap => "gameinput.wallleap", + GameInput::ToggleLantern => "gameinput.togglelantern", GameInput::Mount => "gameinput.mount", GameInput::Enter => "gameinput.enter", GameInput::Command => "gameinput.command",