mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
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:
parent
3239fc1f2f
commit
5f077e880d
BIN
assets/voxygen/voxel/sprite/door/door-1.vox
(Stored with Git LFS)
Normal file
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
BIN
assets/voxygen/voxel/sprite/door/door-2.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -545,6 +545,14 @@ impl Client {
|
|||||||
.unwrap();
|
.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>) {
|
pub fn collect_block(&mut self, pos: Vec3<i32>) {
|
||||||
self.singleton_stream
|
self.singleton_stream
|
||||||
.send(ClientMsg::ControlEvent(ControlEvent::InventoryManip(
|
.send(ClientMsg::ControlEvent(ControlEvent::InventoryManip(
|
||||||
|
@ -12,6 +12,7 @@ pub const DEFAULT_HOLD_DURATION: Duration = Duration::from_millis(200);
|
|||||||
pub enum InventoryManip {
|
pub enum InventoryManip {
|
||||||
Pickup(Uid),
|
Pickup(Uid),
|
||||||
Collect(Vec3<i32>),
|
Collect(Vec3<i32>),
|
||||||
|
DoorInteraction(Vec3<i32>),
|
||||||
Use(Slot),
|
Use(Slot),
|
||||||
Swap(Slot, Slot),
|
Swap(Slot, Slot),
|
||||||
Drop(Slot),
|
Drop(Slot),
|
||||||
@ -153,6 +154,7 @@ pub struct ControllerInputs {
|
|||||||
pub secondary: Input,
|
pub secondary: Input,
|
||||||
pub ability3: Input,
|
pub ability3: Input,
|
||||||
pub jump: Input,
|
pub jump: Input,
|
||||||
|
pub interact: Input,
|
||||||
pub roll: Input,
|
pub roll: Input,
|
||||||
pub glide: Input,
|
pub glide: Input,
|
||||||
pub wall_leap: Input,
|
pub wall_leap: Input,
|
||||||
@ -178,6 +180,7 @@ impl ControllerInputs {
|
|||||||
self.secondary.tick(dt);
|
self.secondary.tick(dt);
|
||||||
self.ability3.tick(dt);
|
self.ability3.tick(dt);
|
||||||
self.jump.tick(dt);
|
self.jump.tick(dt);
|
||||||
|
self.interact.tick(dt);
|
||||||
self.roll.tick(dt);
|
self.roll.tick(dt);
|
||||||
self.glide.tick(dt);
|
self.glide.tick(dt);
|
||||||
self.wall_leap.tick(dt);
|
self.wall_leap.tick(dt);
|
||||||
@ -190,6 +193,7 @@ impl ControllerInputs {
|
|||||||
self.secondary.tick_freshness();
|
self.secondary.tick_freshness();
|
||||||
self.ability3.tick_freshness();
|
self.ability3.tick_freshness();
|
||||||
self.jump.tick_freshness();
|
self.jump.tick_freshness();
|
||||||
|
self.interact.tick_freshness();
|
||||||
self.roll.tick_freshness();
|
self.roll.tick_freshness();
|
||||||
self.glide.tick_freshness();
|
self.glide.tick_freshness();
|
||||||
self.wall_leap.tick_freshness();
|
self.wall_leap.tick_freshness();
|
||||||
@ -203,6 +207,7 @@ impl ControllerInputs {
|
|||||||
self.secondary.update_with_new(new.secondary);
|
self.secondary.update_with_new(new.secondary);
|
||||||
self.ability3.update_with_new(new.ability3);
|
self.ability3.update_with_new(new.ability3);
|
||||||
self.jump.update_with_new(new.jump);
|
self.jump.update_with_new(new.jump);
|
||||||
|
self.interact.update_with_new(new.interact);
|
||||||
self.roll.update_with_new(new.roll);
|
self.roll.update_with_new(new.roll);
|
||||||
self.glide.update_with_new(new.glide);
|
self.glide.update_with_new(new.glide);
|
||||||
self.wall_leap.update_with_new(new.wall_leap);
|
self.wall_leap.update_with_new(new.wall_leap);
|
||||||
|
@ -61,6 +61,8 @@ pub enum BlockKind {
|
|||||||
StreetLamp,
|
StreetLamp,
|
||||||
StreetLampTall,
|
StreetLampTall,
|
||||||
Door,
|
Door,
|
||||||
|
DoorOpen1,
|
||||||
|
DoorOpen2,
|
||||||
Bed,
|
Bed,
|
||||||
Bench,
|
Bench,
|
||||||
ChairSingle,
|
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 {
|
pub fn is_air(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
BlockKind::Air => true,
|
BlockKind::Air => true,
|
||||||
@ -146,6 +155,8 @@ impl BlockKind {
|
|||||||
BlockKind::StreetLamp => true,
|
BlockKind::StreetLamp => true,
|
||||||
BlockKind::StreetLampTall => true,
|
BlockKind::StreetLampTall => true,
|
||||||
BlockKind::Door => false,
|
BlockKind::Door => false,
|
||||||
|
BlockKind::DoorOpen1 => false,
|
||||||
|
BlockKind::DoorOpen2 => false,
|
||||||
BlockKind::Bed => false,
|
BlockKind::Bed => false,
|
||||||
BlockKind::Bench => false,
|
BlockKind::Bench => false,
|
||||||
BlockKind::ChairSingle => false,
|
BlockKind::ChairSingle => false,
|
||||||
@ -230,6 +241,8 @@ impl BlockKind {
|
|||||||
BlockKind::StreetLamp => false,
|
BlockKind::StreetLamp => false,
|
||||||
BlockKind::StreetLampTall => false,
|
BlockKind::StreetLampTall => false,
|
||||||
BlockKind::Door => false,
|
BlockKind::Door => false,
|
||||||
|
BlockKind::DoorOpen1 => false,
|
||||||
|
BlockKind::DoorOpen2 => false,
|
||||||
BlockKind::Bed => false,
|
BlockKind::Bed => false,
|
||||||
BlockKind::Bench => false,
|
BlockKind::Bench => false,
|
||||||
BlockKind::ChairSingle => false,
|
BlockKind::ChairSingle => false,
|
||||||
@ -301,7 +314,9 @@ impl BlockKind {
|
|||||||
BlockKind::Scarecrow => true,
|
BlockKind::Scarecrow => true,
|
||||||
BlockKind::StreetLamp => true,
|
BlockKind::StreetLamp => true,
|
||||||
BlockKind::StreetLampTall => true,
|
BlockKind::StreetLampTall => true,
|
||||||
BlockKind::Door => false,
|
BlockKind::Door => true,
|
||||||
|
BlockKind::DoorOpen1 => false,
|
||||||
|
BlockKind::DoorOpen2 => false,
|
||||||
BlockKind::Bed => true,
|
BlockKind::Bed => true,
|
||||||
BlockKind::Bench => true,
|
BlockKind::Bench => true,
|
||||||
BlockKind::ChairSingle => true,
|
BlockKind::ChairSingle => true,
|
||||||
@ -350,6 +365,8 @@ impl BlockKind {
|
|||||||
BlockKind::Carrot => 0.18,
|
BlockKind::Carrot => 0.18,
|
||||||
BlockKind::Radish => 0.18,
|
BlockKind::Radish => 0.18,
|
||||||
BlockKind::Door => 3.0,
|
BlockKind::Door => 3.0,
|
||||||
|
BlockKind::DoorOpen1 => 3.0,
|
||||||
|
BlockKind::DoorOpen2 => 3.0,
|
||||||
BlockKind::Bed => 1.54,
|
BlockKind::Bed => 1.54,
|
||||||
BlockKind::Bench => 1.45,
|
BlockKind::Bench => 1.45,
|
||||||
BlockKind::ChairSingle => 1.36,
|
BlockKind::ChairSingle => 1.36,
|
||||||
@ -389,6 +406,18 @@ impl BlockKind {
|
|||||||
BlockKind::VeloriteFrag => true,
|
BlockKind::VeloriteFrag => true,
|
||||||
BlockKind::Chest => true,
|
BlockKind::Chest => true,
|
||||||
BlockKind::Coconut => 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,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -423,6 +452,8 @@ impl Block {
|
|||||||
| BlockKind::Window2
|
| BlockKind::Window2
|
||||||
| BlockKind::Window3
|
| BlockKind::Window3
|
||||||
| BlockKind::Window4
|
| BlockKind::Window4
|
||||||
|
| BlockKind::DoorOpen1
|
||||||
|
| BlockKind::DoorOpen2
|
||||||
| BlockKind::Door => Some(self.color[0] & 0b111),
|
| BlockKind::Door => Some(self.color[0] & 0b111),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use common::{
|
|||||||
Pos, MAX_PICKUP_RANGE_SQR,
|
Pos, MAX_PICKUP_RANGE_SQR,
|
||||||
},
|
},
|
||||||
sync::{Uid, WorldSyncExt},
|
sync::{Uid, WorldSyncExt},
|
||||||
terrain::block::Block,
|
terrain::{Block, BlockKind},
|
||||||
vol::{ReadVol, Vox},
|
vol::{ReadVol, Vox},
|
||||||
};
|
};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
@ -92,6 +92,83 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
|||||||
state.write_component(entity, event);
|
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) => {
|
comp::InventoryManip::Collect(pos) => {
|
||||||
let block = state.terrain().get(pos).ok().copied();
|
let block = state.terrain().get(pos).ok().copied();
|
||||||
|
|
||||||
|
@ -254,6 +254,14 @@ fn sprite_config_for(kind: BlockKind) -> Option<SpriteConfig> {
|
|||||||
variations: 1,
|
variations: 1,
|
||||||
wind_sway: 0.0,
|
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 {
|
BlockKind::Bed => Some(SpriteConfig {
|
||||||
variations: 1,
|
variations: 1,
|
||||||
wind_sway: 0.0,
|
wind_sway: 0.0,
|
||||||
@ -2178,6 +2186,22 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
Vec3::one(),
|
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
|
// Bed
|
||||||
(
|
(
|
||||||
(BlockKind::Bed, 0),
|
(BlockKind::Bed, 0),
|
||||||
|
@ -268,7 +268,7 @@ impl PlayState for SessionState {
|
|||||||
.state()
|
.state()
|
||||||
.terrain()
|
.terrain()
|
||||||
.get(*sp)
|
.get(*sp)
|
||||||
.map(|b| b.is_collectible() || can_build)
|
.map(|b| b.is_collectible() || can_build || b.is_interactable_terrain())
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -453,9 +453,13 @@ impl PlayState for SessionState {
|
|||||||
},
|
},
|
||||||
Event::InputUpdate(GameInput::Interact, state) => {
|
Event::InputUpdate(GameInput::Interact, state) => {
|
||||||
let mut client = self.client.borrow_mut();
|
let mut client = self.client.borrow_mut();
|
||||||
|
self.inputs.interact.set_state(state);
|
||||||
|
|
||||||
// Collect terrain sprites
|
// Collect terrain sprites
|
||||||
if let Some(select_pos) = self.scene.select_pos() {
|
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);
|
client.collect_block(select_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user