Check block distance
This commit is contained in:
parent
268fc19b7b
commit
9d6c8dc524
@ -16,10 +16,12 @@ pub struct Entity {
|
|||||||
pub yaw: f32,
|
pub yaw: f32,
|
||||||
pub head_yaw: f32,
|
pub head_yaw: f32,
|
||||||
pub pitch: f32,
|
pub pitch: f32,
|
||||||
|
// TODO: Change this in diffrent poses
|
||||||
|
pub standing_eye_height: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Entity {
|
impl Entity {
|
||||||
pub fn new(entity_id: EntityId, entity_type: EntityType) -> Self {
|
pub fn new(entity_id: EntityId, entity_type: EntityType, standing_eye_height: f32) -> Self {
|
||||||
Self {
|
Self {
|
||||||
entity_id,
|
entity_id,
|
||||||
entity_type,
|
entity_type,
|
||||||
@ -32,6 +34,7 @@ impl Entity {
|
|||||||
yaw: 0.0,
|
yaw: 0.0,
|
||||||
head_yaw: 0.0,
|
head_yaw: 0.0,
|
||||||
pitch: 0.0,
|
pitch: 0.0,
|
||||||
|
standing_eye_height,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,13 +5,13 @@ use crate::{position::WorldPosition, VarInt};
|
|||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
#[packet(0x09)]
|
#[packet(0x09)]
|
||||||
pub struct CBlockUpdate {
|
pub struct CBlockUpdate<'a> {
|
||||||
location: WorldPosition,
|
location: &'a WorldPosition,
|
||||||
block_id: VarInt,
|
block_id: VarInt,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CBlockUpdate {
|
impl<'a> CBlockUpdate<'a> {
|
||||||
pub fn new(location: WorldPosition, block_id: VarInt) -> Self {
|
pub fn new(location: &'a WorldPosition, block_id: VarInt) -> Self {
|
||||||
Self { location, block_id }
|
Self { location, block_id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -329,6 +329,10 @@ impl Player {
|
|||||||
pub fn handle_player_action(&mut self, server: &mut Server, player_action: SPlayerAction) {
|
pub fn handle_player_action(&mut self, server: &mut Server, player_action: SPlayerAction) {
|
||||||
match Status::from_i32(player_action.status.0).unwrap() {
|
match Status::from_i32(player_action.status.0).unwrap() {
|
||||||
Status::StartedDigging => {
|
Status::StartedDigging => {
|
||||||
|
if !self.can_interact_with_block_at(&player_action.location, 1.0) {
|
||||||
|
// TODO: maybe log?
|
||||||
|
return;
|
||||||
|
}
|
||||||
// TODO: do validation
|
// TODO: do validation
|
||||||
// TODO: Config
|
// TODO: Config
|
||||||
if self.gamemode == GameMode::Creative {
|
if self.gamemode == GameMode::Creative {
|
||||||
@ -337,20 +341,28 @@ impl Player {
|
|||||||
// TODO: currently this is always dirt replace it
|
// TODO: currently this is always dirt replace it
|
||||||
server.broadcast_packet(self, &CWorldEvent::new(2001, &location, 11, false));
|
server.broadcast_packet(self, &CWorldEvent::new(2001, &location, 11, false));
|
||||||
// AIR
|
// AIR
|
||||||
server.broadcast_packet(self, &CBlockUpdate::new(location, 0.into()));
|
server.broadcast_packet(self, &CBlockUpdate::new(&location, 0.into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status::CancelledDigging => {
|
Status::CancelledDigging => {
|
||||||
|
if !self.can_interact_with_block_at(&player_action.location, 1.0) {
|
||||||
|
// TODO: maybe log?
|
||||||
|
return;
|
||||||
|
}
|
||||||
self.current_block_destroy_stage = 0;
|
self.current_block_destroy_stage = 0;
|
||||||
}
|
}
|
||||||
Status::FinishedDigging => {
|
Status::FinishedDigging => {
|
||||||
// TODO: do validation
|
// TODO: do validation
|
||||||
let location = player_action.location;
|
let location = player_action.location;
|
||||||
|
if !self.can_interact_with_block_at(&location, 1.0) {
|
||||||
|
// TODO: maybe log?
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Block break & block break sound
|
// Block break & block break sound
|
||||||
// TODO: currently this is always dirt replace it
|
// TODO: currently this is always dirt replace it
|
||||||
server.broadcast_packet(self, &CWorldEvent::new(2001, &location, 11, false));
|
server.broadcast_packet(self, &CWorldEvent::new(2001, &location, 11, false));
|
||||||
// AIR
|
// AIR
|
||||||
server.broadcast_packet(self, &CBlockUpdate::new(location, 0.into()));
|
server.broadcast_packet(self, &CBlockUpdate::new(&location, 0.into()));
|
||||||
// TODO: Send this every tick
|
// TODO: Send this every tick
|
||||||
self.client
|
self.client
|
||||||
.send_packet(&CAcknowledgeBlockChange::new(player_action.sequence));
|
.send_packet(&CAcknowledgeBlockChange::new(player_action.sequence));
|
||||||
@ -376,12 +388,14 @@ impl Player {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_use_item_on(&mut self, server: &mut Server, use_item_on: SUseItemOn) {
|
pub fn handle_use_item_on(&mut self, server: &mut Server, use_item_on: SUseItemOn) {
|
||||||
self.client
|
|
||||||
.send_packet(&CAcknowledgeBlockChange::new(use_item_on.sequence));
|
|
||||||
|
|
||||||
let location = use_item_on.location;
|
let location = use_item_on.location;
|
||||||
|
|
||||||
|
if !self.can_interact_with_block_at(&location, 1.0) {
|
||||||
|
// TODO: maybe log?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let face = BlockFace::from_i32(use_item_on.face.0).unwrap();
|
let face = BlockFace::from_i32(use_item_on.face.0).unwrap();
|
||||||
let location = WorldPosition(location.0 + face.to_offset());
|
|
||||||
if let Some(item) = self.inventory.held_item() {
|
if let Some(item) = self.inventory.held_item() {
|
||||||
let minecraft_id =
|
let minecraft_id =
|
||||||
global_registry::find_minecraft_id(global_registry::ITEM_REGISTRY, item.item_id)
|
global_registry::find_minecraft_id(global_registry::ITEM_REGISTRY, item.item_id)
|
||||||
@ -394,10 +408,19 @@ impl Player {
|
|||||||
{
|
{
|
||||||
server.broadcast_packet(
|
server.broadcast_packet(
|
||||||
self,
|
self,
|
||||||
&CBlockUpdate::new(location, (block_state_id as i32).into()),
|
&CBlockUpdate::new(&location, (block_state_id as i32).into()),
|
||||||
|
);
|
||||||
|
server.broadcast_packet(
|
||||||
|
self,
|
||||||
|
&CBlockUpdate::new(
|
||||||
|
&WorldPosition(location.0 + face.to_offset()),
|
||||||
|
(block_state_id as i32).into(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.client
|
||||||
|
.send_packet(&CAcknowledgeBlockChange::new(use_item_on.sequence));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_set_held_item(&mut self, _server: &mut Server, held: SSetHeldItem) {
|
pub fn handle_set_held_item(&mut self, _server: &mut Server, held: SSetHeldItem) {
|
||||||
|
|||||||
@ -11,6 +11,7 @@ use pumpkin_protocol::{
|
|||||||
CGameEvent, CPlayDisconnect, CPlayerInfoUpdate, CSyncPlayerPosition, CSystemChatMessage,
|
CGameEvent, CPlayDisconnect, CPlayerInfoUpdate, CSyncPlayerPosition, CSystemChatMessage,
|
||||||
PlayerAction,
|
PlayerAction,
|
||||||
},
|
},
|
||||||
|
position::WorldPosition,
|
||||||
server::play::{
|
server::play::{
|
||||||
SChatCommand, SChatMessage, SClientInformationPlay, SConfirmTeleport, SInteract,
|
SChatCommand, SChatMessage, SClientInformationPlay, SConfirmTeleport, SInteract,
|
||||||
SPlayPingRequest, SPlayerAction, SPlayerCommand, SPlayerPosition, SPlayerPositionRotation,
|
SPlayPingRequest, SPlayerAction, SPlayerCommand, SPlayerPosition, SPlayerPositionRotation,
|
||||||
@ -21,7 +22,7 @@ use pumpkin_protocol::{
|
|||||||
use pumpkin_world::vector3::Vector3;
|
use pumpkin_world::vector3::Vector3;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{client::Client, server::Server};
|
use crate::{client::Client, server::Server, util::boundingbox::BoundingBox};
|
||||||
|
|
||||||
pub struct Player {
|
pub struct Player {
|
||||||
pub client: Client,
|
pub client: Client,
|
||||||
@ -55,7 +56,7 @@ impl Player {
|
|||||||
pub fn new(client: Client, entity_id: EntityId, gamemode: GameMode) -> Self {
|
pub fn new(client: Client, entity_id: EntityId, gamemode: GameMode) -> Self {
|
||||||
Self {
|
Self {
|
||||||
client,
|
client,
|
||||||
entity: Entity::new(entity_id, EntityType::Player),
|
entity: Entity::new(entity_id, EntityType::Player, 1.62),
|
||||||
on_ground: false,
|
on_ground: false,
|
||||||
awaiting_teleport: None,
|
awaiting_teleport: None,
|
||||||
sneaking: false,
|
sneaking: false,
|
||||||
@ -125,6 +126,24 @@ impl Player {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn block_interaction_range(&self) -> f64 {
|
||||||
|
if self.gamemode == GameMode::Creative {
|
||||||
|
5.0
|
||||||
|
} else {
|
||||||
|
4.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn can_interact_with_block_at(&self, pos: &WorldPosition, additional_range: f64) -> bool {
|
||||||
|
let d = self.block_interaction_range() + additional_range;
|
||||||
|
let box_pos = BoundingBox::from_block(pos);
|
||||||
|
box_pos.squared_magnitude(Vector3 {
|
||||||
|
x: self.entity.x,
|
||||||
|
y: self.entity.y + self.entity.standing_eye_height as f64,
|
||||||
|
z: self.entity.z,
|
||||||
|
}) < d * d
|
||||||
|
}
|
||||||
|
|
||||||
/// Kicks the Client with a reason depending on the connection state
|
/// Kicks the Client with a reason depending on the connection state
|
||||||
pub fn kick(&mut self, reason: TextComponent) {
|
pub fn kick(&mut self, reason: TextComponent) {
|
||||||
assert!(self.client.connection_state == ConnectionState::Play);
|
assert!(self.client.connection_state == ConnectionState::Play);
|
||||||
|
|||||||
43
pumpkin/src/util/boundingbox.rs
Normal file
43
pumpkin/src/util/boundingbox.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
use pumpkin_protocol::position::WorldPosition;
|
||||||
|
use pumpkin_world::vector3::Vector3;
|
||||||
|
|
||||||
|
pub struct BoundingBox {
|
||||||
|
pub min_x: f64,
|
||||||
|
pub min_y: f64,
|
||||||
|
pub min_z: f64,
|
||||||
|
pub max_x: f64,
|
||||||
|
pub max_y: f64,
|
||||||
|
pub max_z: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BoundingBox {
|
||||||
|
pub fn new(min_x: f64, min_y: f64, min_z: f64, max_x: f64, max_y: f64, max_z: f64) -> Self {
|
||||||
|
Self {
|
||||||
|
min_x,
|
||||||
|
min_y,
|
||||||
|
min_z,
|
||||||
|
max_x,
|
||||||
|
max_y,
|
||||||
|
max_z,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_block(position: &WorldPosition) -> Self {
|
||||||
|
let position = position.0;
|
||||||
|
Self {
|
||||||
|
min_x: position.x as f64,
|
||||||
|
min_y: position.y as f64,
|
||||||
|
min_z: position.z as f64,
|
||||||
|
max_x: (position.x as f64) + 1.0,
|
||||||
|
max_y: (position.y as f64) + 1.0,
|
||||||
|
max_z: (position.z as f64) + 1.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn squared_magnitude(&self, pos: Vector3<f64>) -> f64 {
|
||||||
|
let d = f64::max(f64::max(self.min_x - pos.x, pos.x - self.max_x), 0.0);
|
||||||
|
let e = f64::max(f64::max(self.min_y - pos.y, pos.y - self.max_y), 0.0);
|
||||||
|
let f = f64::max(f64::max(self.min_z - pos.z, pos.z - self.max_z), 0.0);
|
||||||
|
super::math::squared_magnitude(d, e, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -10,3 +10,7 @@ pub fn wrap_degrees(var: f32) -> f32 {
|
|||||||
|
|
||||||
var1
|
var1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn squared_magnitude(a: f64, b: f64, c: f64) -> f64 {
|
||||||
|
a * a + b * b + c * c
|
||||||
|
}
|
||||||
|
|||||||
@ -1 +1,2 @@
|
|||||||
|
pub mod boundingbox;
|
||||||
pub mod math;
|
pub mod math;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user