예제 #1
0
 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);
 }
예제 #2
0
 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);
             }
         }
     }
 }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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);
            }
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
예제 #9
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.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);
        }
예제 #10
0
        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);
                }
            }
        }
예제 #11
0
        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);
        }
예제 #12
0
        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;
        }
예제 #13
0
            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);
            }
예제 #14
0
        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);
        }
예제 #15
0
        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;
            }
        }
예제 #16
0
        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;
        }
예제 #17
0
        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);
        }
예제 #18
0
        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);
        }
예제 #19
0
        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;
        }
예제 #20
0
            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);
            }
예제 #21
0
        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);
        }
예제 #22
0
        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();
        }
예제 #23
0
        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));
        }
예제 #24
0
        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);
                }
            }
        }
예제 #25
0
        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);
        }
예제 #26
0
        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]);
            }
        }
예제 #27
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);
        }
예제 #28
0
        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);
        }
예제 #29
0
        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);
            }
        }
예제 #30
0
        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);
        }