Implement player entities
This commit is contained in:
parent
b037fb1e5c
commit
e157daecaf
|
@ -18,6 +18,10 @@ pub fn add_systems(m: &mut ecs::Manager) {
|
|||
m.add_system(sys);
|
||||
let sys = systems::ApplyGravity::new(m);
|
||||
m.add_system(sys);
|
||||
let sys = systems::LerpPosition::new(m);
|
||||
m.add_render_system(sys);
|
||||
let sys = systems::LerpRotation::new(m);
|
||||
m.add_render_system(sys);
|
||||
|
||||
block_entity::add_systems(m);
|
||||
}
|
||||
|
@ -44,6 +48,23 @@ impl Position {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TargetPosition {
|
||||
pub position: Vector3<f64>,
|
||||
}
|
||||
|
||||
impl TargetPosition {
|
||||
pub fn new(x: f64, y: f64, z: f64) -> TargetPosition {
|
||||
TargetPosition {
|
||||
position: Vector3::new(x, y, z),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn zero() -> TargetPosition {
|
||||
TargetPosition::new(0.0, 0.0, 0.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Velocity of an entity in the world.
|
||||
#[derive(Debug)]
|
||||
pub struct Velocity {
|
||||
|
@ -81,6 +102,24 @@ impl Rotation {
|
|||
Rotation::new(0.0, 0.0)
|
||||
}
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct TargetRotation {
|
||||
pub yaw: f64,
|
||||
pub pitch: f64,
|
||||
}
|
||||
|
||||
impl TargetRotation {
|
||||
pub fn new(yaw: f64, pitch: f64) -> TargetRotation {
|
||||
TargetRotation {
|
||||
yaw: yaw,
|
||||
pitch: pitch,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn zero() -> TargetRotation {
|
||||
TargetRotation::new(0.0, 0.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Gravity {
|
||||
pub on_ground: bool,
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
use ecs;
|
||||
use super::{
|
||||
Position,
|
||||
TargetPosition,
|
||||
Velocity,
|
||||
Rotation,
|
||||
TargetRotation,
|
||||
Gravity,
|
||||
Bounds,
|
||||
GameInfo,
|
||||
|
@ -45,6 +47,21 @@ pub fn create_local(m: &mut ecs::Manager) -> ecs::Entity {
|
|||
entity
|
||||
}
|
||||
|
||||
pub fn create_remote(m: &mut ecs::Manager) -> ecs::Entity {
|
||||
let entity = m.create_entity();
|
||||
m.add_component_direct(entity, Position::new(0.0, 0.0, 0.0));
|
||||
m.add_component_direct(entity, TargetPosition::new(0.0, 0.0, 0.0));
|
||||
m.add_component_direct(entity, Rotation::new(0.0, 0.0));
|
||||
m.add_component_direct(entity, TargetRotation::new(0.0, 0.0));
|
||||
m.add_component_direct(entity, Velocity::new(0.0, 0.0, 0.0));
|
||||
m.add_component_direct(entity, Bounds::new(Aabb3::new(
|
||||
Point3::new(-0.3, 0.0, -0.3),
|
||||
Point3::new(0.3, 1.8, 0.3)
|
||||
)));
|
||||
m.add_component_direct(entity, PlayerModel::new(true, true, false));
|
||||
entity
|
||||
}
|
||||
|
||||
|
||||
pub struct PlayerModel {
|
||||
model: Option<model::ModelKey>,
|
||||
|
|
|
@ -118,3 +118,99 @@ impl ecs::System for UpdateLastPosition {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LerpPosition {
|
||||
filter: ecs::Filter,
|
||||
position: ecs::Key<Position>,
|
||||
target_position: ecs::Key<TargetPosition>,
|
||||
game_info: ecs::Key<GameInfo>,
|
||||
}
|
||||
|
||||
impl LerpPosition {
|
||||
pub fn new(m: &mut ecs::Manager) -> LerpPosition {
|
||||
let position = m.get_key();
|
||||
let target_position = m.get_key();
|
||||
LerpPosition {
|
||||
filter: ecs::Filter::new()
|
||||
.with(position)
|
||||
.with(target_position),
|
||||
position: position,
|
||||
target_position: target_position,
|
||||
game_info: m.get_key(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ecs::System for LerpPosition {
|
||||
|
||||
fn filter(&self) -> &ecs::Filter {
|
||||
&self.filter
|
||||
}
|
||||
|
||||
fn update(&mut self, m: &mut ecs::Manager, _: &mut world::World, _: &mut render::Renderer) {
|
||||
let world_entity = m.get_world();
|
||||
let delta = m.get_component_mut(world_entity, self.game_info).unwrap().delta.min(5.0);
|
||||
for e in m.find(&self.filter) {
|
||||
let pos = m.get_component_mut(e, self.position).unwrap();
|
||||
let target_pos = m.get_component(e, self.target_position).unwrap();
|
||||
|
||||
pos.position = pos.position + (target_pos.position - pos.position) * delta * 0.2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LerpRotation {
|
||||
filter: ecs::Filter,
|
||||
rotation: ecs::Key<Rotation>,
|
||||
target_rotation: ecs::Key<TargetRotation>,
|
||||
game_info: ecs::Key<GameInfo>,
|
||||
}
|
||||
|
||||
impl LerpRotation {
|
||||
pub fn new(m: &mut ecs::Manager) -> LerpRotation {
|
||||
let rotation = m.get_key();
|
||||
let target_rotation = m.get_key();
|
||||
LerpRotation {
|
||||
filter: ecs::Filter::new()
|
||||
.with(rotation)
|
||||
.with(target_rotation),
|
||||
rotation: rotation,
|
||||
target_rotation: target_rotation,
|
||||
game_info: m.get_key(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ecs::System for LerpRotation {
|
||||
|
||||
fn filter(&self) -> &ecs::Filter {
|
||||
&self.filter
|
||||
}
|
||||
|
||||
fn update(&mut self, m: &mut ecs::Manager, _: &mut world::World, _: &mut render::Renderer) {
|
||||
use std::f64::consts::PI;
|
||||
let world_entity = m.get_world();
|
||||
let delta = m.get_component_mut(world_entity, self.game_info).unwrap().delta.min(5.0);
|
||||
for e in m.find(&self.filter) {
|
||||
let rot = m.get_component_mut(e, self.rotation).unwrap();
|
||||
let target_rot = m.get_component_mut(e, self.target_rotation).unwrap();
|
||||
target_rot.yaw = (PI*2.0 + target_rot.yaw) % (PI*2.0);
|
||||
target_rot.pitch = (PI*2.0 + target_rot.pitch) % (PI*2.0);
|
||||
|
||||
let mut delta_yaw = target_rot.yaw - rot.yaw;
|
||||
let mut delta_pitch = target_rot.pitch - rot.pitch;
|
||||
|
||||
if delta_yaw.abs() > PI {
|
||||
delta_yaw = (PI - delta_yaw.abs()) * delta_yaw.signum();
|
||||
}
|
||||
if delta_pitch.abs() > PI {
|
||||
delta_pitch = (PI - delta_pitch.abs()) * delta_pitch.signum();
|
||||
}
|
||||
|
||||
rot.yaw += delta_yaw * 0.2 * delta;
|
||||
rot.pitch += delta_pitch * 0.2 * delta;
|
||||
rot.yaw = (PI*2.0 + rot.yaw) % (PI*2.0);
|
||||
rot.pitch = (PI*2.0 + rot.pitch) % (PI*2.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,8 +59,10 @@ pub struct Server {
|
|||
player_movement: ecs::Key<entity::player::PlayerMovement>,
|
||||
gravity: ecs::Key<entity::Gravity>,
|
||||
position: ecs::Key<entity::Position>,
|
||||
target_position: ecs::Key<entity::TargetPosition>,
|
||||
gamemode: ecs::Key<Gamemode>,
|
||||
pub rotation: ecs::Key<entity::Rotation>,
|
||||
target_rotation: ecs::Key<entity::TargetRotation>,
|
||||
//
|
||||
|
||||
pub player: Option<ecs::Entity>,
|
||||
|
@ -286,8 +288,10 @@ impl Server {
|
|||
player_movement: entities.get_key(),
|
||||
gravity: entities.get_key(),
|
||||
position: entities.get_key(),
|
||||
target_position: entities.get_key(),
|
||||
gamemode: entities.get_key(),
|
||||
rotation: entities.get_key(),
|
||||
target_rotation: entities.get_key(),
|
||||
//
|
||||
|
||||
entities: entities,
|
||||
|
@ -366,6 +370,13 @@ impl Server {
|
|||
ChangeGameState => on_game_state_change,
|
||||
UpdateSign => on_sign_update,
|
||||
PlayerInfo => on_player_info,
|
||||
// Entities
|
||||
EntityDestroy => on_entity_destroy,
|
||||
SpawnPlayer => on_player_spawn,
|
||||
EntityTeleport => on_entity_teleport,
|
||||
EntityMove => on_entity_move,
|
||||
EntityLook => on_entity_look,
|
||||
EntityLookAndMove => on_entity_look_and_move,
|
||||
}
|
||||
},
|
||||
Err(err) => panic!("Err: {:?}", err),
|
||||
|
@ -533,6 +544,85 @@ impl Server {
|
|||
}
|
||||
}
|
||||
|
||||
fn on_entity_destroy(&mut self, entity_destroy: packet::play::clientbound::EntityDestroy) {
|
||||
for id in entity_destroy.entity_ids.data {
|
||||
if let Some(entity) = self.entity_map.remove(&id.0) {
|
||||
self.entities.remove_entity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn on_entity_teleport(&mut self, entity_telport: packet::play::clientbound::EntityTeleport) {
|
||||
use std::f64::consts::PI;
|
||||
if let Some(entity) = self.entity_map.get(&entity_telport.entity_id.0) {
|
||||
let target_position = self.entities.get_component_mut(*entity, self.target_position).unwrap();
|
||||
let target_rotation = self.entities.get_component_mut(*entity, self.target_rotation).unwrap();
|
||||
target_position.position.x = entity_telport.x;
|
||||
target_position.position.y = entity_telport.y;
|
||||
target_position.position.z = entity_telport.z;
|
||||
target_rotation.yaw = -((entity_telport.yaw as f64) / 256.0) * PI * 2.0;
|
||||
target_rotation.pitch = -((entity_telport.pitch as f64) / 256.0) * PI * 2.0;
|
||||
}
|
||||
}
|
||||
|
||||
fn on_entity_move(&mut self, m: packet::play::clientbound::EntityMove) {
|
||||
if let Some(entity) = self.entity_map.get(&m.entity_id.0) {
|
||||
let position = self.entities.get_component_mut(*entity, self.target_position).unwrap();
|
||||
position.position.x += m.delta_x as f64 / (32.0 * 128.0);
|
||||
position.position.y += m.delta_y as f64 / (32.0 * 128.0);
|
||||
position.position.z += m.delta_z as f64 / (32.0 * 128.0);
|
||||
}
|
||||
}
|
||||
|
||||
fn on_entity_look(&mut self, look: packet::play::clientbound::EntityLook) {
|
||||
use std::f64::consts::PI;
|
||||
if let Some(entity) = self.entity_map.get(&look.entity_id.0) {
|
||||
let rotation = self.entities.get_component_mut(*entity, self.target_rotation).unwrap();
|
||||
rotation.yaw = -((look.yaw as f64) / 256.0) * PI * 2.0;
|
||||
rotation.pitch = -((look.pitch as f64) / 256.0) * PI * 2.0;
|
||||
}
|
||||
}
|
||||
|
||||
fn on_entity_look_and_move(&mut self, lookmove: packet::play::clientbound::EntityLookAndMove) {
|
||||
use std::f64::consts::PI;
|
||||
if let Some(entity) = self.entity_map.get(&lookmove.entity_id.0) {
|
||||
let position = self.entities.get_component_mut(*entity, self.target_position).unwrap();
|
||||
let rotation = self.entities.get_component_mut(*entity, self.target_rotation).unwrap();
|
||||
position.position.x += lookmove.delta_x as f64 / (32.0 * 128.0);
|
||||
position.position.y += lookmove.delta_y as f64 / (32.0 * 128.0);
|
||||
position.position.z += lookmove.delta_z as f64 / (32.0 * 128.0);
|
||||
rotation.yaw = -((lookmove.yaw as f64) / 256.0) * PI * 2.0;
|
||||
rotation.pitch = -((lookmove.pitch as f64) / 256.0) * PI * 2.0;
|
||||
}
|
||||
}
|
||||
|
||||
fn on_player_spawn(&mut self, spawn: packet::play::clientbound::SpawnPlayer) {
|
||||
use std::f64::consts::PI;
|
||||
if let Some(entity) = self.entity_map.remove(&spawn.entity_id.0) {
|
||||
self.entities.remove_entity(entity);
|
||||
}
|
||||
let entity = entity::player::create_remote(&mut self.entities);
|
||||
let position = self.entities.get_component_mut(entity, self.position).unwrap();
|
||||
let target_position = self.entities.get_component_mut(entity, self.target_position).unwrap();
|
||||
let rotation = self.entities.get_component_mut(entity, self.rotation).unwrap();
|
||||
let target_rotation = self.entities.get_component_mut(entity, self.target_rotation).unwrap();
|
||||
position.position.x = spawn.x;
|
||||
position.position.y = spawn.y;
|
||||
position.position.z = spawn.z;
|
||||
target_position.position.x = spawn.x;
|
||||
target_position.position.y = spawn.y;
|
||||
target_position.position.z = spawn.z;
|
||||
rotation.yaw = -((spawn.yaw as f64) / 256.0) * PI * 2.0;
|
||||
rotation.pitch = -((spawn.pitch as f64) / 256.0) * PI * 2.0;
|
||||
target_rotation.yaw = rotation.yaw;
|
||||
target_rotation.pitch = rotation.pitch;
|
||||
if let Some(info) = self.players.get(&spawn.uuid) {
|
||||
let model = self.entities.get_component_mut_direct::<entity::player::PlayerModel>(entity).unwrap();
|
||||
model.set_skin(info.skin_url.clone());
|
||||
}
|
||||
self.entity_map.insert(spawn.entity_id.0, entity);
|
||||
}
|
||||
|
||||
fn on_teleport(&mut self, teleport: packet::play::clientbound::TeleportPlayer) {
|
||||
if let Some(player) = self.player {
|
||||
let position = self.entities.get_component_mut(player, self.position).unwrap();
|
||||
|
|
Loading…
Reference in New Issue