steel_core/player/lifecycle/
world_transition.rs1use super::*;
2
3impl Player {
4 fn apply_post_teleport_transition(&self, post_transition: &TeleportPostTransition) {
5 for action in post_transition.actions() {
6 match *action {
7 TeleportPostAction::PlayPortalSound => {
8 self.send_packet(CLevelEvent::new(
9 level_events::SOUND_PORTAL_TRAVEL,
10 BlockPos::ZERO,
11 0,
12 false,
13 ));
14 }
15 TeleportPostAction::PlacePortalTicket(target) => {
16 let ticket_position = match target {
17 PortalTicketTarget::Destination => BlockPos::from(self.position()),
18 PortalTicketTarget::Block(pos) => pos,
19 };
20 self.get_world().place_portal_ticket(ticket_position);
21 }
22 }
23 }
24 }
25
26 pub(crate) fn change_world_within_domain(
29 self: &Arc<Self>,
30 teleport_transition: &TeleportTransition,
31 ) -> bool {
32 let current_world = self.get_world();
33 let new_world = Arc::clone(&teleport_transition.target_world);
34 if current_world.domain() != new_world.domain() {
35 tracing::error!(
36 entity_id = self.id(),
37 source_domain = current_world.domain(),
38 target_domain = new_world.domain(),
39 "Refusing player world change outside the domain-switch workflow"
40 );
41 return false;
42 }
43
44 let current_position = self.position();
45 let current_rotation = self.rotation();
46 let current_velocity = self.velocity();
47 let position = teleport_transition.resolved_position(current_position);
48 let rotation = teleport_transition.resolved_rotation(current_rotation);
49 let velocity =
50 teleport_transition.resolved_velocity(current_velocity, current_rotation, rotation);
51 self.set_portal_cooldown(teleport_transition.portal_cooldown);
52 if !teleport_transition.as_passenger {
53 self.stop_riding();
54 }
55 if Arc::ptr_eq(¤t_world, &new_world) {
56 if let Err(error) = self.teleport_with_velocity_packet(
57 position,
58 velocity,
59 rotation,
60 teleport_transition.position,
61 teleport_transition.velocity,
62 teleport_transition.rotation,
63 teleport_transition.relatives,
64 ) {
65 panic!(
66 "failed to commit same-world portal teleport for player {}: {error}",
67 self.id()
68 );
69 }
70 self.reset_flying_ticks();
71 } else {
72 self.reset(new_world, ResetReason::WorldChange);
73 if !self.spawn_with_velocity_packet(
74 position,
75 rotation,
76 velocity,
77 ResetReason::WorldChange,
78 teleport_transition.position,
79 teleport_transition.rotation,
80 teleport_transition.velocity,
81 teleport_transition.relatives,
82 ) {
83 return false;
84 }
85 self.send_inventory_to_remote();
87 }
88 self.apply_post_teleport_transition(&teleport_transition.post_transition);
89 true
90 }
91}