Added entity pickup, changed item model

This commit is contained in:
Joshua Barretto 2019-07-29 17:19:08 +01:00
parent 331b6c8b3a
commit 39fc1d6b71
11 changed files with 108 additions and 13 deletions

BIN
assets/voxygen/voxel/object/pouch.vox (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -4,13 +4,13 @@ pub mod error;
// Reexports
pub use crate::error::Error;
pub use specs::{join::Join, Entity as EcsEntity, ReadStorage};
pub use specs::{join::Join, saveload::Marker, Entity as EcsEntity, ReadStorage};
use common::{
comp,
msg::{ClientMsg, ClientState, ServerError, ServerInfo, ServerMsg},
net::PostBox,
state::State,
state::{State, Uid},
terrain::{block::Block, chonk::ChonkMetrics, TerrainChunk, TerrainChunkSize},
vol::VolSize,
ChatType,
@ -173,6 +173,12 @@ impl Client {
self.postbox.send_message(ClientMsg::DropInventorySlot(x))
}
pub fn pick_up(&mut self, entity: EcsEntity) {
if let Some(uid) = self.state.ecs().read_storage::<Uid>().get(entity).copied() {
self.postbox.send_message(ClientMsg::PickUp(uid.id()));
}
}
pub fn view_distance(&self) -> Option<u32> {
self.view_distance
}

View File

@ -48,6 +48,7 @@ pub enum Body {
CarpetHumanSquare,
CarpetHumanSquare2,
CarpetHumanSquircle,
Pouch,
}
impl Body {

View File

@ -3,7 +3,7 @@ use specs_idvs::IDVStorage;
use vek::*;
// Position
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
#[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct Pos(pub Vec3<f32>);
impl Component for Pos {
@ -11,7 +11,7 @@ impl Component for Pos {
}
// Velocity
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
#[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct Vel(pub Vec3<f32>);
impl Component for Vel {
@ -19,7 +19,7 @@ impl Component for Vel {
}
// Orientation
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
#[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct Ori(pub Vec3<f32>);
impl Component for Ori {

View File

@ -30,6 +30,7 @@ pub enum ClientMsg {
},
SwapInventorySlots(usize, usize),
DropInventorySlot(usize),
PickUp(u64),
TerrainChunkRequest {
key: Vec2<i32>,
},

View File

@ -63,7 +63,12 @@ impl<'a> System<'a> for Sys {
{
// Integrate forces
// Friction is assumed to be a constant dependent on location
let friction = 50.0 * if a.on_ground { FRIC_GROUND } else { FRIC_AIR };
let friction = 50.0
* if on_grounds.get(entity).is_some() {
FRIC_GROUND
} else {
FRIC_AIR
};
vel.0 = integrate_forces(dt.0, vel.0, GRAVITY, friction);
// Basic collision with terrain

View File

@ -506,12 +506,49 @@ impl Server {
state.write_component(entity, comp::InventoryUpdate);
if let (Some(pos), Some(item)) =
(state.ecs().read_storage::<comp::Pos>().get(entity), item)
if let (Some(item), Some(pos)) =
(item, state.ecs().read_storage::<comp::Pos>().get(entity))
{
dropped_items.push((*pos, item));
dropped_items.push((
*pos,
state
.ecs()
.read_storage::<comp::Ori>()
.get(entity)
.copied()
.unwrap_or(comp::Ori(Vec3::unit_y())),
item,
));
}
}
ClientMsg::PickUp(uid) => {
let item_entity = state.ecs_mut().entity_from_uid(uid);
let ecs = state.ecs_mut();
let item_entity = if let (Some((item, item_entity)), Some(inv)) = (
item_entity.and_then(|item_entity| {
ecs.write_storage::<comp::Item>()
.get_mut(item_entity)
.map(|item| (*item, item_entity))
}),
ecs.write_storage::<comp::Inventory>().get_mut(entity),
) {
if inv.insert(item).is_none() {
Some(item_entity)
} else {
None
}
} else {
None
};
if let Some(item_entity) = item_entity {
let _ = ecs.delete_entity_synced(item_entity);
}
state.write_component(entity, comp::InventoryUpdate);
}
ClientMsg::Character { name, body } => match client.client_state {
// Become Registered first.
ClientState::Connected => {
@ -688,9 +725,11 @@ impl Server {
self.state.set_block(pos, block);
}
for (pos, item) in dropped_items {
self.create_object(pos, comp::object::Body::Crate)
for (pos, ori, item) in dropped_items {
self.create_object(Default::default(), comp::object::Body::Pouch)
.with(comp::Pos(pos.0 + Vec3::unit_z() * 1.0))
.with(item)
.with(comp::Vel(ori.0.normalized() * 2.0 + Vec3::unit_z() * 2.0))
.build();
}

View File

@ -583,6 +583,7 @@ impl FigureModelCache {
"object/carpet_human_squircle.vox",
Vec3::new(-21.0, -21.0, -0.5),
),
object::Body::Pouch => ("object/pouch.vox", Vec3::new(-5.5, -4.5, 0.0)),
};
Self::load_mesh(name, offset)
}
@ -970,8 +971,13 @@ impl<S: Skeleton> FigureState<S> {
dt: f32,
) {
// Update interpolation values
self.pos = Lerp::lerp(self.pos, pos, 15.0 * dt);
self.ori = Slerp::slerp(self.ori, ori, 7.5 * dt);
if self.pos.distance_squared(pos) < 64.0 * 64.0 {
self.pos = Lerp::lerp(self.pos, pos, 15.0 * dt);
self.ori = Slerp::slerp(self.ori, ori, 7.5 * dt);
} else {
self.pos = pos;
self.ori = ori;
}
let mat = Mat4::<f32>::identity()
* Mat4::translation_3d(self.pos)

View File

@ -9,6 +9,7 @@ use crate::{
use client::{self, Client};
use common::{clock::Clock, comp, comp::Pos, msg::ClientState, terrain::Block, vol::ReadVol};
use log::error;
use specs::Join;
use std::{cell::RefCell, rc::Rc, time::Duration};
use vek::*;
@ -212,6 +213,35 @@ impl PlayState for SessionState {
Event::InputUpdate(GameInput::Glide, state) => {
self.controller.glide = state;
}
Event::InputUpdate(GameInput::Interact, state) => {
let mut client = self.client.borrow_mut();
let player_pos = client
.state()
.read_storage::<comp::Pos>()
.get(client.entity())
.copied();
if let (Some(player_pos), true) = (player_pos, state) {
let entity = (
&client.state().ecs().entities(),
&client.state().ecs().read_storage::<comp::Pos>(),
&client.state().ecs().read_storage::<comp::Item>(),
)
.join()
.filter(|(_, pos, _)| {
pos.0.distance_squared(player_pos.0) < 3.0 * 3.0
})
.min_by_key(|(_, pos, _)| {
(pos.0.distance_squared(player_pos.0) * 1000.0) as i32
})
.map(|(entity, _, _)| entity);
if let Some(entity) = entity {
client.pick_up(entity);
}
}
}
// Pass all other events to the scene
event => {

View File

@ -35,6 +35,7 @@ pub struct ControlSettings {
pub attack: KeyMouse,
pub second_attack: KeyMouse,
pub roll: KeyMouse,
pub interact: KeyMouse,
}
impl Default for ControlSettings {
@ -66,6 +67,7 @@ impl Default for ControlSettings {
attack: KeyMouse::Mouse(MouseButton::Left),
second_attack: KeyMouse::Mouse(MouseButton::Right),
roll: KeyMouse::Mouse(MouseButton::Middle),
interact: KeyMouse::Key(VirtualKeyCode::E),
}
}
}

View File

@ -38,6 +38,7 @@ pub enum GameInput {
SecondAttack,
Roll,
Respawn,
Interact,
}
/// Represents an incoming event from the window.
@ -143,6 +144,7 @@ impl Window {
key_map.insert(settings.controls.attack, GameInput::Attack);
key_map.insert(settings.controls.second_attack, GameInput::SecondAttack);
key_map.insert(settings.controls.roll, GameInput::Roll);
key_map.insert(settings.controls.interact, GameInput::Interact);
let keypress_map = HashMap::new();