示例#1
0
    private static bool ValidateCharacter(PlayerSpawnRequest request)
    {
        var isOk    = true;
        var message = "";

        //Disable this until we fix skin tone checks.

        /*
         * if(ServerValidations.HasIllegalSkinTone(request.CharacterSettings))
         * {
         *      message += " Invalid player skin tone.";
         *      isOk = false;
         * }
         *
         *
         * if(ServerValidations.HasIllegalCharacterName(request.CharacterSettings.Name))
         * {
         *      message += " Invalid player character name.";
         *      isOk = false;
         * }
         */
        if (ServerValidations.HasIllegalCharacterAge(request.CharacterSettings.Age))
        {
            message += " Invalid character age.";
            isOk     = false;
        }

        if (isOk == false)
        {
            message += " Please change and resave character.";
            ValidateFail(request.JoinedViewer, request.UserID, message);
        }

        return(isOk);
    }
示例#2
0
        /// <summary>
        /// This method is invoked when the event is fired
        /// </summary>
        /// <param name="data"> the network data object</param>
        private void PlayerSpawnRequestListener(NetworkData data)
        {
            try
            {
                PlayerSpawnRequest playerSpawnRequest = data as PlayerSpawnRequest;

                if (playerSpawnRequest == null)
                {
                    return;
                }

                Player ply;
                if (m_network.clientList.ContainsKey(playerSpawnRequest.Sender))
                {
                    ply = m_network.clientList[playerSpawnRequest.Sender].Player;
                }
                else
                {
                    return;
                }

                Console.WriteLine(ply.Name + " spawned (" + ply.SteamId + ") ");
                MessageAllClients(ply.Name + " has spawned!", false, false);
            }
            catch (Exception ex)
            {
                Console.WriteLine("[ERROR] Hellion Extended Server[SpawnRequest]:" + ex.InnerException.ToString());
            }
        }
示例#3
0
        public override GameObject ServerSpawn(PlayerSpawnRequest spawnRequest)
        {
            var newPlayer = PlayerSpawn.ServerSpawnPlayer(spawnRequest.JoinedViewer, AntagOccupation,
                                                          spawnRequest.CharacterSettings);

            return(newPlayer);
        }
示例#4
0
    private void CmdRequestJob(JobType jobType, string jsonCharSettings)
    {
        var characterSettings = JsonConvert.DeserializeObject <CharacterSettings>(jsonCharSettings);

        if (GameManager.Instance.CurrentRoundState != RoundState.Started)
        {
            Logger.LogWarningFormat("Round hasn't started yet, can't request job {0} for {1}", Category.Jobs, jobType, characterSettings);
            return;
        }

        int slotsTaken = GameManager.Instance.GetOccupationsCount(jobType);
        int slotsMax   = GameManager.Instance.GetOccupationMaxCount(jobType);

        if (slotsTaken >= slotsMax)
        {
            return;
        }

        var spawnRequest =
            PlayerSpawnRequest.RequestOccupation(this, GameManager.Instance.GetRandomFreeOccupation(jobType), characterSettings);

        GameManager.Instance.SpawnPlayerRequestQueue.Enqueue(spawnRequest);

        GameManager.Instance.ProcessSpawnPlayerQueue();
    }
示例#5
0
    /// <summary>
    /// Check if the joined viewer should be spawned as an antag (prior to actually
    /// spawning them).
    /// Only called for mid-round joiners.
    /// </summary>
    /// <param name="spawnRequest">player's spawn request, which should be used to determine
    /// if they should spawn as an antag</param>
    /// <returns>true if an antag should be spawned.</returns>
    protected virtual bool ShouldSpawnAntag(PlayerSpawnRequest spawnRequest)
    {
        // Does this game mode support mid-round antags?
        if (!MidRoundAntags)
        {
            return(false);
        }

        // Can this job be an antag?
        if (NonAntagJobTypes.Contains(spawnRequest.RequestedOccupation.JobType))
        {
            return(false);
        }

        // Has this player enabled any of the possible antags?
        if (!HasPossibleAntagEnabled(ref spawnRequest.CharacterSettings.AntagPreferences))
        {
            return(false);
        }

        // Are there enough antags already?
        int newPlayerCount     = PlayerList.Instance.InGamePlayers.Count + 1;
        var expectedAntagCount = (int)Math.Floor(newPlayerCount * AntagRatio);

        return(AntagManager.Instance.AntagCount < expectedAntagCount);
    }
        public bool Initiate(TestRunSO TestRunSO)
        {
            CharacterSettings characterSettings;

            if (string.IsNullOrEmpty(SerialisedCharacterSettings))
            {
                characterSettings = new CharacterSettings();
            }
            else
            {
                characterSettings = JsonConvert.DeserializeObject <CharacterSettings>(SerialisedCharacterSettings);
            }

            var Connectedplayer = PlayerList.Instance.Get(PlayerManager.LocalPlayer);

            var Request = PlayerSpawnRequest.RequestOccupation(PlayerManager.LocalViewerScript, Occupation, characterSettings,
                                                               Connectedplayer.UserId);


            PlayerSpawn.ServerSpawnPlayer(Request, PlayerManager.LocalViewerScript, Occupation, characterSettings,
                                          spawnPos: PositionToSpawn.RoundToInt(), existingMind: PlayerManager.LocalPlayerScript.mind,
                                          conn: Connectedplayer.Connection);

            return(true);
        }
示例#7
0
    /// <summary>
    /// Spawn the player requesting the spawn as an antag, includes creating their player object
    /// and transferring them to it. This is used as an alternative
    /// to PlayerSpawn.ServerSpawnPlayer when an antag should be spawned.
    ///
    /// Defaults to picking a random antag from the possible antags list and
    /// spawning them as per the antag-specific spawn logic.
    /// </summary>
    protected void SpawnAntag(PlayerSpawnRequest playerSpawnRequest)
    {
        if (PossibleAntags.Count <= 0)
        {
            Logger.LogError("PossibleAntags is empty! Game mode must have some if spawning antags.",
                            Category.GameMode);
            return;
        }

        var antagPool = PossibleAntags.Where(a =>
                                             HasAntagEnabled(ref playerSpawnRequest.CharacterSettings.AntagPreferences, a)).ToList();

        if (antagPool.Count < 1)
        {
            Logger.LogErrorFormat("No possible antags! Either PossibleAntags is empty or this player hasn't enabled " +
                                  "any antags and they were spawned as one anyways.", Category.GameMode);
        }

        var antag = antagPool.PickRandom();

        if (!AllocateJobsToAntags && antag.AntagOccupation == null)
        {
            Logger.LogErrorFormat("AllocateJobsToAntags is false but {0} AntagOccupation is null! " +
                                  "Game mode must either set AllocateJobsToAntags or possible antags neeed an AntagOccupation.",
                                  Category.GameMode, antag.AntagName);
            return;
        }
        AntagManager.Instance.ServerSpawnAntag(antag, playerSpawnRequest);
    }
示例#8
0
 protected override bool ShouldSpawnAntag(PlayerSpawnRequest spawnRequest)
 {
     // Populates traitors based on the ratio set
     return(!LoyalImplanted.Contains(spawnRequest.RequestedOccupation.JobType) &&
            AntagManager.Instance.AntagCount <= Math.Floor(PlayerList.Instance.InGamePlayers.Count * TraitorRatio) &&
            PlayerList.Instance.InGamePlayers.Count > 0);
 }
    private void CmdRequestJob(JobType jobType, string jsonCharSettings)
    {
        var characterSettings = JsonConvert.DeserializeObject <CharacterSettings>(jsonCharSettings);

        if (GameManager.Instance.CurrentRoundState != RoundState.Started)
        {
            Logger.LogWarningFormat("Round hasn't started yet, can't request job {0} for {1}", Category.Jobs, jobType, characterSettings);
            return;
        }

        int slotsTaken = GameManager.Instance.GetOccupationsCount(jobType);
        int slotsMax   = GameManager.Instance.GetOccupationMaxCount(jobType);

        if (slotsTaken >= slotsMax)
        {
            return;
        }

        var spawnRequest =
            PlayerSpawnRequest.RequestOccupation(this, GameManager.Instance.GetRandomFreeOccupation(jobType), characterSettings);

        //regardless of their chosen occupation, they might spawn as an antag instead.
        //If they do, bypass the normal spawn logic.
        if (GameManager.Instance.TrySpawnAntag(spawnRequest))
        {
            return;
        }

        PlayerSpawn.ServerSpawnPlayer(spawnRequest);
    }
示例#10
0
        public void PlayerSpawnRequest(GenericEvent evnt)
        {
            PlayerSpawnRequest data = evnt.Data as PlayerSpawnRequest;

            //Check if Permissions are Loaded
            ServerInstance.Instance.PermissionManager.GetPermission(data.Sender);
        }
示例#11
0
    /// <summary>
    /// Server-side only. For use when a player has only joined (as a JoinedViewer) and
    /// is not in control of any mobs. Spawns the joined viewer as the indicated occupation and transfers control to it.
    /// Note that this doesn't take into account game mode or antags, it just spawns whatever is requested.
    /// </summary>
    /// <param name="request">holds the request data</param>
    /// <param name="joinedViewer">viewer who should control the player</param>
    /// <param name="occupation">occupation to spawn as</param>
    /// <param name="characterSettings">settings to use for the character</param>
    /// <returns>the game object of the spawned player</returns>
    public static GameObject ServerSpawnPlayer(PlayerSpawnRequest request, JoinedViewer joinedViewer, Occupation occupation, CharacterSettings characterSettings, bool showBanner = true)
    {
        if (ValidateCharacter(request) == false)
        {
            return(null);
        }

        NetworkConnection conn = joinedViewer.connectionToClient;

        // TODO: add a nice cutscene/animation for the respawn transition
        var newPlayer = ServerSpawnInternal(conn, occupation, characterSettings, null, showBanner: showBanner);

        if (newPlayer != null && occupation.IsCrewmember)
        {
            CrewManifestManager.Instance.AddMember(newPlayer.GetComponent <PlayerScript>(), occupation.JobType);
        }

        if (SpawnEvent != null)
        {
            SpawnEventArgs args = new SpawnEventArgs()
            {
                player = newPlayer
            };
            SpawnEvent.Invoke(null, args);
        }

        return(newPlayer);
    }
示例#12
0
        /// <summary>
        /// Server only. Spawn the joined viewer as the indicated antag, includes creating their player object
        /// and transferring them to it. This is used as an alternative
        /// to PlayerSpawn.ServerSpawnPlayer when an antag should be spawned.
        /// </summary>
        /// <param name="chosenAntag">antag to spawn as</param>
        /// <param name="spawnRequest">player's requested spawn</param>
        public void ServerSpawnAntag(Antagonist chosenAntag, PlayerSpawnRequest spawnRequest)
        {
            //spawn the antag using their custom spawn logic
            ConnectedPlayer spawnedPlayer = chosenAntag.ServerSpawn(spawnRequest).Player();

            ServerFinishAntag(chosenAntag, spawnedPlayer);
        }
示例#13
0
        private void AcceptRequest(NetMessage msg)
        {
            var characterSettings = JsonConvert.DeserializeObject <CharacterSettings>(msg.JsonCharSettings);
            var spawnRequest      = PlayerSpawnRequest.RequestOccupation(
                SentByPlayer.ViewerScript, GameManager.Instance.GetRandomFreeOccupation(msg.JobType), characterSettings, SentByPlayer.UserId);

            GameManager.Instance.TrySpawnPlayer(spawnRequest);
        }
示例#14
0
 /// <summary>
 /// Spawn the player requesting the spawn as an antag, includes creating their player object
 /// and transferring them to it. This is used as an alternative
 /// to PlayerSpawn.ServerSpawnPlayer when an antag should be spawned.
 ///
 /// Defaults to picking a random antag from the possible antags list and
 /// spawning them as per the antag-specific spawn logic.
 /// </summary>
 protected void SpawnAntag(PlayerSpawnRequest playerSpawnRequest)
 {
     if (PossibleAntags.Count > 0)
     {
         int randIndex = Random.Range(0, PossibleAntags.Count);
         AntagManager.Instance.ServerSpawnAntag(PossibleAntags[randIndex], playerSpawnRequest);
     }
 }
示例#15
0
        /// <summary>
        /// Server only. Spawn the joined viewer as the indicated antag, includes creating their player object
        /// and transferring them to it. This is used as an alternative
        /// to PlayerSpawn.ServerSpawnPlayer when an antag should be spawned.
        /// </summary>
        /// <param name="chosenAntag">antag to spawn as</param>
        /// <param name="spawnRequest">player's requested spawn</param>
        public void ServerSpawnAntag(Antagonist chosenAntag, PlayerSpawnRequest spawnRequest)
        {
            //spawn the antag using their custom spawn logic
            var spawnedPlayer = chosenAntag.ServerSpawn(spawnRequest);

            var connectedPlayer = PlayerList.Instance.Get(spawnedPlayer);

            ServerFinishAntag(chosenAntag, connectedPlayer, spawnedPlayer);
        }
示例#16
0
        public override GameObject ServerSpawn(PlayerSpawnRequest spawnRequest)
        {
            var newPlayer = PlayerSpawn.ServerSpawnPlayer(spawnRequest);

            UpdateChatMessage.Send(newPlayer, ChatChannel.System, ChatModifier.None,
                                   "<color=red>As a member of the Cargonian Members Federation you have been ordered to help in the efforts to secede from the rest of the station.</color>");
            // spawn them normally, with their preferred occupation
            return(newPlayer);
        }
示例#17
0
        public override GameObject ServerSpawn(PlayerSpawnRequest spawnRequest)
        {
            var newPlayer = PlayerSpawn.ServerSpawnPlayer(spawnRequest);

            UpdateChatMessage.Send(newPlayer, ChatChannel.System, ChatModifier.None,
                                   "<color=red>Something has awoken in you. You feel the urgent need to rebel with your brothers against this station.</color>");
            // spawn them normally, with their preferred occupation
            return(newPlayer);
        }
        private void AcceptRequest()
        {
            var characterSettings = JsonConvert.DeserializeObject <CharacterSettings>(JsonCharSettings);
            var spawnRequest      = PlayerSpawnRequest.RequestOccupation(
                SentByPlayer.ViewerScript, GameManager.Instance.GetRandomFreeOccupation(JobType), characterSettings, SentByPlayer.UserId);

            GameManager.Instance.SpawnPlayerRequestQueue.Enqueue(spawnRequest);
            GameManager.Instance.ProcessSpawnPlayerQueue();
        }
示例#19
0
    /// <summary>
    /// Checks if the conditions are met to spawn an antag, and spawns them
    /// as the antag if so, spawning them as an actual player and transferring them into the body
    /// (meaning there's no need to call PlayerSpawn.ServerSpawnPlayer). Does nothing
    /// if the conditions are not met to spawn this viewer as an antag.
    /// Only called for mid-round joiners.
    /// </summary>
    /// <param name="spawnRequest">spawn requested by the player</param>
    /// <returns>true if the viewer was spawned as an antag.</returns>
    public bool TrySpawnAntag(PlayerSpawnRequest spawnRequest)
    {
        if (ShouldSpawnAntag(spawnRequest))
        {
            SpawnAntag(spawnRequest);
            return(true);
        }

        return(false);
    }
示例#20
0
        public override GameObject ServerSpawn(PlayerSpawnRequest spawnRequest)
        {
            // spawn them normally, with their preferred occupation
            var spawn = PlayerSpawn.ServerSpawnPlayer(spawnRequest);

            //Add blob player to game object
            spawn.AddComponent <BlobStarter>();

            return(spawn);
        }
示例#21
0
        /// <summary>
        /// Start the round
        /// </summary>
        public virtual void StartRound()
        {
            Logger.LogFormat("Starting {0} round!", Category.GameMode, Name);

            List <PlayerSpawnRequest> playerSpawnRequests;
            List <PlayerSpawnRequest> antagSpawnRequests;
            int antagsToSpawn = CalculateAntagCount(PlayerList.Instance.ReadyPlayers.Count);
            var jobAllocator  = new JobAllocator();
            var playerPool    = PlayerList.Instance.ReadyPlayers;

            if (AllocateJobsToAntags)
            {
                // Allocate jobs to all players first then choose antags
                playerSpawnRequests = jobAllocator.DetermineJobs(playerPool);
                var antagCandidates = playerSpawnRequests.Where(p =>
                                                                !NonAntagJobTypes.Contains(p.RequestedOccupation.JobType) &&
                                                                HasPossibleAntagEnabled(ref p.CharacterSettings.AntagPreferences) && HasPossibleAntagNotBanned(p.UserID));
                antagSpawnRequests = antagCandidates.PickRandom(antagsToSpawn).ToList();
                // Player and antag spawn requests are kept separate to stop players being spawned twice
                playerSpawnRequests.RemoveAll(antagSpawnRequests.Contains);
            }
            else
            {
                // Choose antags first then allocate jobs to all other players
                var antagCandidates = playerPool.Where(p =>
                                                       HasPossibleAntagEnabled(ref p.CharacterSettings.AntagPreferences) && HasPossibleAntagNotBanned(p.UserId));
                var chosenAntags = antagCandidates.PickRandom(antagsToSpawn).ToList();
                // Player and antag spawn requests are kept separate to stop players being spawned twice
                playerPool.RemoveAll(chosenAntags.Contains);
                playerSpawnRequests = jobAllocator.DetermineJobs(playerPool);
                antagSpawnRequests  = chosenAntags.Select(player =>
                                                          PlayerSpawnRequest.RequestOccupation(player, null)).ToList();
            }

            // Spawn all players and antags
            foreach (var spawnReq in playerSpawnRequests)
            {
                PlayerSpawn.ServerSpawnPlayer(spawnReq);
            }
            foreach (var spawnReq in antagSpawnRequests)
            {
                SpawnAntag(spawnReq);
            }

            var msg =
                $"{PlayerList.Instance.ReadyPlayers.Count} players ready, {antagsToSpawn} antags to spawn. {playerSpawnRequests.Count} players spawned (excludes antags), {antagSpawnRequests.Count} antags spawned";

            DiscordWebhookMessage.Instance.AddWebHookMessageToQueue(DiscordWebhookURLs.DiscordWebhookAdminLogURL,
                                                                    msg,
                                                                    "[GameMode]");

            StationObjectiveManager.Instance.ServerChooseObjective();
            GameManager.Instance.CurrentRoundState = RoundState.Started;
            EventManager.Broadcast(Event.RoundStarted, true);
        }
示例#22
0
    // /// <summary>
    // /// Check if the round should end yet
    // /// </summary>
    // public override void CheckEndCondition()
    // {
    //  Logger.Log("Check end round conditions!", Category.GameMode);
    // }

    // /// <summary>
    // /// End the round and display any relevant reports
    // /// </summary>
    // public override void EndRound()
    // {

    // }

    protected override bool ShouldSpawnAntag(PlayerSpawnRequest spawnRequest)
    {
        if (spawnRequest.RequestedOccupation.JobType == JobType.CARGOTECH ||
            spawnRequest.RequestedOccupation.JobType == JobType.QUARTERMASTER ||
            spawnRequest.RequestedOccupation.JobType == JobType.MINER)
        {
            return(true);
        }

        return(false);
    }
示例#23
0
        public override void Process()
        {
            // Server stuff here
            if (SentByPlayer == null || SentByPlayer.ViewerScript == null)
            {
                return;
            }

            if (SentByPlayer.UserId == null)
            {
                SentByPlayer.ViewerScript.NotifyJobRequestFailed(JobRequestError.InvalidUserID);
                Logger.Log("User ID was null, cant spawn job.", Category.Admin);
                return;
            }

            if (SentByPlayer.UserId != PlayerID)
            {
                SentByPlayer.ViewerScript.NotifyJobRequestFailed(JobRequestError.InvalidPlayerID);
                Logger.Log($"User: {SentByPlayer.Username} ID: {SentByPlayer.UserId} used a different ID: {PlayerID} to request a job.", Category.Admin);
                return;
            }

            var characterSettings = JsonConvert.DeserializeObject <CharacterSettings>(JsonCharSettings);

            if (GameManager.Instance.CurrentRoundState != RoundState.Started)
            {
                SentByPlayer.ViewerScript.NotifyJobRequestFailed(JobRequestError.RoundNotReady);
                Logger.LogWarningFormat("Round hasn't started yet, can't request job {0} for {1}", Category.Jobs, JobType, characterSettings);
                return;
            }

            if (PlayerList.Instance.FindPlayerJobBanEntryServer(PlayerID, JobType, true) != null)
            {
                SentByPlayer.ViewerScript.NotifyJobRequestFailed(JobRequestError.JobBanned);
                return;
            }

            int slotsTaken = GameManager.Instance.GetOccupationsCount(JobType);
            int slotsMax   = GameManager.Instance.GetOccupationMaxCount(JobType);

            if (slotsTaken >= slotsMax)
            {
                SentByPlayer.ViewerScript.NotifyJobRequestFailed(JobRequestError.PositionsFilled);
                return;
            }

            var spawnRequest = PlayerSpawnRequest.RequestOccupation(
                SentByPlayer.ViewerScript, GameManager.Instance.GetRandomFreeOccupation(JobType), characterSettings, SentByPlayer.UserId);

            GameManager.Instance.SpawnPlayerRequestQueue.Enqueue(spawnRequest);

            GameManager.Instance.ProcessSpawnPlayerQueue();
        }
示例#24
0
        /// <summary>
        /// Allocates a job to players. Updates _determinedPlayers and _playersLeft.
        /// </summary>
        /// <param name="players">Players to allocate jobs to</param>
        /// <param name="job">The job to allocate</param>
        private void AllocateJobs(IReadOnlyCollection <ConnectedPlayer> players, Occupation job)
        {
            // Update determined players and players left
            determinedPlayers.AddRange(players.Select(player =>
                                                      PlayerSpawnRequest.RequestOccupation(player.ViewerScript, job, player.CharacterSettings, player.UserId)));
            playersLeft.RemoveAll(players.Contains);
            missedOutPlayers.RemoveAll(players.Contains);

            // Update occupation counts
            occupationCount.TryGetValue(job, out int currentCount);
            occupationCount[job] = currentCount + 1;
        }
示例#25
0
 protected override bool ShouldSpawnAntag(PlayerSpawnRequest spawnRequest)
 {
     for (int i = 0; i < TraitorAmount - 1; i++)
     {
         return(!LoyalImplanted.Contains(spawnRequest.RequestedOccupation.JobType) &&
                AntagManager.Instance.AntagCount == 0 &&
                PlayerList.Instance.InGamePlayers.Count > 0);
     }
     return(!LoyalImplanted.Contains(spawnRequest.RequestedOccupation.JobType) &&
            AntagManager.Instance.AntagCount == 0 &&
            PlayerList.Instance.InGamePlayers.Count > 0);
 }
示例#26
0
    public void CmdRequestJob(JobType jobType, CharacterSettings characterSettings)
    {
        var spawnRequest =
            PlayerSpawnRequest.RequestOccupation(this, GameManager.Instance.GetRandomFreeOccupation(jobType), characterSettings);

        //regardless of their chosen occupation, they might spawn as an antag instead.
        //If they do, bypass the normal spawn logic.
        if (GameManager.Instance.TrySpawnAntag(spawnRequest))
        {
            return;
        }

        PlayerSpawn.ServerSpawnPlayer(spawnRequest.JoinedViewer, spawnRequest.RequestedOccupation, characterSettings);
    }
示例#27
0
        public void TestSpawnEvent(GenericEvent evnt)
        {
            PlayerSpawnRequest hesse = evnt.Data as PlayerSpawnRequest;
            Player             p     = GetPluginHelper.getPlayerFromGuid(hesse.Sender);

            if (p == null)
            {
                GetLogger.Error("Error! Player Not Found E:55");
                return;
            }
            GetPluginHelper.SendMessageToServer(p.Name + " has joined the server!");
            GetPluginHelper.SendMessageToClient(p, "Welcome to the server " + p.Name + "!");
            GetPluginHelper.SendMessageToClient(p, "Use /help for all commands");
        }
        public void PlayerJoinEvent(GenericEvent evnt)
        {
            dynamic e = Convert.ChangeType(evnt.Data, AA);

            if (e == null)
            {
                Console.WriteLine("ERROR! #4543 PLZ TELL YUNG TO FIX ME!!!!!");
                return;
            }
            PlayerSpawnRequest ev   = e.Method();
            Player             p    = GetPluginHelper.getPlayerFromGuid(ev.Sender);
            String             name = p == null ? "M/A" : p.Name;

            Console.WriteLine("Player Spawn Info: GUID {0} Name {1} Type of Spawn {2} ", ev.Sender, name, ev.SpawnSetupType);
        }
示例#29
0
    protected override bool ShouldSpawnAntag(PlayerSpawnRequest spawnRequest)
    {
        //spawn only if there is not yet any syndicate ops (and at least one other player) or
        //the ratio is too low
        var existingNukeOps = PlayerList.Instance.AntagPlayers.Count;
        var inGamePlayers   = PlayerList.Instance.InGamePlayers.Count;

        if ((inGamePlayers > 0 && existingNukeOps == 0) ||
            existingNukeOps < Math.Floor(inGamePlayers * nukeOpsRatio))
        {
            return(true);
        }

        return(false);
    }
示例#30
0
        /// <summary>
        /// Server only. Spawn the joined viewer as the indicated antag, includes creating their player object
        /// and transferring them to it. This is used as an alternative
        /// to PlayerSpawn.ServerSpawnPlayer when an antag should be spawned.
        /// </summary>
        /// <param name="chosenAntag">antag to spawn as</param>
        /// <param name="spawnRequest">player's requested spawn</param>
        public void ServerSpawnAntag(Antagonist chosenAntag, PlayerSpawnRequest spawnRequest)
        {
            //spawn the antag using their custom spawn logic
            var spawnedPlayer = chosenAntag.ServerSpawn(spawnRequest);

            var connectedPlayer = PlayerList.Instance.Get(spawnedPlayer);

            // Generate objectives for this antag
            List <Objective> objectives = AntagData.GenerateObjectives(connectedPlayer.Script, chosenAntag);
            // Set the antag
            var spawnedAntag = SpawnedAntag.Create(chosenAntag, connectedPlayer.Script.mind, objectives);

            connectedPlayer.Script.mind.SetAntag(spawnedAntag);
            ActiveAntags.Add(spawnedAntag);
            Logger.Log($"Created new antag. Made {connectedPlayer.Name} a {chosenAntag.AntagName} with objectives:\n{spawnedAntag.GetObjectivesForLog()}", Category.Antags);
        }