use anyhow::Result; use mcproto_rs::types::Vec3; use mcproto_rs::v1_19_3::{Packet761, SetCenterChunkSpec, SynchronizePlayerPositionSpec}; use crate::connect::MinecraftClient; use crate::world::World; pub struct Player { pub client: MinecraftClient, pub name: String, pub position: Vec3, pub yaw: f32, pub pitch: f32, last_center_chunk: Option<(i32, i32)>, } impl Player { pub fn new(client: MinecraftClient, name: String, position: Vec3, yaw: f32, pitch: f32) -> Player { Player { client, name, position, yaw, pitch, last_center_chunk: None, } } pub fn create_teleport_packet(&self) -> Packet761 { Packet761::SynchronizePlayerPosition(SynchronizePlayerPositionSpec { position: self.position.clone(), yaw: self.yaw, pitch: self.pitch, flags: Default::default(), teleport_id: 0.into(), // TODO: teleport id ack dismount_vehicle: false, }) } pub async fn teleport(&mut self, position: Vec3, yaw: f32, pitch: f32) -> Result<()> { self.position = position; self.yaw = yaw; self.pitch = pitch; self.send_packet(self.create_teleport_packet())?; Ok(()) } pub fn chunk_x(&self) -> i32 { self.position.x.ceil() as i32 / 16 } pub fn chunk_z(&self) -> i32 { self.position.z.ceil() as i32 / 16 } pub fn synchronize_center_chunk(&mut self) -> Result<()> { let cx = self.chunk_x(); let cz = self.chunk_z(); let tup = Some((cx, cz)); if self.last_center_chunk != tup { self.last_center_chunk = tup; self.send_packet(Packet761::SetCenterChunk(SetCenterChunkSpec { chunk_x: cx.into(), chunk_z: cz.into(), }))?; } Ok(()) } pub async fn send_all_nearby_chunks(&self, world: &(dyn World + Sync + Send)) -> Result<()> { // TODO: proper chunk observing for x_off in -7..7 { for z_off in -7..7 { world.send_chunk(&self, self.chunk_x() + x_off, self.chunk_z() + z_off).await?; } } Ok(()) } pub fn send_packet(&self, packet: Packet761) -> Result<()> { self.client.send_packet(packet) } pub fn send_all_packets(&self, packets: Vec) -> Result<(), anyhow::Error> { self.client.send_all_packets(packets) } }