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);
|
m.add_system(sys);
|
||||||
let sys = systems::ApplyGravity::new(m);
|
let sys = systems::ApplyGravity::new(m);
|
||||||
m.add_system(sys);
|
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);
|
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.
|
/// Velocity of an entity in the world.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Velocity {
|
pub struct Velocity {
|
||||||
|
@ -81,6 +102,24 @@ impl Rotation {
|
||||||
Rotation::new(0.0, 0.0)
|
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 struct Gravity {
|
||||||
pub on_ground: bool,
|
pub on_ground: bool,
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
use ecs;
|
use ecs;
|
||||||
use super::{
|
use super::{
|
||||||
Position,
|
Position,
|
||||||
|
TargetPosition,
|
||||||
Velocity,
|
Velocity,
|
||||||
Rotation,
|
Rotation,
|
||||||
|
TargetRotation,
|
||||||
Gravity,
|
Gravity,
|
||||||
Bounds,
|
Bounds,
|
||||||
GameInfo,
|
GameInfo,
|
||||||
|
@ -45,6 +47,21 @@ pub fn create_local(m: &mut ecs::Manager) -> ecs::Entity {
|
||||||
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 {
|
pub struct PlayerModel {
|
||||||
model: Option<model::ModelKey>,
|
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>,
|
player_movement: ecs::Key<entity::player::PlayerMovement>,
|
||||||
gravity: ecs::Key<entity::Gravity>,
|
gravity: ecs::Key<entity::Gravity>,
|
||||||
position: ecs::Key<entity::Position>,
|
position: ecs::Key<entity::Position>,
|
||||||
|
target_position: ecs::Key<entity::TargetPosition>,
|
||||||
gamemode: ecs::Key<Gamemode>,
|
gamemode: ecs::Key<Gamemode>,
|
||||||
pub rotation: ecs::Key<entity::Rotation>,
|
pub rotation: ecs::Key<entity::Rotation>,
|
||||||
|
target_rotation: ecs::Key<entity::TargetRotation>,
|
||||||
//
|
//
|
||||||
|
|
||||||
pub player: Option<ecs::Entity>,
|
pub player: Option<ecs::Entity>,
|
||||||
|
@ -286,8 +288,10 @@ impl Server {
|
||||||
player_movement: entities.get_key(),
|
player_movement: entities.get_key(),
|
||||||
gravity: entities.get_key(),
|
gravity: entities.get_key(),
|
||||||
position: entities.get_key(),
|
position: entities.get_key(),
|
||||||
|
target_position: entities.get_key(),
|
||||||
gamemode: entities.get_key(),
|
gamemode: entities.get_key(),
|
||||||
rotation: entities.get_key(),
|
rotation: entities.get_key(),
|
||||||
|
target_rotation: entities.get_key(),
|
||||||
//
|
//
|
||||||
|
|
||||||
entities: entities,
|
entities: entities,
|
||||||
|
@ -366,6 +370,13 @@ impl Server {
|
||||||
ChangeGameState => on_game_state_change,
|
ChangeGameState => on_game_state_change,
|
||||||
UpdateSign => on_sign_update,
|
UpdateSign => on_sign_update,
|
||||||
PlayerInfo => on_player_info,
|
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),
|
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) {
|
fn on_teleport(&mut self, teleport: packet::play::clientbound::TeleportPlayer) {
|
||||||
if let Some(player) = self.player {
|
if let Some(player) = self.player {
|
||||||
let position = self.entities.get_component_mut(player, self.position).unwrap();
|
let position = self.entities.get_component_mut(player, self.position).unwrap();
|
||||||
|
|
Loading…
Reference in New Issue