Theme

alex/beta-minecraft-rust

Minecraft Beta 1.7.3 Rewrite

BRANCH main
main
SNAPSHOT Draw terrain GPU-driven from packed per-section buffers with GPU occlusion culling, add a render distance slider (2-128) with a quad/disk shape, cut chunk bookkeeping at high render distances, and fix a light underflow at y=0
DOWNLOAD
Download file

root / crates / server / src / player / travel.rs

//! `ServerConfigurationManager.sendPlayerToOtherDimension` and respawning out of the Nether.

use common::protocol::Packet;
use glam::DVec3;

use super::ServerPlayer;
use crate::level::Level;

/// Why a player leaves its dimension at the end of the tick.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Departure {
    Portal,
    /// Death outside the Overworld respawns in it.
    Respawn,
}

impl ServerPlayer {
    /// Where the player leaves to, if anywhere: the other side of a portal or the Overworld.
    pub fn destination(&self, dimension: i8) -> Option<i8> {
        match self.departure? {
            Departure::Portal if dimension != -1 => Some(-1),
            Departure::Portal | Departure::Respawn => Some(0),
        }
    }

    /// Moves the player entity from one level into the other.
    pub fn change_dimension(&mut self, from: &mut Level, to: &mut Level) {
        let Some(departure) = self.departure.take() else {
            return;
        };
        self.flush_stats(from);
        from.statistics.remove(&self.entity_id);
        let Some(mut stored) = from.entities.remove(self.entity_id) else {
            return;
        };
        self.sent_chunks.clear();
        self.stream = Default::default();
        self.tracked.clear();
        if departure == Departure::Respawn {
            to.entities.insert(stored);
            self.respawn(to);
            return;
        }
        if !to.has_sky() {
            to.weather = crate::Server::nether_weather(&from.weather);
        }
        self.send(Packet::Respawn {
            dimension: to.dimension(),
        });
        // Remote clients recreate their player at full health
        self.health_sent = i32::MIN;
        let entity = &mut stored.entity;
        let scale = if to.dimension() == -1 { 1.0 / 8.0 } else { 8.0 };
        let pos = DVec3::new(entity.pos.x * scale, entity.pos.y, entity.pos.z * scale);
        entity.set_location_and_angles(pos, entity.yaw, entity.pitch);
        crate::blocks::portal::place_in_portal(to, entity);
        let (pos, yaw, pitch) = (entity.pos, entity.yaw, entity.pitch);
        to.entities.insert(stored);
        self.teleport(to, pos, yaw, pitch);
        self.send(Packet::UpdateTime { time: to.time });
        self.send_weather(to, false);
        self.sync_container(to);
    }
}