/// <summary> /// Sends a message to the antag player and tells it to start the antag banner animation. /// </summary> /// <param name="player">Who</param> /// <param name="antag">What antag data</param> private static void ShowAntagBanner(ConnectedPlayer player, Antagonist antag) { SpawnBannerMessage.Send( player.GameObject, antag.AntagName, antag.SpawnSound.AssetAddress, antag.TextColor, antag.BackgroundColor, antag.PlaySound); }
/// <summary> /// Spawns a new player character and transfers the connection's control into the new body. /// If existingMind is null, creates the new mind and assigns it to the new body. /// /// Fires server and client side player spawn hooks. /// </summary> /// <param name="connection">connection to give control to the new player character</param> /// <param name="occupation">occupation of the new player character</param> /// <param name="characterSettings">settings of the new player character</param> /// <param name="existingMind">existing mind to transfer to the new player, if null new mind will be created /// and assigned to the new player character</param> /// <param name="spawnPos">world position to spawn at</param> /// <param name="spawnItems">If spawning a player, should the player spawn without the defined initial equipment for their occupation?</param> /// <param name="willDestroyOldBody">if true, indicates the old body is going to be destroyed rather than pooled, /// thus we shouldn't send any network message which reference's the old body's ID since it won't exist.</param> /// /// <returns>the spawned object</returns> private static GameObject ServerSpawnInternal(NetworkConnection connection, Occupation occupation, CharacterSettings characterSettings, Mind existingMind, Vector3Int?spawnPos = null, bool spawnItems = true, bool willDestroyOldBody = false, bool showBanner = true) { //determine where to spawn them if (spawnPos == null) { Transform spawnTransform; //Spawn normal location for special jobs or if less than 2 minutes passed if (GameManager.Instance.stationTime < ARRIVALS_SPAWN_TIME || occupation.LateSpawnIsArrivals == false) { spawnTransform = SpawnPoint.GetRandomPointForJob(occupation.JobType); } else { spawnTransform = SpawnPoint.GetRandomPointForLateSpawn(); //Fallback to assistant spawn location if none found for late join if (spawnTransform == null && occupation.JobType != JobType.NULL) { spawnTransform = SpawnPoint.GetRandomPointForJob(JobType.ASSISTANT); } } if (spawnTransform == null) { Logger.LogErrorFormat( "Unable to determine spawn position for connection {0} occupation {1}. Cannot spawn player.", Category.EntitySpawn, connection.address, occupation.DisplayName); return(null); } spawnPos = spawnTransform.transform.position.CutToInt(); } //create the player object var newPlayer = ServerCreatePlayer(spawnPos.GetValueOrDefault()); var newPlayerScript = newPlayer.GetComponent <PlayerScript>(); //get the old body if they have one. var oldBody = existingMind?.GetCurrentMob(); //transfer control to the player object ServerTransferPlayer(connection, newPlayer, oldBody, EVENT.PlayerSpawned, characterSettings, willDestroyOldBody); if (existingMind == null) { //create the mind of the player Mind.Create(newPlayer, occupation); } else { //transfer the mind to the new body existingMind.SetNewBody(newPlayerScript); } var ps = newPlayer.GetComponent <PlayerScript>(); var connectedPlayer = PlayerList.Instance.Get(connection); connectedPlayer.Name = ps.playerName; connectedPlayer.Job = ps.mind.occupation.JobType; UpdateConnectedPlayersMessage.Send(); //fire all hooks var info = SpawnInfo.Player(occupation, characterSettings, CustomNetworkManager.Instance.humanPlayerPrefab, SpawnDestination.At(spawnPos), spawnItems: spawnItems); Spawn._ServerFireClientServerSpawnHooks(SpawnResult.Single(info, newPlayer)); if (occupation != null && showBanner) { SpawnBannerMessage.Send( newPlayer, occupation.DisplayName, occupation.SpawnSound.AssetAddress, occupation.TextColor, occupation.BackgroundColor, occupation.PlaySound); } return(newPlayer); }