/// <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); }
public IEnumerator ServerRespawnAsAntag(ConnectedPlayer connectedPlayer, Antagonist antagonist) { var antagOccupation = antagonist.AntagOccupation; if (antagOccupation != null) { connectedPlayer.Script.mind.occupation = antagonist.AntagOccupation; } if (antagonist.AntagJobType == JobType.SYNDICATE) { yield return(StartCoroutine(SubSceneManager.Instance.LoadSyndicate())); yield return(WaitFor.EndOfFrame); } if (antagonist.AntagJobType == JobType.WIZARD) { yield return(StartCoroutine(SubSceneManager.Instance.LoadWizard())); yield return(WaitFor.EndOfFrame); } PlayerSpawn.ServerRespawnPlayer(connectedPlayer.Script.mind); ServerFinishAntag(antagonist, connectedPlayer); }
/// <summary> /// Creates a new antagonist, defaults to a random player with a random antag type if null is passed. /// </summary> /// <param name="chosenAntag">The antag type to spawn</param> /// <param name="chosenPlayer">The player to make an antag</param> public void CreateAntag(Antagonist chosenAntag = null, ConnectedPlayer chosenPlayer = null) { // Choose a random non-antag player if one hasn't been provided ConnectedPlayer player = chosenPlayer; if (player == null) { if (PlayerList.Instance.NonAntagPlayers.Count == 0) { Logger.LogWarning("Unable to create new antag: No suitable candidates left."); return; } player = PlayerList.Instance.NonAntagPlayers.PickRandom(); } // Choose a random antag type if one hasn't been provided Antagonist antag = chosenAntag ?? AntagData.GetRandomAntag(); // Generate objectives for this antag List <Objective> objectives = AntagData.GenerateObjectives(player.Script, antag); antag.GiveObjectives(objectives); // Set the antag player.Script.mind.SetAntag(antag); ActiveAntags.Add(antag); Logger.Log($"Created new antag. Made {player.Name} a {antag.AntagName} with objectives:\n{antag.GetObjectivesForLog()}", Category.Antags); }
public IEnumerator ServerRespawnAsAntag(ConnectedPlayer connectedPlayer, Antagonist antagonist) { var antagOccupation = antagonist.AntagOccupation; if (antagOccupation != null) { connectedPlayer.Script.mind.occupation = antagonist.AntagOccupation; } //Can be null if respawning spectator ghost as they dont have an occupation and their antag occupation is null too if (connectedPlayer.Script.mind.occupation == null) { yield break; } if (antagonist.AntagJobType == JobType.SYNDICATE) { yield return(StartCoroutine(SubSceneManager.Instance.LoadSyndicate())); yield return(WaitFor.EndOfFrame); } if (antagonist.AntagJobType == JobType.WIZARD) { yield return(StartCoroutine(SubSceneManager.Instance.LoadWizard())); yield return(WaitFor.EndOfFrame); } PlayerSpawn.ServerRespawnPlayer(connectedPlayer.Script.mind); ServerFinishAntag(antagonist, connectedPlayer); }
/// <summary> /// Generates a set of valid objectives for a player based on their antag type. /// Will set them up and ensure all targets are unique. /// Amount to generate does not include the escape objective. /// </summary> /// <param name="player">The player receiving these objectives</param> /// <param name="antag">The antag type</param> /// <param name="amount">How many objectives to generate, not including escape objectives</param> public List <Objective> GenerateObjectives(PlayerScript player, Antagonist antag) { int amount = antag.NumberOfObjectives; // Get all antag core and shared objectives which are possible for this player List <Objective> objPool = antag.CoreObjectives.Where(obj => obj.IsPossible(player)).ToList(); if (antag.CanUseSharedObjectives) { objPool = objPool.Concat(SharedObjectives).Where(obj => obj.IsPossible(player)).ToList(); } if (objPool.Count == 0) { amount = 0; Logger.LogWarning($"No objectives available, only assigning escape type objective", Category.Antags); } List <Objective> generatedObjs = new List <Objective>(); Objective newObjective; for (int i = 0; i < amount; i++) { // Select objective and perform setup e.g. assign owner and targets newObjective = PickRandomObjective(ref objPool); newObjective.DoSetup(player.mind); generatedObjs.Add(newObjective); // Trim any objectives which aren't possible // Should be done everytime an objective is assigned and setup, // otherwise all targets could be taken already! objPool = objPool.Where(obj => obj.IsPossible(player)).ToList(); if (objPool.Count == 0) { // No objectives left to give so stop assigning break; } } if (antag.NeedsEscapeObjective) { // Add one escape type objective if needed // Be careful not to remove all escape objectives from AntagData newObjective = PickRandomObjective(ref EscapeObjectives, false); newObjective.DoSetup(player.mind); generatedObjs.Add(newObjective); } if (antag.ChanceForGimmickObjective != 0 && DMMath.Prob(antag.ChanceForGimmickObjective)) { // Add one gimmick objective newObjective = PickRandomObjective(ref GimmickObjectives, false); newObjective.DoSetup(player.mind); generatedObjs.Add(newObjective); } return(generatedObjs); }
/// <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); }
/// <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); }
private SpawnedAntag SetAntagDetails(Antagonist chosenAntag, ConnectedPlayer connectedPlayer) { // 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); return(spawnedAntag); }
/// <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(GameObject player, Antagonist antag) { AntagBannerMessage.Send( player, antag.AntagName, antag.SpawnSound, antag.TextColor, antag.BackgroundColor, antag.PlaySound); }
private void ServerFinishAntag(Antagonist chosenAntag, ConnectedPlayer connectedPlayer, GameObject spawnedPlayer) { var spawnedAntag = SetAntagDetails(chosenAntag, connectedPlayer); ActiveAntags.Add(spawnedAntag); ShowAntagBanner(spawnedPlayer, chosenAntag); Logger.Log( $"Created new antag. Made {connectedPlayer.Name} a {chosenAntag.AntagName} with objectives:\n{spawnedAntag.GetObjectivesForLog()}", Category.Antags); }
public void ServerRespawnAsAntag(ConnectedPlayer connectedPlayer, Antagonist antagonist) { SetAntagDetails(antagonist, connectedPlayer); var antagOccupation = antagonist.AntagOccupation; if (antagOccupation != null) { connectedPlayer.Script.mind.occupation = antagonist.AntagOccupation; } ServerFinishAntag(antagonist, connectedPlayer, connectedPlayer.GameObject); PlayerSpawn.ServerRespawnPlayer(connectedPlayer.Script.mind); }
/// <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); }
public IEnumerator ServerRespawnAsAntag(ConnectedPlayer connectedPlayer, Antagonist antagonist) { var antagOccupation = antagonist.AntagOccupation; if (antagOccupation != null) { connectedPlayer.Script.mind.occupation = antagonist.AntagOccupation; } if (antagonist.AntagJobType == JobType.WIZARD) { yield return(WaitFor.EndOfFrame); } PlayerSpawn.ServerRespawnPlayer(connectedPlayer.Script.mind); ServerFinishAntag(antagonist, connectedPlayer); }
public IEnumerator ServerRespawnAsAntag(ConnectedPlayer connectedPlayer, Antagonist antagonist) { var antagOccupation = antagonist.AntagOccupation; if (antagOccupation != null) { connectedPlayer.Script.mind.occupation = antagonist.AntagOccupation; } //Can be null if respawning spectator ghost as they dont have an occupation and their antag occupation is null too if (connectedPlayer.Script.mind.occupation == null) { yield break; } PlayerSpawn.ServerRespawnPlayer(connectedPlayer.Script.mind); ServerFinishAntag(antagonist, connectedPlayer); }
/// <summary> /// Create a spawned antag of the indicated antag type for the indicated mind with the given objectives. /// </summary> /// <param name="antagonist"></param> /// <param name="owner"></param> /// <param name="objectives"></param> /// <returns></returns> public static SpawnedAntag Create(Antagonist antagonist, Mind owner, IEnumerable <Objective> objectives) { return(new SpawnedAntag(antagonist, owner, objectives)); }
private SpawnedAntag(Antagonist antagonist, Mind owner, IEnumerable <Objective> objectives) { Antagonist = antagonist; Owner = owner; Objectives = objectives; }