things/player/Player.Lobby.cs

Player partial class, lobby-specific logic. It syncs lobby state and look offset, positions the player at a lobby slot, updates look direction smoothing, controls animation helper state, and handles EnterLobby RPC to set camera and player properties.

Networking
using Sandbox;
using Sandbox.Citizen;
using Sandbox.Diagnostics;
using System;

public partial class Player
{
	[Sync( SyncFlags.FromHost )] public int LobbySlotIndex { get; set; } = -1;
	[Sync] public Vector2 LobbyLookMouseOffset { get; set; }
	[Sync] public bool IsInLobby { get; set; }
	private Vector2 _displayLobbyLookMouseOffset;

	public void UpdateLobby()
	{
		//Gizmo.Draw.Color = Color.White;
		//Gizmo.Draw.Text( $"IsNoclipping: {AnimationHelper.IsNoclipping}", new global::Transform( WorldPosition + Vector3.Up * 10f ) );

		var container = Manager.Instance.CameraContainer;
		var cameraPos = container.WorldPosition;

		var associatedSlot = Scene.GetAllComponents<LobbyPlayerSlot>().FirstOrDefault( x => x.SlotIndex == LobbySlotIndex );
		if ( associatedSlot != null )
		{
			WorldPosition = associatedSlot.WorldPosition;
			var yaw = Rotation.LookAt( cameraPos - WorldPosition, Vector3.Up ).Yaw();
			Model.LocalRotation = new Angles( 0f, yaw, 0f );
		}

		if ( IsProxy )
		{
			if ( _displayLobbyLookMouseOffset.LengthSquared <= 0.0001f )
				_displayLobbyLookMouseOffset = LobbyLookMouseOffset;

			_displayLobbyLookMouseOffset = Vector2.Lerp( _displayLobbyLookMouseOffset, LobbyLookMouseOffset, RealTime.Delta * 16f );
		}
		else
		{
			_displayLobbyLookMouseOffset = LobbyLookMouseOffset;
		}

		var lookPos = cameraPos + new Vector3( 0f, -_displayLobbyLookMouseOffset.x, _displayLobbyLookMouseOffset.y ) * 200f;
		AnimationHelper.WithLook( lookPos - (WorldPosition + Vector3.Up * 60f) );

		AnimationHelper.IsNoclipping = false;
		AnimationHelper.WithVelocity( Vector3.Zero );
		AnimationHelper.WithWishVelocity( Vector3.Zero );
		AnimationHelper.Target.Set( "scale_height", 1f ); // not sure why this is necessary, but when game first starts the player has 1.2 height in lobby

		if ( IsProxy )
			return;

		LobbyLookMouseOffset = new Vector2(Utils.Map(Mouse.Position.x, 0f, Screen.Width, -1f, 1f), Utils.Map( Mouse.Position.y, 0f, Screen.Height, 1f, -1f ) );
		_displayLobbyLookMouseOffset = LobbyLookMouseOffset;
	}

	[Rpc.Broadcast( NetFlags.Reliable )]
	public void EnterLobby()
	{
		IsInLobby = true;

		var container = Manager.Instance.CameraContainer;
		container.WorldPosition = Manager.LOBBY_CAMERA_POS;
		container.WorldRotation = new Angles( 0f, 0f, 0f );

		PhysicalCollider.Enabled = true;

		AnimationHelper.HoldType = CitizenAnimationHelper.HoldTypes.Shotgun;
		AnimationHelper.IsNoclipping = false;
		AnimationHelper.IsGrounded = true;
		SetGunVisible( true );

		//if ( IsProxy )
		//	return;

		//SetLobbyHoldType( GetRandomLobbyHoldType() );
	}

	//public CitizenAnimationHelper.HoldTypes GetRandomLobbyHoldType()
	//{
	//	return CitizenAnimationHelper.HoldTypes.Shotgun;
	//}

	//[Rpc.Broadcast(NetFlags.Reliable)]
	//public void SetLobbyHoldType( CitizenAnimationHelper.HoldTypes holdType)
	//{
	//	AnimationHelper.HoldType = holdType;
	//}
}