summaryrefslogtreecommitdiff
path: root/src/player.rs
blob: e63c8a4083bcf4c983426f13ac0a4234cea58e69 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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<f64>,
    pub yaw: f32,
    pub pitch: f32,
    last_center_chunk: Option<(i32, i32)>,

}


impl Player {
    pub fn new(client: MinecraftClient, name: String, position: Vec3<f64>, 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<f64>, 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<Packet761>) -> Result<(), anyhow::Error> {
        self.client.send_all_packets(packets)
    }
}