+static void player__post_update(void){
+ if( player_subsystems[ localplayer.subsystem ]->post_update )
+ player_subsystems[ localplayer.subsystem ]->post_update();
+}
+
+/*
+ * Applies gate transport to a player_interface
+ */
+static void player__pass_gate( u32 id ){
+ world_instance *world = world_current_instance();
+
+ /* update boundary hash (network animation) */
+ u16 index = mdl_entity_id_id(id) & ~NETMSG_BOUNDARY_MASK;
+ localplayer.boundary_hash ^= NETMSG_GATE_BOUNDARY_BIT;
+ localplayer.boundary_hash &= ~NETMSG_BOUNDARY_MASK;
+ localplayer.boundary_hash |= index;
+
+ ent_gate *gate = mdl_arritm( &world->ent_gate, mdl_entity_id_id(id) );
+ world_routes_fracture( world, gate, localplayer.rb.co, localplayer.rb.v );
+
+ localplayer.gate_waiting = gate;
+ world_routes_activate_entry_gate( world_current_instance(), gate );
+
+ struct player_cam_controller *cc = &localplayer.cam_control;
+ m4x3_mulv( gate->transport, cc->tpv_lpf, cc->tpv_lpf );
+ m3x3_mulv( gate->transport, cc->cam_velocity_smooth,
+ cc->cam_velocity_smooth );
+ m3x3_copy( localplayer.basis, localplayer.basis_gate );
+
+ v4f q;
+ m3x3_q( gate->transport, q );
+ q_mul( q, localplayer.qbasis, localplayer.qbasis );
+ q_normalize( localplayer.qbasis );
+ q_m3x3( localplayer.qbasis, localplayer.basis );
+ m3x3_transpose( localplayer.basis, localplayer.invbasis );
+
+ m4x3_mulv( gate->transport, localplayer.cam.pos, localplayer.cam.pos );
+
+ if( gate->flags & k_ent_gate_nonlocal )
+ world_set_active_instance( gate->target );
+
+ audio_lock();
+ audio_oneshot( &audio_gate_pass, 1.0f, 0.0f );
+ audio_unlock();
+
+ replay_clear( &skaterift.replay );