Skip to content

Commit

Permalink
Refactor Entity
Browse files Browse the repository at this point in the history
  • Loading branch information
Snowiiii committed Sep 7, 2024
1 parent cd25387 commit 2ee9710
Show file tree
Hide file tree
Showing 9 changed files with 289 additions and 195 deletions.
3 changes: 0 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion pumpkin-entity/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ version.workspace = true
edition.workspace = true

[dependencies]
pumpkin-core = { path = "../pumpkin-core"}
59 changes: 0 additions & 59 deletions pumpkin-entity/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,63 +1,4 @@
use entity_type::EntityType;
use pose::EntityPose;
use pumpkin_core::math::{
get_section_cord, position::WorldPosition, vector2::Vector2, vector3::Vector3,
};

pub mod entity_type;
pub mod pose;

pub type EntityId = i32;

pub struct Entity {
pub entity_id: EntityId,
pub entity_type: EntityType,
pub pos: Vector3<f64>,
pub block_pos: WorldPosition,
pub chunk_pos: Vector2<i32>,

pub yaw: f32,
pub head_yaw: f32,
pub pitch: f32,
// TODO: Change this in diffrent poses
pub standing_eye_height: f32,
pub pose: EntityPose,
}

impl Entity {
pub fn new(entity_id: EntityId, entity_type: EntityType, standing_eye_height: f32) -> Self {
Self {
entity_id,
entity_type,
pos: Vector3::new(0.0, 0.0, 0.0),
block_pos: WorldPosition(Vector3::new(0, 0, 0)),
chunk_pos: Vector2::new(0, 0),
yaw: 0.0,
head_yaw: 0.0,
pitch: 0.0,
standing_eye_height,
pose: EntityPose::Standing,
}
}

pub fn set_pos(&mut self, x: f64, y: f64, z: f64) {
if self.pos.x != x || self.pos.y != y || self.pos.z != z {
self.pos = Vector3::new(x, y, z);
let i = x.floor() as i32;
let j = y.floor() as i32;
let k = z.floor() as i32;

let block_pos = self.block_pos.0;
if i != block_pos.x || j != block_pos.y || k != block_pos.z {
self.block_pos = WorldPosition(Vector3::new(i, j, k));

if get_section_cord(i) != self.chunk_pos.x
|| get_section_cord(k) != self.chunk_pos.z
{
self.chunk_pos =
Vector2::new(get_section_cord(block_pos.x), get_section_cord(block_pos.z));
}
}
}
}
}
4 changes: 2 additions & 2 deletions pumpkin-protocol/src/client/play/c_play_disconnect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ use serde::Serialize;
#[derive(Serialize)]
#[packet(0x1D)]
pub struct CPlayDisconnect<'a> {
reason: TextComponent<'a>,
reason: &'a TextComponent<'a>,
}

impl<'a> CPlayDisconnect<'a> {
pub fn new(reason: TextComponent<'a>) -> Self {
pub fn new(reason: &'a TextComponent<'a>) -> Self {
Self { reason }
}
}
2 changes: 1 addition & 1 deletion pumpkin/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ impl Client {
}
// So we can also kick on errors, but generally should use Player::kick
ConnectionState::Play => {
self.try_send_packet(&CPlayDisconnect::new(TextComponent::text(reason)))
self.try_send_packet(&CPlayDisconnect::new(&TextComponent::text(reason)))
.unwrap_or_else(|_| self.close());
}
_ => {
Expand Down
96 changes: 70 additions & 26 deletions pumpkin/src/client/player_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,27 @@ impl Player {
Self::clamp_vertical(position.feet_y),
Self::clamp_horizontal(position.z),
);
// TODO: teleport when moving > 8 block

// send new position to all other players
let on_ground = self.on_ground;
entity.on_ground = position.ground;
let on_ground = entity.on_ground;
let entity_id = entity.entity_id;
let (x, y, z) = entity.pos.into();
let (lastx, lasty, lastz) = self.last_position.into();
let world = self.world.clone();
let world = world.lock().await;

// let delta = Vector3::new(x - lastx, y - lasty, z - lastz);
// let velocity = self.velocity;

// // Player is falling down fast, we should account for that
// let max_speed = if self.fall_flying { 300.0 } else { 100.0 };

// teleport when more than 8 blocks (i guess 8 blocks)
// TODO: REPLACE * 2.0 by movement packets. see vanilla for details
// if delta.length_squared() - velocity.length_squared() > max_speed * 2.0 {
// self.teleport(x, y, z, self.entity.yaw, self.entity.pitch);
// return;
// }
// send new position to all other players
world.broadcast_packet(
&[self.client.token],
&CUpdateEntityPos::new(
Expand Down Expand Up @@ -128,11 +140,11 @@ impl Player {
Self::clamp_vertical(position_rotation.feet_y),
Self::clamp_horizontal(position_rotation.z),
);
entity.on_ground = position_rotation.ground;
entity.yaw = wrap_degrees(position_rotation.yaw) % 360.0;
entity.pitch = wrap_degrees(position_rotation.pitch).clamp(-90.0, 90.0) % 360.0;

// send new position to all other players
let on_ground = self.on_ground;
let on_ground = entity.on_ground;
let entity_id = entity.entity_id;
let (x, y, z) = entity.pos.into();
let (lastx, lasty, lastz) = self.last_position.into();
Expand All @@ -142,6 +154,20 @@ impl Player {
let world = self.world.clone();
let world = world.lock().await;

// let delta = Vector3::new(x - lastx, y - lasty, z - lastz);
// let velocity = self.velocity;

// // Player is falling down fast, we should account for that
// let max_speed = if self.fall_flying { 300.0 } else { 100.0 };

// // teleport when more than 8 blocks (i guess 8 blocks)
// // TODO: REPLACE * 2.0 by movement packets. see vanilla for details
// if delta.length_squared() - velocity.length_squared() > max_speed * 2.0 {
// self.teleport(x, y, z, yaw, pitch);
// return;
// }
// send new position to all other players

world.broadcast_packet(
&[self.client.token],
&CUpdateEntityPosRot::new(
Expand All @@ -168,10 +194,11 @@ impl Player {
return;
}
let entity = &mut self.entity;
entity.on_ground = rotation.ground;
entity.yaw = wrap_degrees(rotation.yaw) % 360.0;
entity.pitch = wrap_degrees(rotation.pitch).clamp(-90.0, 90.0) % 360.0;
// send new position to all other players
let on_ground = self.on_ground;
let on_ground = entity.on_ground;
let entity_id = entity.entity_id;
let yaw = modulus(entity.yaw * 256.0 / 360.0, 256.0);
let pitch = modulus(entity.pitch * 256.0 / 360.0, 256.0);
Expand All @@ -191,7 +218,7 @@ impl Player {
}

pub fn handle_player_ground(&mut self, _server: &mut Server, ground: SSetPlayerGround) {
self.on_ground = ground.on_ground;
self.entity.on_ground = ground.on_ground;
}

pub async fn handle_player_command(&mut self, _server: &mut Server, command: SPlayerCommand) {
Expand All @@ -202,30 +229,45 @@ impl Player {
if let Some(action) = Action::from_i32(command.action.0) {
match action {
pumpkin_protocol::server::play::Action::StartSneaking => {
if !self.sneaking {
self.set_sneaking(true).await
if !self.entity.sneaking {
self.entity
.set_sneaking(&mut self.client, self.world.clone(), true)
.await
}
}
pumpkin_protocol::server::play::Action::StopSneaking => {
if self.sneaking {
self.set_sneaking(false).await
if self.entity.sneaking {
self.entity
.set_sneaking(&mut self.client, self.world.clone(), false)
.await
}
}
pumpkin_protocol::server::play::Action::LeaveBed => todo!(),
pumpkin_protocol::server::play::Action::StartSprinting => {
if !self.sprinting {
self.set_sprinting(true).await
if !self.entity.sprinting {
self.entity
.set_sprinting(&mut self.client, self.world.clone(), true)
.await
}
}
pumpkin_protocol::server::play::Action::StopSprinting => {
if self.sprinting {
self.set_sprinting(false).await
if self.entity.sprinting {
self.entity
.set_sprinting(&mut self.client, self.world.clone(), false)
.await
}
}
pumpkin_protocol::server::play::Action::StartHorseJump => todo!(),
pumpkin_protocol::server::play::Action::StopHorseJump => todo!(),
pumpkin_protocol::server::play::Action::OpenVehicleInventory => todo!(),
pumpkin_protocol::server::play::Action::StartFlyingElytra => {} // TODO
pumpkin_protocol::server::play::Action::StartFlyingElytra => {
let fall_flying = self.entity.check_fall_flying();
if self.entity.fall_flying != fall_flying {
self.entity
.set_fall_flying(&mut self.client, self.world.clone(), fall_flying)
.await;
}
} // TODO
}
} else {
self.kick(TextComponent::text("Invalid player command"))
Expand Down Expand Up @@ -320,8 +362,10 @@ impl Player {

pub async fn handle_interact(&mut self, _: &mut Server, interact: SInteract) {
let sneaking = interact.sneaking;
if self.sneaking != sneaking {
self.set_sneaking(sneaking).await;
if self.entity.sneaking != sneaking {
self.entity
.set_sneaking(&mut self.client, self.world.clone(), sneaking)
.await;
}
match ActionType::from_i32(interact.typ.0) {
Some(action) => match action {
Expand All @@ -335,27 +379,27 @@ impl Player {
let attacked_player = world.get_by_entityid(self, entity_id.0 as EntityId);
if let Some(mut player) = attacked_player {
let token = player.client.token;
let velo = player.velocity;
let velo = player.entity.velocity;
if config.protect_creative && player.gamemode == GameMode::Creative {
return;
}
if config.knockback {
let yaw = self.entity.yaw;
let strength = 1.0;
player.knockback(
player.entity.knockback(
strength * 0.5,
(yaw * (PI / 180.0)).sin() as f64,
-(yaw * (PI / 180.0)).cos() as f64,
);
let packet = &CEntityVelocity::new(
&entity_id,
player.velocity.x as f32,
player.velocity.y as f32,
player.velocity.z as f32,
velo.x as f32,
velo.y as f32,
velo.z as f32,
);
self.velocity = self.velocity.multiply(0.6, 1.0, 0.6);
self.entity.velocity = self.entity.velocity.multiply(0.6, 1.0, 0.6);

player.velocity = velo;
player.entity.velocity = velo;
player.client.send_packet(packet);
}
if config.hurt_animation {
Expand Down
Loading

0 comments on commit 2ee9710

Please sign in to comment.