diff --git a/assets/common/manifests/ship_manifest.ron b/assets/common/manifests/ship_manifest.ron index a35bb7a264..4e753b8624 100644 --- a/assets/common/manifests/ship_manifest.ron +++ b/assets/common/manifests/ship_manifest.ron @@ -13,15 +13,22 @@ central: ("airship_human.propeller-r"), ), bone3: ( - offset: (-1.5, -11.0, -5.5), + offset: (-1.5, -10.0, -4.5), central: ("airship_human.rudder"), ), custom_indices: { 1: Air(ChairSingle, 4), 2: Air(Helm, 0), - 3: Air(Door, 4), - 8: Air(Door, 0), + 3: Air(DoorWide, 4), + 8: Air(DoorWide, 0), + 9: Air(CraftingBench, 0), + 11: Air(RepairBench, 0), + 12: Air(DismantlingBench, 4), + 15: Air(Anvil, 2), + 17: Air(CookingPot, 0), + 18: Air(WallLamp, 4), + 23: Air(FireBowlGround, 4), }, ), AirBalloon: ( diff --git a/assets/common/voxel/airship_human/structure.vox b/assets/common/voxel/airship_human/structure.vox index 31d1adcf51..757d25dd14 100644 --- a/assets/common/voxel/airship_human/structure.vox +++ b/assets/common/voxel/airship_human/structure.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:45dcf85530d5a788a160f78a5c6ffe47cb468e96398d4d3479e120b805b9d914 -size 99675 +oid sha256:54ca9513508373762350412df26824aee6c3ce98ae9c64d436b4cd5e7d5b6686 +size 99695 diff --git a/assets/voxygen/voxel/sprite/door/door-wide.vox b/assets/voxygen/voxel/sprite/door/door-wide.vox new file mode 100644 index 0000000000..1d4b42a3ac --- /dev/null +++ b/assets/voxygen/voxel/sprite/door/door-wide.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a11b60ba0364781be1c20bdfa5f0f667bd01cb79e7edcd4c1a240a278636393 +size 8404 diff --git a/assets/voxygen/voxel/sprite_manifest.ron b/assets/voxygen/voxel/sprite_manifest.ron index 34cd801de1..7e839871fc 100644 --- a/assets/voxygen/voxel/sprite_manifest.ron +++ b/assets/voxygen/voxel/sprite_manifest.ron @@ -1871,6 +1871,16 @@ DoorDark: Some(( ], wind_sway: 0.0, )), +DoorWide: Some(( + variations: [ + ( + model: "voxygen.voxel.sprite.door.door-wide", + offset: (-5.5, -5.5, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ], + wind_sway: 0.0, +)), // Bed Bed: Some(( variations: [ diff --git a/common/src/comp/body/ship.rs b/common/src/comp/body/ship.rs index 5629ed6741..47f3b9dd85 100644 --- a/common/src/comp/body/ship.rs +++ b/common/src/comp/body/ship.rs @@ -243,7 +243,7 @@ pub mod figuredata { AssetExt::load("common.manifests.ship_manifest")?; let mut colliders = HashMap::new(); for (_, spec) in (manifest.read().0).0.iter() { - for bone in [&spec.bone0, &spec.bone1, &spec.bone2, &spec.bone3].iter() { + for (index, bone) in [&spec.bone0, &spec.bone1, &spec.bone2, &spec.bone3].iter().enumerate() { // TODO: Currently both client and server load models and manifests from // "common.voxel.". In order to support CSG procedural airships, we probably // need to load them in the server and sync them as an ECS resource. @@ -254,7 +254,7 @@ pub mod figuredata { let dyna = base_structure.vol.map_into(|cell| { if let Some(i) = cell { let color = base_structure.palette[u8::from(i) as usize]; - if let Some(block) = spec.custom_indices.get(&i.into()) { + if let Some(block) = spec.custom_indices.get(&i.into()) && index == 0 { block.to_block(color) } else { Block::new(BlockKind::Misc, color) diff --git a/common/src/terrain/sprite.rs b/common/src/terrain/sprite.rs index 0fc2f4bf57..45e989ffe6 100644 --- a/common/src/terrain/sprite.rs +++ b/common/src/terrain/sprite.rs @@ -243,6 +243,7 @@ make_case_elim!( CommonLockedChest = 0xD9, RepairBench = 0xDA, Helm = 0xDB, + DoorWide = 0xDC, } ); @@ -376,6 +377,7 @@ impl SpriteKind { SpriteKind::Bamboo => 9.0 / 11.0, SpriteKind::MagicalBarrier => 3.0, SpriteKind::MagicalSeal => 1.0, + SpriteKind::Helm => 1.7, _ => return None, }) } @@ -505,10 +507,12 @@ impl SpriteKind { #[inline] pub fn is_controller(&self) -> bool { - match self { - SpriteKind::Helm => true, - _ => false, - } + matches!(self, SpriteKind::Helm) + } + + #[inline] + pub fn is_door(&self) -> bool { + matches!(self, SpriteKind::Door | SpriteKind::DoorWide | SpriteKind::DoorDark) } /// Which tool (if any) is needed to collect this sprite? @@ -640,7 +644,8 @@ impl SpriteKind { | SpriteKind::Grave | SpriteKind::Gravestone | SpriteKind::MagicalBarrier - | SpriteKind::Helm, + | SpriteKind::Helm + | SpriteKind::DoorWide, ) } } diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index dbfd1346ec..0ad8e11b4f 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -31,7 +31,7 @@ use crate::{ use client::Client; use common::{ calendar::Calendar, - comp, + comp::{self, ship::figuredata::VOXEL_COLLIDER_MANIFEST}, outcome::Outcome, resources::DeltaTime, terrain::{BlockKind, TerrainChunk, TerrainGrid}, @@ -667,6 +667,7 @@ impl Scene { self.trail_mgr.maintain(renderer, scene_data); // Update light constants + let max_light_dist = loaded_distance.powi(2) + LIGHT_DIST_RADIUS; lights.extend( ( &scene_data.state.ecs().read_storage::(), @@ -690,7 +691,7 @@ impl Scene { light_anim.col != Rgb::zero() && light_anim.strength > 0.0 && pos.0.distance_squared(viewpoint_pos) - < loaded_distance.powi(2) + LIGHT_DIST_RADIUS + < max_light_dist && h.map_or(true, |h| !h.is_dead) }) .map(|(pos, interpolated, light_anim, _)| { @@ -704,6 +705,43 @@ impl Scene { .map(|el| el.light.with_strength((el.fadeout)(el.timeout))), ), ); + let voxel_colliders_manifest = VOXEL_COLLIDER_MANIFEST.read(); + let figure_mgr = &self.figure_mgr; + lights.extend( + ( + &scene_data.state.ecs().entities(), + &scene_data.state.read_storage::(), + &scene_data.state.read_storage::(), + &scene_data.state.read_storage::(), + &scene_data.state.read_storage::(), + ).join().filter_map(|(entity, pos, ori, body, collider)| { + let vol = collider.get_vol(&voxel_colliders_manifest)?; + + let mat = Mat4::from(ori.to_quat()).translated_3d(pos.0) + * Mat4::translation_3d(vol.translation); + + let p = mat.inverted().mul_point(viewpoint_pos); + let aabb = Aabb { + min: Vec3::zero(), + max: vol.volume().sz.as_(), + }; + if aabb.contains_point(p) || aabb.distance_to_point(p) < max_light_dist { + figure_mgr + .get_blocks_of_interest(entity, body, Some(collider)) + .map(move |(blocks_of_interest, _)| { + blocks_of_interest.lights.iter().map( + move |(block_offset, level)| { + let wpos = mat.mul_point(block_offset.as_() + 0.5); + (wpos, level) + }, + ).filter(move |(wpos, _)| wpos.distance_squared(viewpoint_pos) < max_light_dist) + .map(|(wpos, level)| Light::new(wpos, Rgb::white(), *level as f32 / 7.0)) + }) + } else { + None + } + }).flatten() + ); lights.sort_by_key(|light| light.get_pos().distance_squared(viewpoint_pos) as i32); lights.truncate(MAX_LIGHT_COUNT); renderer.update_consts(&mut self.data.lights, lights); diff --git a/voxygen/src/scene/terrain.rs b/voxygen/src/scene/terrain.rs index 3a967dc06f..65eba8986e 100644 --- a/voxygen/src/scene/terrain.rs +++ b/voxygen/src/scene/terrain.rs @@ -302,7 +302,7 @@ pub fn get_sprite_instances<'a, I: 'a>( light, glow, page, - matches!(sprite, SpriteKind::Door), + sprite.is_door(), ); set_instance(lod_level, instance, wpos); }