Skip to main content

basalt_api/events/
player.rs

1//! Player lifecycle and movement events.
2
3use crate::components::{ChunkPosition, Position, Rotation};
4
5/// A player moved or changed look direction.
6///
7/// Fired after the position is updated. Not cancellable — the server
8/// is not authoritative for position in vanilla Minecraft.
9/// The moving player is available via `ctx.player()`.
10#[derive(Debug, Clone)]
11pub struct PlayerMovedEvent {
12    /// New absolute position.
13    pub position: Position,
14    /// New facing direction.
15    pub rotation: Rotation,
16    /// Whether the player is on the ground.
17    pub on_ground: bool,
18    /// Chunk position before the movement (for boundary detection).
19    pub old_chunk: ChunkPosition,
20}
21crate::game_event!(PlayerMovedEvent);
22
23/// A new player has joined the server.
24///
25/// Not cancellable — the player is already connected. The joining
26/// player's identity is available via `ctx.player()`.
27#[derive(Debug, Clone)]
28pub struct PlayerJoinedEvent;
29crate::game_event!(PlayerJoinedEvent);
30
31/// A player has disconnected from the server.
32///
33/// Not cancellable — the connection is already closed. The leaving
34/// player's identity is available via `ctx.player()`.
35#[derive(Debug, Clone)]
36pub struct PlayerLeftEvent;
37crate::game_event!(PlayerLeftEvent);
38
39#[cfg(test)]
40mod tests {
41    use crate::events::Event;
42
43    use super::*;
44
45    #[test]
46    fn player_moved_not_cancellable() {
47        let mut event = PlayerMovedEvent {
48            position: Position {
49                x: 0.0,
50                y: 64.0,
51                z: 0.0,
52            },
53            rotation: Rotation {
54                yaw: 0.0,
55                pitch: 0.0,
56            },
57            on_ground: true,
58            old_chunk: ChunkPosition { x: 0, z: 0 },
59        };
60        event.cancel(); // no-op
61        assert!(!event.is_cancelled());
62    }
63
64    #[test]
65    fn event_routing() {
66        use crate::events::{BusKind, EventRouting};
67        assert_eq!(PlayerMovedEvent::BUS, BusKind::Game);
68        assert_eq!(PlayerJoinedEvent::BUS, BusKind::Game);
69        assert_eq!(PlayerLeftEvent::BUS, BusKind::Game);
70    }
71}