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); }
/// <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()); } }
public override GameObject ServerSpawn(PlayerSpawnRequest spawnRequest) { var newPlayer = PlayerSpawn.ServerSpawnPlayer(spawnRequest.JoinedViewer, AntagOccupation, spawnRequest.CharacterSettings); return(newPlayer); }
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(); }
/// <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); }
/// <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); }
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); }
public void PlayerSpawnRequest(GenericEvent evnt) { PlayerSpawnRequest data = evnt.Data as PlayerSpawnRequest; //Check if Permissions are Loaded ServerInstance.Instance.PermissionManager.GetPermission(data.Sender); }
/// <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); }
/// <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); }
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); }
/// <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); } }
/// <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); }
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); }
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(); }
/// <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); }
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); }
/// <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); }
// /// <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); }
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(); }
/// <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; }
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); }
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); }
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); }
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); }
/// <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); }