public static Character Spawn(string name, Vector2 worldPos) { Character spawnedCharacter = null; Vector2 spawnPosition = worldPos; string characterLowerCase = name.ToLowerInvariant(); JobPrefab job = null; if (!JobPrefab.Prefabs.ContainsKey(characterLowerCase)) { job = JobPrefab.Prefabs.Find(jp => jp.Name != null && jp.Name.Equals(characterLowerCase, StringComparison.OrdinalIgnoreCase)); } else { job = JobPrefab.Prefabs[characterLowerCase]; } bool human = job != null || characterLowerCase == CharacterPrefab.HumanSpeciesName; if (string.IsNullOrWhiteSpace(name)) { return(null); } if (human) { var variant = job != null?Rand.Range(0, job.Variants, Rand.RandSync.Server) : 0; CharacterInfo characterInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: job, variant: variant); spawnedCharacter = Character.Create(characterInfo, spawnPosition, ToolBox.RandomSeed(8)); if (GameMain.GameSession != null) { //TODO: a way to select which team to spawn to? spawnedCharacter.TeamID = Character.Controlled != null ? Character.Controlled.TeamID : CharacterTeamType.Team1; #if CLIENT GameMain.GameSession.CrewManager.AddCharacter(spawnedCharacter); #endif } spawnedCharacter.GiveJobItems(null); spawnedCharacter.Info.StartItemsGiven = true; } else { if (CharacterPrefab.FindBySpeciesName(name) != null) { spawnedCharacter = Character.Create(name, spawnPosition, ToolBox.RandomSeed(8)); } } return(spawnedCharacter); }
public void InitRound() { characters.Clear(); List <WayPoint> spawnWaypoints = null; List <WayPoint> mainSubWaypoints = WayPoint.SelectCrewSpawnPoints(characterInfos, Submarine.MainSub).ToList(); if (Level.IsLoadedOutpost) { spawnWaypoints = WayPoint.WayPointList.FindAll(wp => wp.SpawnType == SpawnType.Human && wp.Submarine == Level.Loaded.StartOutpost && wp.CurrentHull?.OutpostModuleTags != null && wp.CurrentHull.OutpostModuleTags.Contains("airlock")); while (spawnWaypoints.Count > characterInfos.Count) { spawnWaypoints.RemoveAt(Rand.Int(spawnWaypoints.Count)); } while (spawnWaypoints.Any() && spawnWaypoints.Count < characterInfos.Count) { spawnWaypoints.Add(spawnWaypoints[Rand.Int(spawnWaypoints.Count)]); } } if (spawnWaypoints == null || !spawnWaypoints.Any()) { spawnWaypoints = mainSubWaypoints; } System.Diagnostics.Debug.Assert(spawnWaypoints.Count == mainSubWaypoints.Count); for (int i = 0; i < spawnWaypoints.Count; i++) { var info = characterInfos[i]; info.TeamID = Character.TeamType.Team1; Character character = Character.Create(info, spawnWaypoints[i].WorldPosition, info.Name); if (character.Info != null) { if (!character.Info.StartItemsGiven && character.Info.InventoryData != null) { DebugConsole.AddWarning($"Error when initializing a round: character \"{character.Name}\" has not been given their initial items but has saved inventory data. Using the saved inventory data instead of giving the character new items."); } if (character.Info.InventoryData != null) { character.Info.SpawnInventoryItems(character.Inventory, character.Info.InventoryData); } else if (!character.Info.StartItemsGiven) { character.GiveJobItems(mainSubWaypoints[i]); } if (character.Info.HealthData != null) { character.Info.ApplyHealthData(character, character.Info.HealthData); } character.GiveIdCardTags(spawnWaypoints[i]); character.Info.StartItemsGiven = true; } AddCharacter(character); #if CLIENT if (IsSinglePlayer && (Character.Controlled == null || character.Info.LastControlled)) { Character.Controlled = character; } #endif } //longer delay in multiplayer to prevent the server from triggering NPC conversations while the players are still loading the round conversationTimer = IsSinglePlayer ? Rand.Range(5.0f, 10.0f) : Rand.Range(45.0f, 60.0f); }