bool TrySpawnCell(out Character cell, ISpatialEntity targetEntity = null) { cell = null; if (protectiveCells.Count >= MaxCellCount) { return(false); } if (targetEntity == null) { targetEntity = wayPoints.GetRandom(wp => wp.CurrentHull != null && populatedHulls.Count(h => h == wp.CurrentHull) < MaxCellsPerRoom && wp.CurrentHull.WaterPercentage >= MinWaterLevel) ?? hulls.GetRandom(h => populatedHulls.Count(h2 => h2 == h) < MaxCellsPerRoom && h.WaterPercentage >= MinWaterLevel) as ISpatialEntity; } if (targetEntity == null) { return(false); } if (targetEntity is Hull h) { populatedHulls.Add(h); } else if (targetEntity is WayPoint wp && wp.CurrentHull != null) { populatedHulls.Add(wp.CurrentHull); } // Don't add items in the list, because we want to be able to ignore the restrictions for spawner organs. cell = Character.Create(Config.DefensiveAgent, targetEntity.WorldPosition, ToolBox.RandomSeed(8), hasAi: true, createNetworkEvent: true); protectiveCells.Add(cell); cell.OnDeath += OnCellDeath; cellSpawnTimer = GetSpawnTime(); return(true); }
public static void LoadPets(XElement petsElement) { foreach (XElement subElement in petsElement.Elements()) { string speciesName = subElement.GetAttributeString("speciesname", ""); string seed = subElement.GetAttributeString("seed", "123"); ushort ownerID = (ushort)subElement.GetAttributeInt("ownerid", 0); Vector2 spawnPos = Vector2.Zero; Character owner = Entity.FindEntityByID(ownerID) as Character; if (owner != null) { spawnPos = owner.WorldPosition; } else { var spawnPoint = WayPoint.WayPointList.Where(wp => wp.SpawnType == SpawnType.Human && wp.Submarine?.Info.Type == SubmarineType.Player).GetRandom(); spawnPos = spawnPoint?.WorldPosition ?? Submarine.MainSub.WorldPosition; } var pet = Character.Create(speciesName, spawnPos, seed); var petBehavior = (pet.AIController as EnemyAIController)?.PetBehavior; if (petBehavior != null) { petBehavior.Owner = owner; var petBehaviorElement = subElement.Attribute("petbehavior"); if (petBehaviorElement != null) { petBehavior.Hunger = petBehaviorElement.GetAttributeFloat(50.0f); petBehavior.Happiness = petBehaviorElement.GetAttributeFloat(50.0f); } } } }
private void SpawnMonsters() { if (disallowed) { return; } Vector2 spawnPos = Level.Loaded.GetRandomInterestingPosition(true, spawnPosType, true); int amount = Rand.Range(minAmount, maxAmount, false); monsters = new Character[amount]; if (spawnDeep) { spawnPos.Y -= Level.Loaded.Size.Y; } for (int i = 0; i < amount; i++) { spawnPos.X += Rand.Range(-0.5f, 0.5f, false); spawnPos.Y += Rand.Range(-0.5f, 0.5f, false); monsters[i] = Character.Create(characterFile, spawnPos, null, GameMain.Client != null); } }
public override void Start(Level level) { if (monsters.Count > 0) { throw new Exception($"monsters.Count > 0 ({monsters.Count})"); } if (tempSonarPositions.Count > 0) { throw new Exception($"tempSonarPositions.Count > 0 ({tempSonarPositions.Count})"); } if (!IsClient) { Level.Loaded.TryGetInterestingPosition(true, Level.PositionType.MainPath, Level.Loaded.Size.X * 0.3f, out Vector2 spawnPos); foreach (var monster in monsterPrefabs) { int amount = Rand.Range(monster.Item2.X, monster.Item2.Y + 1); for (int i = 0; i < amount; i++) { monsters.Add(Character.Create(monster.Item1.Identifier, spawnPos, ToolBox.RandomSeed(8), createNetworkEvent: false)); } } InitializeMonsters(monsters); } }
public override void Start(Level level) { Level.Loaded.TryGetInterestingPosition(true, Level.PositionType.MainPath, Level.Loaded.Size.X * 0.3f, out Vector2 spawnPos); bool isClient = IsClient; if (!string.IsNullOrEmpty(monsterFile)) { for (int i = 0; i < monsterCount; i++) { monsters.Add(Character.Create(monsterFile, spawnPos, ToolBox.RandomSeed(8), null, isClient, true, false)); } } foreach (var monster in monsterFiles) { for (int i = 0; i < monster.Item2; i++) { monsters.Add(Character.Create(monster.Item1, spawnPos, ToolBox.RandomSeed(8), null, isClient, true, false)); } } monsters.ForEach(m => m.Enabled = false); SwarmBehavior.CreateSwarm(monsters.Cast <AICharacter>()); sonarPositions.Add(spawnPos); }
private Character[] SpawnMonsters(int amount, bool createNetworkEvent) { if (disallowed) { return(null); } Vector2 spawnPos; float minDist = spawnPosType == Level.PositionType.Ruin ? 0.0f : 20000.0f; if (!Level.Loaded.TryGetInterestingPosition(true, spawnPosType, minDist, out spawnPos)) { //no suitable position found, disable the event repeat = false; Finished(); return(null); } var monsters = new Character[amount]; if (spawnDeep) { spawnPos.Y -= Level.Loaded.Size.Y; } for (int i = 0; i < amount; i++) { spawnPos.X += Rand.Range(-0.5f, 0.5f, Rand.RandSync.Server); spawnPos.Y += Rand.Range(-0.5f, 0.5f, Rand.RandSync.Server); monsters[i] = Character.Create(characterFile, spawnPos, null, GameMain.Client != null, true, createNetworkEvent); } return(monsters); }
private IEnumerable <object> CreateAIHusk(Character character) { character.Enabled = false; Entity.Spawner.AddToRemoveQueue(character); var configFile = Character.GetConfigFile("humanhusk"); if (string.IsNullOrEmpty(configFile)) { DebugConsole.ThrowError("Failed to turn character \"" + character.Name + "\" into a husk - husk config file not found."); yield return(CoroutineStatus.Success); } //XDocument doc = XMLExtensions.TryLoadXml(configFile); //if (doc?.Root == null) //{ // DebugConsole.ThrowError("Failed to turn character \"" + character.Name + "\" into a husk - husk config file ("+configFile+") could not be read."); // yield return CoroutineStatus.Success; //} //character.Info.Ragdoll = null; //character.Info.SourceElement = doc.Root; var husk = Character.Create(configFile, character.WorldPosition, character.Info.Name, character.Info, isRemotePlayer: false, hasAi: true); foreach (Limb limb in husk.AnimController.Limbs) { if (limb.type == LimbType.None) { limb.body.SetTransform(character.SimPosition, 0.0f); continue; } var matchingLimb = character.AnimController.GetLimb(limb.type); if (matchingLimb?.body != null) { limb.body.SetTransform(matchingLimb.SimPosition, matchingLimb.Rotation); limb.body.LinearVelocity = matchingLimb.LinearVelocity; limb.body.AngularVelocity = matchingLimb.body.AngularVelocity; } } if (character.Inventory.Items.Length != husk.Inventory.Items.Length) { string errorMsg = "Failed to move items from a human's inventory into a humanhusk's inventory (inventory sizes don't match)"; DebugConsole.ThrowError(errorMsg); GameAnalyticsManager.AddErrorEventOnce("AfflictionHusk.CreateAIHusk:InventoryMismatch", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); yield return(CoroutineStatus.Success); } for (int i = 0; i < character.Inventory.Items.Length && i < husk.Inventory.Items.Length; i++) { if (character.Inventory.Items[i] == null) { continue; } husk.Inventory.TryPutItem(character.Inventory.Items[i], i, true, false, null); } yield return(CoroutineStatus.Success); }
private Character[] SpawnMonsters(int amount) { if (disallowed) { return(null); } Vector2 spawnPos = Level.Loaded.GetRandomInterestingPosition(true, spawnPosType, true); var monsters = new Character[amount]; if (spawnDeep) { spawnPos.Y -= Level.Loaded.Size.Y; } for (int i = 0; i < amount; i++) { spawnPos.X += Rand.Range(-0.5f, 0.5f, Rand.RandSync.Server); spawnPos.Y += Rand.Range(-0.5f, 0.5f, Rand.RandSync.Server); monsters[i] = Character.Create(characterFile, spawnPos, null, GameMain.Client != null); } return(monsters); }
private Character SpawnWatchman(Submarine outpost) { WayPoint watchmanSpawnpoint = WayPoint.WayPointList.Find(wp => wp.Submarine == outpost); if (watchmanSpawnpoint == null) { DebugConsole.ThrowError("Failed to spawn a watchman at the outpost. No spawnpoints found inside the outpost."); return(null); } string seed = outpost == Level.Loaded.StartOutpost ? map.SelectedLocation.Name : map.CurrentLocation.Name; Rand.SetSyncedSeed(ToolBox.StringToInt(seed)); JobPrefab watchmanJob = JobPrefab.List.Find(jp => jp.Identifier == "watchman"); CharacterInfo characterInfo = new CharacterInfo(Character.HumanConfigFile, jobPrefab: watchmanJob); var spawnedCharacter = Character.Create(characterInfo, watchmanSpawnpoint.WorldPosition, Level.Loaded.Seed + (outpost == Level.Loaded.StartOutpost ? "start" : "end")); InitializeWatchman(spawnedCharacter); (spawnedCharacter.AIController as HumanAIController)?.ObjectiveManager.SetOrder( new AIObjectiveGoTo(watchmanSpawnpoint, spawnedCharacter, repeat: true, getDivingGearIfNeeded: false)); if (watchmanJob != null) { spawnedCharacter.GiveJobItems(); } return(spawnedCharacter); }
private void LoadMonster(CharacterPrefab monsterPrefab, XElement element, Submarine submarine) { string[] moduleFlags = element.GetAttributeStringArray("moduleflags", null); string[] spawnPointTags = element.GetAttributeStringArray("spawnpointtags", null); ISpatialEntity spawnPos = SpawnAction.GetSpawnPos(SpawnAction.SpawnLocationType.Outpost, SpawnType.Enemy, moduleFlags, spawnPointTags, element.GetAttributeBool("asfaraspossible", false)); if (spawnPos == null) { spawnPos = submarine.GetHulls(alsoFromConnectedSubs: false).GetRandom(); } Character spawnedCharacter = Character.Create(monsterPrefab.Identifier, spawnPos.WorldPosition, ToolBox.RandomSeed(8), createNetworkEvent: false); characters.Add(spawnedCharacter); if (element.GetAttributeBool("requirekill", false)) { requireKill.Add(spawnedCharacter); } if (spawnedCharacter.Inventory != null) { characterItems.Add(spawnedCharacter, spawnedCharacter.Inventory.FindAllItems(recursive: true)); } if (submarine != null && spawnedCharacter.AIController is EnemyAIController enemyAi) { enemyAi.UnattackableSubmarines.Add(submarine); enemyAi.UnattackableSubmarines.Add(Submarine.MainSub); foreach (Submarine sub in Submarine.MainSub.DockedTo) { enemyAi.UnattackableSubmarines.Add(sub); } } }
private IEnumerable <object> CreateAIHusk() { character.Enabled = false; Entity.Spawner.AddToRemoveQueue(character); string huskedSpeciesName = GetHuskedSpeciesName(character.SpeciesName, Prefab as AfflictionPrefabHusk); CharacterPrefab prefab = CharacterPrefab.FindBySpeciesName(huskedSpeciesName); if (prefab == null) { DebugConsole.ThrowError("Failed to turn character \"" + character.Name + "\" into a husk - husk config file not found."); yield return(CoroutineStatus.Success); } var husk = Character.Create(huskedSpeciesName, character.WorldPosition, ToolBox.RandomSeed(8), character.Info, isRemotePlayer: false, hasAi: true); foreach (Limb limb in husk.AnimController.Limbs) { if (limb.type == LimbType.None) { limb.body.SetTransform(character.SimPosition, 0.0f); continue; } var matchingLimb = character.AnimController.GetLimb(limb.type); if (matchingLimb?.body != null) { limb.body.SetTransform(matchingLimb.SimPosition, matchingLimb.Rotation); limb.body.LinearVelocity = matchingLimb.LinearVelocity; limb.body.AngularVelocity = matchingLimb.body.AngularVelocity; } } if (character.Inventory != null && husk.Inventory != null) { if (character.Inventory.Items.Length != husk.Inventory.Items.Length) { string errorMsg = "Failed to move items from the source character's inventory into a husk's inventory (inventory sizes don't match)"; DebugConsole.ThrowError(errorMsg); GameAnalyticsManager.AddErrorEventOnce("AfflictionHusk.CreateAIHusk:InventoryMismatch", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); yield return(CoroutineStatus.Success); } for (int i = 0; i < character.Inventory.Items.Length && i < husk.Inventory.Items.Length; i++) { if (character.Inventory.Items[i] == null) { continue; } husk.Inventory.TryPutItem(character.Inventory.Items[i], i, true, false, null); } } husk.SetStun(5); yield return(new WaitForSeconds(5, false)); #if CLIENT husk.PlaySound(CharacterSound.SoundType.Idle); #endif yield return(CoroutineStatus.Success); }
public override void Start(Level level) { Vector2 spawnPos = Level.Loaded.GetRandomInterestingPosition(true, Level.PositionType.MainPath, true); monster = Character.Create(monsterFile, spawnPos, null, GameMain.Client != null); monster.Enabled = false; radarPosition = spawnPos; }
public Entity Spawn() { var character = string.IsNullOrEmpty(identifier) ? null : Character.Create(identifier, Submarine == null ? Position : Submarine.Position + Position, ToolBox.RandomSeed(8), CharacterInfo, createNetworkEvent: false); return(character); }
private Character[] SpawnMonsters(int amount, bool createNetworkEvent) { if (disallowed) { return(null); } Vector2 spawnPos; float minDist = spawnPosType == Level.PositionType.Ruin ? 0.0f : 20000.0f; if (!Level.Loaded.TryGetInterestingPosition(true, spawnPosType, minDist, out spawnPos)) { //no suitable position found, disable the event repeat = false; Finished(); return(null); } var monsters = new Character[amount]; if (spawnDeep) { spawnPos.Y -= Level.Loaded.Size.Y; //disable the event if the ocean floor is too high up to spawn the monster deep if (spawnPos.Y < Level.Loaded.GetBottomPosition(spawnPos.X).Y) { repeat = false; Finished(); return(null); } } for (int i = 0; i < amount; i++) { spawnPos.X += Rand.Range(-0.5f, 0.5f, Rand.RandSync.Server); spawnPos.Y += Rand.Range(-0.5f, 0.5f, Rand.RandSync.Server); monsters[i] = Character.Create(characterFile, spawnPos, null, GameMain.Client != null, true, createNetworkEvent); #if CLIENT if (GameMain.Server != null) { GameSession.inGameInfo.AddNoneClientCharacter(monsters[i]); if (createNetworkEvent && GameMain.NilMod.CreatureLimitRespawns) { GameMain.Server.ServerLog.WriteLine("Respawning creature: " + monsters[i].Name + " - respawns used: " + Respawned + " / " + MaxRespawned, Networking.ServerLog.MessageType.Spawns); } else if (createNetworkEvent && !GameMain.NilMod.CreatureLimitRespawns) { GameMain.Server.ServerLog.WriteLine("Respawning creature: " + monsters[i].Name + " - respawns used: " + Respawned + " / Infinite", Networking.ServerLog.MessageType.Spawns); } } #endif } return(monsters); }
private void QuickStart() { Submarine selectedSub = null; string subName = GameMain.Config.QuickStartSubmarineName; if (!string.IsNullOrEmpty(subName)) { DebugConsole.NewMessage($"Loading the predefined quick start sub \"{subName}\"", Color.White); selectedSub = Submarine.SavedSubmarines.FirstOrDefault(s => s.Name.ToLower() == subName.ToLower()); if (selectedSub == null) { DebugConsole.NewMessage($"Cannot find a sub that matches the name \"{subName}\".", Color.Red); } } if (selectedSub == null) { DebugConsole.NewMessage("Loading a random sub.", Color.White); var subs = Submarine.SavedSubmarines.Where(s => !s.HasTag(SubmarineTag.Shuttle) && !s.HasTag(SubmarineTag.HideInMenus)); selectedSub = subs.ElementAt(Rand.Int(subs.Count())); } var gamesession = new GameSession( selectedSub, "Data/Saves/test.xml", GameModePreset.List.Find(gm => gm.Identifier == "devsandbox"), missionPrefab: null); //(gamesession.GameMode as SinglePlayerCampaign).GenerateMap(ToolBox.RandomSeed(8)); gamesession.StartRound(ToolBox.RandomSeed(8)); GameMain.GameScreen.Select(); string[] jobIdentifiers = new string[] { "captain", "engineer", "mechanic" }; for (int i = 0; i < 3; i++) { var spawnPoint = WayPoint.GetRandom(SpawnType.Human, null, Submarine.MainSub); if (spawnPoint == null) { DebugConsole.ThrowError("No spawnpoints found in the selected submarine. Quickstart failed."); GameMain.MainMenuScreen.Select(); return; } var characterInfo = new CharacterInfo( Character.HumanConfigFile, jobPrefab: JobPrefab.List.Find(j => j.Identifier == jobIdentifiers[i])); if (characterInfo.Job == null) { DebugConsole.ThrowError("Failed to find the job \"" + jobIdentifiers[i] + "\"!"); } var newCharacter = Character.Create(Character.HumanConfigFile, spawnPoint.WorldPosition, ToolBox.RandomSeed(8), characterInfo); newCharacter.GiveJobItems(spawnPoint); gamesession.CrewManager.AddCharacter(newCharacter); Character.Controlled = newCharacter; } }
public override void Start(Level level) { Vector2 spawnPos; Level.Loaded.TryGetInterestingPosition(true, Level.PositionType.MainPath, Level.Loaded.Size.X * 0.3f, out spawnPos); monster = Character.Create(monsterFile, spawnPos, null, GameMain.Client != null, true, false); monster.Enabled = false; radarPosition = spawnPos; }
private IEnumerable <object> CreateAIHusk(Character character) { character.Enabled = false; Entity.Spawner.AddToRemoveQueue(character); string speciesName = GetHuskedSpeciesName(character.SpeciesName, Prefab as AfflictionPrefabHusk); string configFile = Character.GetConfigFilePath(speciesName); if (string.IsNullOrEmpty(configFile)) { DebugConsole.ThrowError("Failed to turn character \"" + character.Name + "\" into a husk - husk config file not found."); yield return(CoroutineStatus.Success); } var husk = Character.Create(configFile, character.WorldPosition, character.Info.Name, character.Info, isRemotePlayer: false, hasAi: true, ragdoll: character.AnimController.RagdollParams); foreach (Limb limb in husk.AnimController.Limbs) { if (limb.type == LimbType.None) { limb.body.SetTransform(character.SimPosition, 0.0f); continue; } var matchingLimb = character.AnimController.GetLimb(limb.type); if (matchingLimb?.body != null) { limb.body.SetTransform(matchingLimb.SimPosition, matchingLimb.Rotation); limb.body.LinearVelocity = matchingLimb.LinearVelocity; limb.body.AngularVelocity = matchingLimb.body.AngularVelocity; } } if (character.Inventory.Items.Length != husk.Inventory.Items.Length) { string errorMsg = "Failed to move items from the source character's inventory into a husk's inventory (inventory sizes don't match)"; DebugConsole.ThrowError(errorMsg); GameAnalyticsManager.AddErrorEventOnce("AfflictionHusk.CreateAIHusk:InventoryMismatch", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); yield return(CoroutineStatus.Success); } for (int i = 0; i < character.Inventory.Items.Length && i < husk.Inventory.Items.Length; i++) { if (character.Inventory.Items[i] == null) { continue; } husk.Inventory.TryPutItem(character.Inventory.Items[i], i, true, false, null); } yield return(CoroutineStatus.Success); }
private IEnumerable <object> CreateAIHusk(Character character) { character.Enabled = false; Entity.Spawner.AddToRemoveQueue(character); if (GameMain.Server != null) { GameMain.Server.ServerLog.WriteLine(character.Name + " Converted into an AI Husk!", Networking.ServerLog.MessageType.Husk); } var characterFiles = GameMain.SelectedPackage.GetFilesOfType(ContentType.Character); var configFile = characterFiles.Find(f => Path.GetFileNameWithoutExtension(f) == "humanhusk"); if (string.IsNullOrEmpty(configFile)) { DebugConsole.ThrowError("Failed to turn character \"" + character.Name + "\" into a husk - humanhusk config file not found."); yield return(CoroutineStatus.Success); } var husk = Character.Create(configFile, character.WorldPosition, character.Info, false, true); foreach (Limb limb in husk.AnimController.Limbs) { if (limb.type == LimbType.None) { limb.body.SetTransform(character.SimPosition, 0.0f); continue; } var matchingLimb = character.AnimController.GetLimb(limb.type); if (matchingLimb?.body != null) { limb.body.SetTransform(matchingLimb.SimPosition, matchingLimb.Rotation); limb.body.LinearVelocity = matchingLimb.LinearVelocity; limb.body.AngularVelocity = matchingLimb.body.AngularVelocity; } } for (int i = 0; i < character.Inventory.Items.Length; i++) { if (character.Inventory.Items[i] == null) { continue; } husk.Inventory.TryPutItem(character.Inventory.Items[i], i, true, false, null); } if (husk.AnimController.Limbs == null || husk.AnimController.Limbs.Length < 1) { DebugConsole.ThrowError("Error in Husk Creation, Character " + husk.Name + " has null or no limbs on creation!"); } yield return(CoroutineStatus.Success); }
public override void Start(Level level) { Level.Loaded.TryGetInterestingPosition(true, Level.PositionType.MainPath, Level.Loaded.Size.X * 0.3f, out Vector2 spawnPos); bool isClient = false; #if CLIENT isClient = GameMain.Client != null; #endif monster = Character.Create(monsterFile, spawnPos, ToolBox.RandomSeed(8), null, isClient, true, false); monster.Enabled = false; sonarPosition = spawnPos; }
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 override void Start(Level level) { Level.Loaded.TryGetInterestingPosition(true, Level.PositionType.MainPath, Level.Loaded.Size.X * 0.3f, out Vector2 spawnPos); bool isClient = GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient; for (int i = 0; i < monsterCount; i++) { monsters.Add(Character.Create(monsterFile, spawnPos, ToolBox.RandomSeed(8), null, isClient, true, false)); } monsters.ForEach(m => m.Enabled = false); SwarmBehavior.CreateSwarm(monsters.Cast <AICharacter>()); sonarPositions.Add(spawnPos); }
private void CreateDummyCharacter() { if (dummyCharacter != null) { RemoveDummyCharacter(); } dummyCharacter = Character.Create(Character.HumanConfigFile, Vector2.Zero); for (int i = 0; i < dummyCharacter.Inventory.SlotPositions.Length; i++) { dummyCharacter.Inventory.SlotPositions[i].X += leftPanel.Rect.Width + 10; } Character.Controlled = dummyCharacter; GameMain.World.ProcessChanges(); }
private void LoadHuman(HumanPrefab humanPrefab, XElement element, Submarine submarine) { string[] moduleFlags = element.GetAttributeStringArray("moduleflags", null); string[] spawnPointTags = element.GetAttributeStringArray("spawnpointtags", null); ISpatialEntity spawnPos = SpawnAction.GetSpawnPos( SpawnAction.SpawnLocationType.Outpost, SpawnType.Human, moduleFlags ?? humanPrefab.GetModuleFlags(), spawnPointTags ?? humanPrefab.GetSpawnPointTags(), element.GetAttributeBool("asfaraspossible", false)); if (spawnPos == null) { spawnPos = submarine.GetHulls(alsoFromConnectedSubs: false).GetRandom(); } var characterInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: humanPrefab.GetJobPrefab(Rand.RandSync.Server), randSync: Rand.RandSync.Server); Character spawnedCharacter = Character.Create(characterInfo.SpeciesName, spawnPos.WorldPosition, ToolBox.RandomSeed(8), characterInfo, createNetworkEvent: false); if (element.GetAttributeBool("requirerescue", false)) { requireRescue.Add(spawnedCharacter); spawnedCharacter.TeamID = CharacterTeamType.FriendlyNPC; #if CLIENT GameMain.GameSession.CrewManager.AddCharacterToCrewList(spawnedCharacter); #endif } else { spawnedCharacter.TeamID = CharacterTeamType.None; } humanPrefab.InitializeCharacter(spawnedCharacter, spawnPos); humanPrefab.GiveItems(spawnedCharacter, Submarine.MainSub, Rand.RandSync.Server, createNetworkEvents: false); if (spawnPos is WayPoint wp) { spawnedCharacter.GiveIdCardTags(wp); } if (element.GetAttributeBool("requirekill", false)) { requireKill.Add(spawnedCharacter); } characters.Add(spawnedCharacter); characterItems.Add(spawnedCharacter, spawnedCharacter.Inventory.FindAllItems(recursive: true)); }
public static void LoadPets(XElement petsElement) { foreach (XElement subElement in petsElement.Elements()) { string speciesName = subElement.GetAttributeString("speciesname", ""); string seed = subElement.GetAttributeString("seed", "123"); int ownerHash = subElement.GetAttributeInt("ownerhash", 0); Vector2 spawnPos = Vector2.Zero; Character owner = Character.CharacterList.Find(c => c.Info?.GetIdentifier() == ownerHash); if (owner != null && owner.Submarine?.Info.Type == SubmarineType.Player) { spawnPos = owner.WorldPosition; } else { //try to find a spawnpoint in the main sub var spawnPoint = WayPoint.WayPointList.Where(wp => wp.SpawnType == SpawnType.Human && wp.Submarine == Submarine.MainSub).GetRandom(); //if not found, try any player sub (shuttle/drone etc) spawnPoint ??= WayPoint.WayPointList.Where(wp => wp.SpawnType == SpawnType.Human && wp.Submarine?.Info.Type == SubmarineType.Player).GetRandom(); spawnPos = spawnPoint?.WorldPosition ?? Submarine.MainSub.WorldPosition; } var pet = Character.Create(speciesName, spawnPos, seed); var petBehavior = (pet?.AIController as EnemyAIController)?.PetBehavior; if (petBehavior != null) { petBehavior.Owner = owner; var petBehaviorElement = subElement.Element("petbehavior"); if (petBehaviorElement != null) { petBehavior.Hunger = petBehaviorElement.GetAttributeFloat("hunger", 50.0f); petBehavior.Happiness = petBehaviorElement.GetAttributeFloat("happiness", 50.0f); } } var inventoryElement = subElement.Element("inventory"); if (inventoryElement != null) { pet.SpawnInventoryItems(pet.Inventory, inventoryElement); } } }
protected Character CreateHuman(HumanPrefab humanPrefab, List <Character> characters, Dictionary <Character, List <Item> > characterItems, Submarine submarine, CharacterTeamType teamType, ISpatialEntity positionToStayIn = null, Rand.RandSync humanPrefabRandSync = Rand.RandSync.Server, bool giveTags = true) { if (positionToStayIn == null) { positionToStayIn = WayPoint.GetRandom(SpawnType.Human, null, submarine); } var characterInfo = humanPrefab.GetCharacterInfo(Rand.RandSync.Server) ?? new CharacterInfo(CharacterPrefab.HumanSpeciesName, npcIdentifier: humanPrefab.Identifier, jobPrefab: humanPrefab.GetJobPrefab(humanPrefabRandSync), randSync: humanPrefabRandSync); characterInfo.TeamID = teamType; Character spawnedCharacter = Character.Create(characterInfo.SpeciesName, positionToStayIn.WorldPosition, ToolBox.RandomSeed(8), characterInfo, createNetworkEvent: false); spawnedCharacter.Prefab = humanPrefab; humanPrefab.InitializeCharacter(spawnedCharacter, positionToStayIn); humanPrefab.GiveItems(spawnedCharacter, submarine, Rand.RandSync.Server, createNetworkEvents: false); characters.Add(spawnedCharacter); characterItems.Add(spawnedCharacter, spawnedCharacter.Inventory.FindAllItems(recursive: true)); return(spawnedCharacter); }
public void StartRound() { listBox.ClearChildren(); characters.Clear(); WayPoint[] waypoints = WayPoint.SelectCrewSpawnPoints(characterInfos, Submarine.MainSub); for (int i = 0; i < waypoints.Length; i++) { Character character; if (characterInfos[i].HullID != null) { var hull = Entity.FindEntityByID((ushort)characterInfos[i].HullID) as Hull; if (hull == null) { continue; } character = Character.Create(characterInfos[i], hull.WorldPosition); } else { character = Character.Create(characterInfos[i], waypoints[i].WorldPosition); Character.Controlled = character; if (character.Info != null && !character.Info.StartItemsGiven) { character.GiveJobItems(waypoints[i]); character.Info.StartItemsGiven = true; } } AddCharacter(character); } if (characters.Any()) { listBox.Select(0); // SelectCharacter(null, characters[0]); } }
private Character SpawnWatchman(Submarine outpost) { WayPoint watchmanSpawnpoint = WayPoint.WayPointList.Find(wp => wp.Submarine == outpost); if (watchmanSpawnpoint == null) { DebugConsole.ThrowError("Failed to spawn a watchman at the outpost. No spawnpoints found inside the outpost."); return(null); } string seed = outpost == Level.Loaded.StartOutpost ? map.SelectedLocation.Name : map.CurrentLocation.Name; Rand.SetSyncedSeed(ToolBox.StringToInt(seed)); JobPrefab watchmanJob = JobPrefab.Get("watchman"); var variant = Rand.Range(0, watchmanJob.Variants, Rand.RandSync.Server); CharacterInfo characterInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: watchmanJob, variant: variant); var spawnedCharacter = Character.Create(characterInfo, watchmanSpawnpoint.WorldPosition, Level.Loaded.Seed + (outpost == Level.Loaded.StartOutpost ? "start" : "end")); InitializeWatchman(spawnedCharacter); var objectiveManager = (spawnedCharacter.AIController as HumanAIController)?.ObjectiveManager; if (objectiveManager != null) { var moveOrder = new AIObjectiveGoTo(watchmanSpawnpoint, spawnedCharacter, objectiveManager, repeat: true, getDivingGearIfNeeded: false); moveOrder.Completed += () => { // Turn towards the center of the sub. Doesn't work in all possible cases, but this is the simplest solution for now. spawnedCharacter.AnimController.TargetDir = spawnedCharacter.Submarine.WorldPosition.X > spawnedCharacter.WorldPosition.X ? Direction.Right : Direction.Left; }; objectiveManager.SetOrder(moveOrder); } if (watchmanJob != null) { spawnedCharacter.GiveJobItems(); } return(spawnedCharacter); }
private IEnumerable <object> CreateAIHusk(Character character) { character.Enabled = false; Entity.Spawner.AddToRemoveQueue(character); var husk = Character.Create( Path.Combine("Content", "Characters", "Human", "humanhusk.xml"), character.WorldPosition, character.Info, false, true); foreach (Limb limb in husk.AnimController.Limbs) { if (limb.type == LimbType.None) { limb.body.SetTransform(character.SimPosition, 0.0f); continue; } var matchingLimb = character.AnimController.GetLimb(limb.type); if (matchingLimb?.body != null) { limb.body.SetTransform(matchingLimb.SimPosition, matchingLimb.Rotation); limb.body.LinearVelocity = matchingLimb.LinearVelocity; limb.body.AngularVelocity = matchingLimb.body.AngularVelocity; } } for (int i = 0; i < character.Inventory.Items.Length; i++) { if (character.Inventory.Items[i] == null) { continue; } husk.Inventory.TryPutItem(character.Inventory.Items[i], i, true, null); } yield return(CoroutineStatus.Success); }
public override void Start(Level level) { if (monsters.Count > 0) { #if DEBUG throw new Exception($"monsters.Count > 0 ({monsters.Count})"); #else DebugConsole.AddWarning("Monster list was not empty at the start of a monster mission. The mission instance may not have been ended correctly on previous rounds."); monsters.Clear(); #endif } if (tempSonarPositions.Count > 0) { #if DEBUG throw new Exception($"tempSonarPositions.Count > 0 ({tempSonarPositions.Count})"); #else DebugConsole.AddWarning("Sonar position list was not empty at the start of a monster mission. The mission instance may not have been ended correctly on previous rounds."); tempSonarPositions.Clear(); #endif } if (!IsClient) { Level.Loaded.TryGetInterestingPosition(true, Level.PositionType.MainPath | Level.PositionType.SidePath, Level.Loaded.Size.X * 0.3f, out Vector2 spawnPos); foreach (var monster in monsterPrefabs) { int amount = Rand.Range(monster.Item2.X, monster.Item2.Y + 1); for (int i = 0; i < amount; i++) { monsters.Add(Character.Create(monster.Item1.Identifier, spawnPos, ToolBox.RandomSeed(8), createNetworkEvent: false)); } } InitializeMonsters(monsters); } }
private void CharacterDead(Character character, CauseOfDeath causeOfDeath) { if (GameMain.Client != null) { return; } var husk = Character.Create( Path.Combine("Content", "Characters", "Human", "humanhusk.xml"), character.WorldPosition, character.Info, false, true); foreach (Limb limb in husk.AnimController.Limbs) { if (limb.type == LimbType.None) { limb.body.SetTransform(character.SimPosition, 0.0f); continue; } var matchingLimb = character.AnimController.GetLimb(limb.type); limb.body.SetTransform(matchingLimb.SimPosition, matchingLimb.Rotation); } for (int i = 0; i < character.Inventory.Items.Length; i++) { if (character.Inventory.Items[i] == null) { continue; } husk.Inventory.TryPutItem(character.Inventory.Items[i], i, true); } character.Enabled = false; Entity.Spawner.AddToRemoveQueue(character); }