Doors can be opened and closed with interaction key (logic for door interaction, code for input event, 2 new vox files)

This commit is contained in:
Goldenrevolver 2020-07-09 15:31:30 +02:00
parent 3239fc1f2f
commit 5f077e880d
8 changed files with 158 additions and 3 deletions

BIN
assets/voxygen/voxel/sprite/door/door-1.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/sprite/door/door-2.vox (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -545,6 +545,14 @@ impl Client {
.unwrap();
}
pub fn interact_with_door(&mut self, pos: Vec3<i32>) {
self.singleton_stream
.send(ClientMsg::ControlEvent(ControlEvent::InventoryManip(
InventoryManip::DoorInteraction(pos),
)))
.unwrap();
}
pub fn collect_block(&mut self, pos: Vec3<i32>) {
self.singleton_stream
.send(ClientMsg::ControlEvent(ControlEvent::InventoryManip(

View File

@ -12,6 +12,7 @@ pub const DEFAULT_HOLD_DURATION: Duration = Duration::from_millis(200);
pub enum InventoryManip {
Pickup(Uid),
Collect(Vec3<i32>),
DoorInteraction(Vec3<i32>),
Use(Slot),
Swap(Slot, Slot),
Drop(Slot),
@ -153,6 +154,7 @@ pub struct ControllerInputs {
pub secondary: Input,
pub ability3: Input,
pub jump: Input,
pub interact: Input,
pub roll: Input,
pub glide: Input,
pub wall_leap: Input,
@ -178,6 +180,7 @@ impl ControllerInputs {
self.secondary.tick(dt);
self.ability3.tick(dt);
self.jump.tick(dt);
self.interact.tick(dt);
self.roll.tick(dt);
self.glide.tick(dt);
self.wall_leap.tick(dt);
@ -190,6 +193,7 @@ impl ControllerInputs {
self.secondary.tick_freshness();
self.ability3.tick_freshness();
self.jump.tick_freshness();
self.interact.tick_freshness();
self.roll.tick_freshness();
self.glide.tick_freshness();
self.wall_leap.tick_freshness();
@ -203,6 +207,7 @@ impl ControllerInputs {
self.secondary.update_with_new(new.secondary);
self.ability3.update_with_new(new.ability3);
self.jump.update_with_new(new.jump);
self.interact.update_with_new(new.interact);
self.roll.update_with_new(new.roll);
self.glide.update_with_new(new.glide);
self.wall_leap.update_with_new(new.wall_leap);

View File

@ -61,6 +61,8 @@ pub enum BlockKind {
StreetLamp,
StreetLampTall,
Door,
DoorOpen1,
DoorOpen2,
Bed,
Bench,
ChairSingle,
@ -95,6 +97,13 @@ impl BlockKind {
}
}
pub fn is_tangible2(&self) -> bool {
match self {
BlockKind::Air => false,
kind => !kind.is_fluid(),
}
}
pub fn is_air(&self) -> bool {
match self {
BlockKind::Air => true,
@ -146,6 +155,8 @@ impl BlockKind {
BlockKind::StreetLamp => true,
BlockKind::StreetLampTall => true,
BlockKind::Door => false,
BlockKind::DoorOpen1 => false,
BlockKind::DoorOpen2 => false,
BlockKind::Bed => false,
BlockKind::Bench => false,
BlockKind::ChairSingle => false,
@ -230,6 +241,8 @@ impl BlockKind {
BlockKind::StreetLamp => false,
BlockKind::StreetLampTall => false,
BlockKind::Door => false,
BlockKind::DoorOpen1 => false,
BlockKind::DoorOpen2 => false,
BlockKind::Bed => false,
BlockKind::Bench => false,
BlockKind::ChairSingle => false,
@ -301,7 +314,9 @@ impl BlockKind {
BlockKind::Scarecrow => true,
BlockKind::StreetLamp => true,
BlockKind::StreetLampTall => true,
BlockKind::Door => false,
BlockKind::Door => true,
BlockKind::DoorOpen1 => false,
BlockKind::DoorOpen2 => false,
BlockKind::Bed => true,
BlockKind::Bench => true,
BlockKind::ChairSingle => true,
@ -350,6 +365,8 @@ impl BlockKind {
BlockKind::Carrot => 0.18,
BlockKind::Radish => 0.18,
BlockKind::Door => 3.0,
BlockKind::DoorOpen1 => 3.0,
BlockKind::DoorOpen2 => 3.0,
BlockKind::Bed => 1.54,
BlockKind::Bench => 1.45,
BlockKind::ChairSingle => 1.36,
@ -389,6 +406,18 @@ impl BlockKind {
BlockKind::VeloriteFrag => true,
BlockKind::Chest => true,
BlockKind::Coconut => true,
BlockKind::Door => false,
BlockKind::DoorOpen1 => false,
BlockKind::DoorOpen2 => false,
_ => false,
}
}
pub fn is_interactable_terrain(&self) -> bool {
match self {
BlockKind::Door => true,
BlockKind::DoorOpen1 => true,
BlockKind::DoorOpen2 => true,
_ => false,
}
}
@ -423,6 +452,8 @@ impl Block {
| BlockKind::Window2
| BlockKind::Window3
| BlockKind::Window4
| BlockKind::DoorOpen1
| BlockKind::DoorOpen2
| BlockKind::Door => Some(self.color[0] & 0b111),
_ => None,
}

View File

@ -6,7 +6,7 @@ use common::{
Pos, MAX_PICKUP_RANGE_SQR,
},
sync::{Uid, WorldSyncExt},
terrain::block::Block,
terrain::{Block, BlockKind},
vol::{ReadVol, Vox},
};
use rand::Rng;
@ -92,6 +92,83 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
state.write_component(entity, event);
},
// the interaction of opening and closing doors
// this might be better off in a different class
comp::InventoryManip::DoorInteraction(pos) => {
let first_door = state.terrain().get(pos).ok().copied();
if let Some(first_door) = first_door {
// check for block that is supported by this interaction (in case this method gets extended)
if first_door.is_interactable_terrain() {
if first_door.kind() == BlockKind::Door {
let ori = first_door.get_ori().unwrap();
let color = first_door.get_color().unwrap();
// the orientation of doors is saved in the first 'color' as the rgb color is not needed
// the orientation is a value between 0 and 7, the function get ori retrieves a value modulo 8 automatically
// the left and right closed doors facing in the same direction have different orientation so we add the difference (difference of 4, modulo 8)
let rgb = [ori + 4, color[1], color[2]].into();
state.try_set_block(pos, Block::new(BlockKind::DoorOpen2, rgb));
// TODO add a sound effect for 'opening' doors here
// calculate where to look for a second door
let mut pos2 = pos.clone();
if ori == 0 { pos2 += (1,0,0); }
else if ori == 2 { pos2 += (0,1,0); }
else if ori == 4 { pos2 += (-1,0,0); }
else if ori == 6 { pos2 += (0,-1,0); }
let second_door = state.terrain().get(pos2).ok().copied().unwrap();
// check if there is a fitting door there
if second_door.kind() == BlockKind::Door {
if second_door.get_ori().unwrap() == (ori + 4) & 0b111 {
state.try_set_block(pos2, Block::new(BlockKind::DoorOpen1, rgb));
}
}
} else if first_door.kind() == BlockKind::DoorOpen1 || first_door.kind() == BlockKind::DoorOpen2 {
let ori = first_door.get_ori().unwrap();
let color = first_door.get_color().unwrap();
// same as above, but only needed for open door 2
let rgb = [ori + 4, color[1], color[2]].into();
if first_door.kind() == BlockKind::DoorOpen1 {
state.try_set_block(pos, Block::new(BlockKind::Door, color));
}else{
state.try_set_block(pos, Block::new(BlockKind::Door, rgb));
}
// TODO add a sound effect for 'closing' doors here
// calculate where to look for a second door
// (cant think of a smarter way to do this for the case of closing doors. kind and ori is not enough anymore to differentiate left and right)
let positions = [(1,0,0),(0,1,0),(-1,0,0),(0,-1,0)];
for i in 0..4 {
let pos2 = pos.clone() + positions[i];
let second_door = state.terrain().get(pos2).ok().copied().unwrap();
//check if there is a fitting door there
if second_door.kind() == BlockKind::DoorOpen1 || second_door.kind() == BlockKind::DoorOpen2 {
if second_door.kind() != first_door.kind() {
if second_door.kind() == BlockKind::DoorOpen1 {
state.try_set_block(pos2, Block::new(BlockKind::Door, color));
}else{
state.try_set_block(pos2, Block::new(BlockKind::Door, rgb));
}
}
}
}
}
}
}
},
comp::InventoryManip::Collect(pos) => {
let block = state.terrain().get(pos).ok().copied();

View File

@ -254,6 +254,14 @@ fn sprite_config_for(kind: BlockKind) -> Option<SpriteConfig> {
variations: 1,
wind_sway: 0.0,
}),
BlockKind::DoorOpen1 => Some(SpriteConfig {
variations: 1,
wind_sway: 0.0,
}),
BlockKind::DoorOpen2 => Some(SpriteConfig {
variations: 1,
wind_sway: 0.0,
}),
BlockKind::Bed => Some(SpriteConfig {
variations: 1,
wind_sway: 0.0,
@ -2178,6 +2186,22 @@ impl<V: RectRasterableVol> Terrain<V> {
Vec3::one(),
),
),
(
(BlockKind::DoorOpen1, 0),
make_models(
"voxygen.voxel.sprite.door.door-1",
Vec3::new(-5.5, -5.5, 0.0),
Vec3::one(),
),
),
(
(BlockKind::DoorOpen2, 0),
make_models(
"voxygen.voxel.sprite.door.door-2",
Vec3::new(-5.5, -5.5, 0.0),
Vec3::one(),
),
),
// Bed
(
(BlockKind::Bed, 0),

View File

@ -268,7 +268,7 @@ impl PlayState for SessionState {
.state()
.terrain()
.get(*sp)
.map(|b| b.is_collectible() || can_build)
.map(|b| b.is_collectible() || can_build || b.is_interactable_terrain())
.unwrap_or(false)
}));
@ -453,9 +453,13 @@ impl PlayState for SessionState {
},
Event::InputUpdate(GameInput::Interact, state) => {
let mut client = self.client.borrow_mut();
self.inputs.interact.set_state(state);
// Collect terrain sprites
if let Some(select_pos) = self.scene.select_pos() {
if self.inputs.interact.is_just_pressed() {
client.interact_with_door(select_pos);
}
client.collect_block(select_pos);
}