public void UseExistingSettings(BossEncounter newData)
 {
     this.SpawnGroupName     = newData.SpawnGroupName;
     this.SpawnGroup         = SpawnGroupManager.GetSpawnGroupByName(this.SpawnGroupName);
     this.Type               = newData.Type;
     this.Position           = newData.Position;
     this.PlayersInEncounter = newData.PlayersInEncounter;
     this.Timer              = newData.Timer;
     this.SpawnAttempts      = newData.SpawnAttempts;
     this.PlayerGPSHashes    = newData.PlayerGPSHashes;
 }
        public bool CreateGpsForPlayers()
        {
            this.SpawnGroup = SpawnGroupManager.GetSpawnGroupByName(this.SpawnGroupName);

            if (this.SpawnGroup == null)
            {
                return(false);
            }

            var playerList = new List <IMyPlayer>();

            MyAPIGateway.Players.GetPlayers(playerList);
            var bossGps = MyAPIGateway.Session.GPS.Create(this.SpawnGroup.BossCustomGPSLabel, "", this.Position, true);



            foreach (var player in playerList)
            {
                if (player.IsBot == true)
                {
                    continue;
                }

                if (this.PlayersInEncounter.Contains(player.IdentityId) == false)
                {
                    continue;
                }

                MyAPIGateway.Session.GPS.AddGps(player.IdentityId, bossGps);
                MyVisualScriptLogicProvider.SetGPSColor(this.SpawnGroup.BossCustomGPSLabel, new Color(255, 0, 255), player.IdentityId);

                if (PlayerGPSHashes.ContainsKey(player.IdentityId) == true)
                {
                    PlayerGPSHashes[player.IdentityId] = bossGps.Hash;
                }
                else
                {
                    PlayerGPSHashes.Add(player.IdentityId, bossGps.Hash);
                }
            }

            return(true);
        }
        public static string AttemptSpawn(Vector3D startCoords, List <string> eligibleNames = null)
        {
            if (Settings.General.UseMaxNpcGrids == true)
            {
                var totalNPCs = NPCWatcher.ActiveNPCs.Count;

                if (totalNPCs >= Settings.General.MaxGlobalNpcGrids)
                {
                    return("Spawning Aborted. Max Global NPCs Limit Reached.");
                }
            }

            if (NPCWatcher.ActiveNpcTypeLimitReachedForArea("PlanetaryCargoShip", startCoords, Settings.PlanetaryCargoShips.MaxShipsPerArea, Settings.PlanetaryCargoShips.AreaSize) == true)
            {
                return("Too Many Planetary Cargo Ship Grids in Player Area");
            }

            MyPlanet planet = SpawnResources.GetNearestPlanet(startCoords);

            if (SpawnResources.GetDistanceFromSurface(startCoords, planet) > Settings.PlanetaryCargoShips.PlayerSurfaceAltitude)
            {
                return("Player Is Too Far From Planet Surface.");
            }

            KnownPlayerLocationManager.CleanExpiredLocations();
            var validFactions  = new Dictionary <string, List <string> >();
            var spawnGroupList = GetPlanetaryCargoShips(startCoords, eligibleNames, out validFactions);

            if (Settings.General.UseModIdSelectionForSpawning == true)
            {
                spawnGroupList = SpawnResources.SelectSpawnGroupSublist(SpawnGroupSublists, EligibleSpawnsByModId);
            }

            if (spawnGroupList.Count == 0)
            {
                return("No Eligible Spawn Groups Could Be Found To Spawn Near Player.");
            }

            var spawnGroup = spawnGroupList[SpawnResources.rnd.Next(0, spawnGroupList.Count)];

            Vector3D startPathCoords = Vector3D.Zero;
            Vector3D endPathCoords   = Vector3D.Zero;
            MatrixD  startMatrix     = MatrixD.CreateWorld(Vector3D.Zero, Vector3D.Forward, Vector3D.Up);

            bool successfulPath = CalculateAtmoTravelPath(spawnGroup, startCoords, planet, out startPathCoords, out endPathCoords, out startMatrix);

            if (successfulPath == false)
            {
                return("Could Not Generate Safe Travel Path For SpawnGroup.");
            }

            //Get Directions
            var  spawnForwardDir = startMatrix.Forward;
            var  spawnUpDir      = startMatrix.Up;
            var  spawnMatrix     = startMatrix;
            long gridOwner       = 0;
            var  randFactionTag  = spawnGroup.FactionOwner;

            if (validFactions.ContainsKey(spawnGroup.SpawnGroupName))
            {
                randFactionTag = validFactions[spawnGroup.SpawnGroupName][SpawnResources.rnd.Next(0, validFactions[spawnGroup.SpawnGroupName].Count)];
            }

            if (NPCWatcher.NPCFactionTagToFounder.ContainsKey(randFactionTag) == true)
            {
                gridOwner = NPCWatcher.NPCFactionTagToFounder[randFactionTag];
            }
            else
            {
                Logger.AddMsg("Could Not Find Faction Founder For: " + randFactionTag);
            }

            foreach (var prefab in spawnGroup.SpawnGroup.Prefabs)
            {
                if (spawnGroup.UseKnownPlayerLocations)
                {
                    KnownPlayerLocationManager.IncreaseSpawnCountOfLocations(startCoords, randFactionTag);
                }

                var options       = SpawnGroupManager.CreateSpawningOptions(spawnGroup, prefab);
                var spawnPosition = Vector3D.Transform((Vector3D)prefab.Position, spawnMatrix);
                var speedL        = prefab.Speed;
                var speedA        = Vector3.Zero;
                var gridList      = new List <IMyCubeGrid>();


                //Speed Management
                if (Settings.PlanetaryCargoShips.UseMinimumSpeed == true && prefab.Speed < Settings.PlanetaryCargoShips.MinimumSpeed)
                {
                    speedL = Settings.PlanetaryCargoShips.MinimumSpeed;
                }

                if (Settings.PlanetaryCargoShips.UseSpeedOverride == true)
                {
                    speedL = Settings.PlanetaryCargoShips.SpeedOverride;
                }



                /*//Character Injection - Start
                 * MyPrefabDefinition prefabDefB = null;
                 *
                 * if(SpawnGroupManager.prefabBackupList.ContainsKey(prefab.SubtypeId) == true){
                 *
                 *      prefabDefB = MyDefinitionManager.Static.GetPrefabDefinition(prefab.SubtypeId);
                 *
                 *      if(SpawnGroupManager.prefabBackupList[prefab.SubtypeId].Count == prefabDefB.CubeGrids.Length){
                 *
                 *              for(int i = 0; i < SpawnGroupManager.prefabBackupList[prefab.SubtypeId].Count; i++){
                 *
                 *                      var clonedGridOb = SpawnGroupManager.prefabBackupList[prefab.SubtypeId][i].Clone();
                 *                      prefabDefB.CubeGrids[i] = clonedGridOb as MyObjectBuilder_CubeGrid;
                 *
                 *              }
                 *
                 *      }
                 *
                 *      SpawnGroupManager.prefabBackupList.Remove(prefab.SubtypeId);
                 *
                 * }
                 *
                 * var injectedCharacters = false;
                 * if(spawnGroup.FillSeatsWithNpcCrew == true){
                 *
                 *      injectedCharacters = true;
                 *
                 *      if(prefabDefB == null){
                 *
                 *              prefabDefB = MyDefinitionManager.Static.GetPrefabDefinition(prefab.SubtypeId);
                 *
                 *      }
                 *
                 *      var backupGridList = new List<MyObjectBuilder_CubeGrid>();
                 *
                 *      for(int i = 0; i < prefabDefB.CubeGrids.Length; i++){
                 *
                 *              var clonedGridOb = prefabDefB.CubeGrids[i].Clone();
                 *              backupGridList.Add(clonedGridOb as MyObjectBuilder_CubeGrid);
                 *              GridUtilities.CreateAndAttachCrew(prefabDefB.CubeGrids[i], spawnGroup, gridOwner);
                 *
                 *      }
                 *
                 *      if(SpawnGroupManager.prefabBackupList.ContainsKey(prefab.SubtypeId) == false){
                 *
                 *              SpawnGroupManager.prefabBackupList.Add(prefab.SubtypeId, backupGridList);
                 *
                 *      }
                 *
                 * }
                 * //Character Injection - End*/

                //Grid Manipulation
                GridBuilderManipulation.ProcessPrefabForManipulation(prefab.SubtypeId, spawnGroup, "PlanetaryCargoShip", prefab.Behaviour);

                try{
                    MyAPIGateway.PrefabManager.SpawnPrefab(gridList, prefab.SubtypeId, spawnPosition, spawnForwardDir, spawnUpDir, Vector3.Zero, Vector3.Zero, !string.IsNullOrWhiteSpace(prefab.BeaconText) ? prefab.BeaconText : null, options, gridOwner);
                }catch (Exception exc) {
                }

                var pendingNPC = new ActiveNPC();
                pendingNPC.SpawnGroup            = spawnGroup;
                pendingNPC.SpawnGroupName        = spawnGroup.SpawnGroupName;
                pendingNPC.InitialFaction        = randFactionTag;
                pendingNPC.faction               = MyAPIGateway.Session.Factions.TryGetFactionByTag(pendingNPC.InitialFaction);
                pendingNPC.Name                  = prefab.SubtypeId;
                pendingNPC.GridName              = MyDefinitionManager.Static.GetPrefabDefinition(prefab.SubtypeId).CubeGrids[0].DisplayName;
                pendingNPC.StartCoords           = startPathCoords;
                pendingNPC.CurrentCoords         = startPathCoords;
                pendingNPC.EndCoords             = endPathCoords;
                pendingNPC.AutoPilotSpeed        = speedL;
                pendingNPC.Planet                = planet;
                pendingNPC.SpawnType             = "PlanetaryCargoShip";
                pendingNPC.CleanupIgnore         = spawnGroup.IgnoreCleanupRules;
                pendingNPC.ForceStaticGrid       = spawnGroup.ForceStaticGrid;
                pendingNPC.KeenAiName            = prefab.Behaviour;
                pendingNPC.KeenAiTriggerDistance = prefab.BehaviourActivationDistance;

                if (spawnGroup.RandomizeWeapons == true)
                {
                    pendingNPC.ReplenishedSystems = false;
                    pendingNPC.ReplacedWeapons    = true;
                }
                else if ((MES_SessionCore.NPCWeaponUpgradesModDetected == true || Settings.General.EnableGlobalNPCWeaponRandomizer == true) && spawnGroup.IgnoreWeaponRandomizerMod == false)
                {
                    pendingNPC.ReplenishedSystems = false;
                    pendingNPC.ReplacedWeapons    = true;
                }
                else if (spawnGroup.ReplenishSystems == true)
                {
                    pendingNPC.ReplenishedSystems = false;
                }

                NPCWatcher.PendingNPCs.Add(pendingNPC);
            }

            Logger.SkipNextMessage = false;
            return("Spawning Group - " + spawnGroup.SpawnGroup.Id.SubtypeName);
        }
        public static string AttemptSpawn(Vector3D startCoords, IMyPlayer player)
        {
            if (Settings.General.UseMaxNpcGrids == true)
            {
                var totalNPCs = NPCWatcher.ActiveNPCs.Count;

                if (totalNPCs >= Settings.General.MaxGlobalNpcGrids)
                {
                    return("Spawning Aborted. Max Global NPCs Limit Reached.");
                }
            }

            if (NPCWatcher.ActiveNpcTypeLimitReachedForArea("PlanetaryInstallation", startCoords, Settings.PlanetaryInstallations.MaxShipsPerArea, Settings.PlanetaryInstallations.AreaSize) == true)
            {
                return("Too Many Planetary Installation Grids in Player Area");
            }

            MyPlanet planet = SpawnResources.GetNearestPlanet(startCoords);

            if (planet == null)
            {
                return("No Planets In Game World Found.");
            }
            else
            {
                if (SpawnResources.GetDistanceFromSurface(startCoords, planet) > Settings.PlanetaryInstallations.PlayerMaximumDistanceFromSurface || SpawnResources.IsPositionInGravity(startCoords, planet) == false)
                {
                    return("Player Not In Planet Gravity Or Too Far From Surface.");
                }
            }

            var planetEntity = planet as IMyEntity;

            if (MES_SessionCore.playerWatchList.ContainsKey(player) == true)
            {
                var playerSurface = SpawnResources.GetNearestSurfacePoint(player.GetPosition(), planet);

                if (MES_SessionCore.playerWatchList[player].InstallationDistanceCoordCheck == Vector3D.Zero)
                {
                    MES_SessionCore.playerWatchList[player].InstallationDistanceCoordCheck = playerSurface;
                    return("New Player Detected. Storing Position On Planet.");
                }

                if (Vector3D.Distance(MES_SessionCore.playerWatchList[player].InstallationDistanceCoordCheck, playerSurface) < Settings.PlanetaryInstallations.PlayerDistanceSpawnTrigger)
                {
                    Logger.AddMsg("Player Travelled: " + Vector3D.Distance(MES_SessionCore.playerWatchList[player].InstallationDistanceCoordCheck, playerSurface) + " Distance From Last Saved Position.");
                    return("Player Hasn't Traveled Far Enough Yet.");
                }

                MES_SessionCore.playerWatchList[player].InstallationDistanceCoordCheck = playerSurface;
            }
            else
            {
                return("Player Not In Watcher List... Although They Probably Should Be If The Script Got Here.");
            }

            var smallStations  = new List <ImprovedSpawnGroup>();
            var mediumStations = new List <ImprovedSpawnGroup>();
            var largeStations  = new List <ImprovedSpawnGroup>();
            var validFactions  = new Dictionary <string, List <string> >();
            var spawnGroupList = GetPlanetaryInstallations(startCoords, out smallStations, out mediumStations, out largeStations, out validFactions);

            if (Settings.General.UseModIdSelectionForSpawning == true)
            {
                spawnGroupList = SpawnResources.SelectSpawnGroupSublist(SpawnGroupSublists, EligibleSpawnsByModId);
                smallStations  = SpawnResources.SelectSpawnGroupSublist(SmallSpawnGroupSublists, EligibleSmallSpawnsByModId);
                mediumStations = SpawnResources.SelectSpawnGroupSublist(MediumSpawnGroupSublists, EligibleMediumSpawnsByModId);
                largeStations  = SpawnResources.SelectSpawnGroupSublist(LargeSpawnGroupSublists, EligibleLargeSpawnsByModId);
            }

            if (spawnGroupList.Count == 0)
            {
                return("No Eligible Spawn Groups Could Be Found To Spawn Near Player.");
            }

            Logger.AddMsg("Found " + (spawnGroupList.Count / 10).ToString() + " Potential Spawn Groups. Small: " + (smallStations.Count / 10).ToString() + " // Medium: " + (mediumStations.Count / 10).ToString() + " // Large: " + (largeStations.Count / 10).ToString(), true);

            string stationSize = "Small";

            spawnGroupList = smallStations;

            bool skippedAbsentSmall  = false;
            bool skippedAbsentMedium = false;
            bool skippedAbsentLarge  = false;

            //Start With Small Station Always, Try Chance For Medium.
            if (stationSize == "Small" && smallStations.Count == 0)
            {
                //No Small Stations Available For This Area, So Try Medium.
                skippedAbsentSmall = true;
                stationSize        = "Medium";
                spawnGroupList     = mediumStations;
            }
            else if (stationSize == "Small" && smallStations.Count != 0)
            {
                int    mediumChance = 0;
                string varName      = "MES-" + planetEntity.EntityId.ToString() + "-Medium";

                if (MyAPIGateway.Utilities.GetVariable <int>(varName, out mediumChance) == false)
                {
                    mediumChance = Settings.PlanetaryInstallations.MediumSpawnChanceBaseValue;
                    MyAPIGateway.Utilities.SetVariable <int>(varName, mediumChance);
                }

                if (SpawnResources.rnd.Next(0, 100) < mediumChance)
                {
                    stationSize    = "Medium";
                    spawnGroupList = mediumStations;
                }
            }

            if (stationSize == "Medium" && mediumStations.Count == 0)
            {
                //No Medium Stations Available For This Area, So Try Large.
                skippedAbsentMedium = true;
                stationSize         = "Large";
                spawnGroupList      = largeStations;
            }
            else if (stationSize == "Medium" && mediumStations.Count != 0)
            {
                int    largeChance = 0;
                string varName     = "MES-" + planetEntity.EntityId.ToString() + "-Large";

                if (MyAPIGateway.Utilities.GetVariable <int>(varName, out largeChance) == false)
                {
                    largeChance = Settings.PlanetaryInstallations.LargeSpawnChanceBaseValue;
                    MyAPIGateway.Utilities.SetVariable <int>(varName, largeChance);
                }

                if (SpawnResources.rnd.Next(0, 100) < largeChance)
                {
                    stationSize    = "Large";
                    spawnGroupList = largeStations;
                }
            }

            if (stationSize == "Large" && largeStations.Count == 0)
            {
                skippedAbsentLarge = true;
                stationSize        = "Medium";
                spawnGroupList     = mediumStations;

                if (mediumStations.Count == 0)
                {
                    skippedAbsentMedium = true;
                    stationSize         = "Small";
                    spawnGroupList      = smallStations;
                }
            }

            if (spawnGroupList.Count == 0)
            {
                return("Could Not Find Station Of Suitable Size For This Spawn Instance.");
            }

            var      spawnGroup  = spawnGroupList[SpawnResources.rnd.Next(0, spawnGroupList.Count)];
            Vector3D spawnCoords = Vector3D.Zero;

            Logger.StartTimer();

            if (GetSpawnCoords(spawnGroup, startCoords, out spawnCoords) == false)
            {
                Logger.AddMsg("Planetary Installation Spawn Coord Calculation Time: " + Logger.StopTimer(), true);
                return("Could Not Find Safe Position To Spawn " + stationSize + " Installation.");
            }

            Logger.AddMsg("Planetary Installation Spawn Coord Calculation Time: " + Logger.StopTimer(), true);

            //Get Directions
            var upDir                = Vector3D.Normalize(spawnCoords - planetEntity.GetPosition());
            var forwardDir           = Vector3D.CalculatePerpendicularVector(upDir);
            var spawnMatrix          = MatrixD.CreateWorld(spawnCoords, forwardDir, upDir);
            var successfulVoxelSpawn = false;

            foreach (var voxel in spawnGroup.SpawnGroup.Voxels)
            {
                var voxelSpawningPosition = Vector3D.Transform((Vector3D)voxel.Offset, spawnMatrix);

                try{
                    var voxelSpawn = MyAPIGateway.Session.VoxelMaps.CreateVoxelMapFromStorageName(voxel.StorageName, voxel.StorageName, voxelSpawningPosition);

                    if (Settings.PlanetaryInstallations.RemoveVoxelsIfGridRemoved == true && spawnGroup.RemoveVoxelsIfGridRemoved == true)
                    {
                        NPCWatcher.SpawnedVoxels.Add(voxelSpawn.EntityId.ToString(), voxelSpawn as IMyEntity);
                    }

                    successfulVoxelSpawn = true;
                }catch (Exception exc) {
                    Logger.AddMsg("Voxel Spawning For " + voxel.StorageName + " Failed");
                }
            }

            if (successfulVoxelSpawn == true)
            {
                var      voxelIdList  = new List <string>(NPCWatcher.SpawnedVoxels.Keys.ToList());
                string[] voxelIdArray = voxelIdList.ToArray();
                MyAPIGateway.Utilities.SetVariable <string[]>("MES-SpawnedVoxels", voxelIdArray);
            }

            long gridOwner      = 0;
            var  randFactionTag = spawnGroup.FactionOwner;

            if (validFactions.ContainsKey(spawnGroup.SpawnGroupName))
            {
                randFactionTag = validFactions[spawnGroup.SpawnGroupName][SpawnResources.rnd.Next(0, validFactions[spawnGroup.SpawnGroupName].Count)];
            }

            if (NPCWatcher.NPCFactionTagToFounder.ContainsKey(randFactionTag) == true)
            {
                gridOwner = NPCWatcher.NPCFactionTagToFounder[randFactionTag];
            }
            else
            {
                Logger.AddMsg("Could Not Find Faction Founder For: " + randFactionTag);
            }

            for (int i = 0; i < spawnGroup.SpawnGroup.Prefabs.Count; i++)
            {
                var prefab        = spawnGroup.SpawnGroup.Prefabs[i];
                var options       = SpawnGroupManager.CreateSpawningOptions(spawnGroup, prefab);
                var spawnPosition = Vector3D.Transform((Vector3D)prefab.Position, spawnMatrix);

                //Realign to Terrain
                var offsetSurfaceCoords = SpawnResources.GetNearestSurfacePoint(spawnPosition, planet);
                var offsetSurfaceMatrix = MatrixD.CreateWorld(offsetSurfaceCoords, forwardDir, upDir);
                var finalCoords         = Vector3D.Transform(new Vector3D(0, (double)prefab.Position.Y, 0), offsetSurfaceMatrix);

                var newForward = offsetSurfaceMatrix.Forward;
                var newUp      = offsetSurfaceMatrix.Up;

                GetReversedForwardDirections(spawnGroup, i, ref newForward);
                GetDerelictDirections(spawnGroup, i, finalCoords, ref newForward, ref newUp);

                var speedL   = Vector3.Zero;
                var speedA   = Vector3.Zero;
                var gridList = new List <IMyCubeGrid>();

                //Grid Manipulation
                GridBuilderManipulation.ProcessPrefabForManipulation(prefab.SubtypeId, spawnGroup, "PlanetaryInstallation", prefab.Behaviour);

                try{
                    MyAPIGateway.PrefabManager.SpawnPrefab(gridList, prefab.SubtypeId, finalCoords, newForward, newUp, speedL, speedA, prefab.BeaconText, options, gridOwner);
                }catch (Exception exc) {
                }

                Logger.AddMsg("Installation Forward Vector: " + newForward.ToString(), true);
                var pendingNPC = new ActiveNPC();
                pendingNPC.SpawnGroup            = spawnGroup;
                pendingNPC.SpawnGroupName        = spawnGroup.SpawnGroupName;
                pendingNPC.InitialFaction        = randFactionTag;
                pendingNPC.faction               = MyAPIGateway.Session.Factions.TryGetFactionByTag(pendingNPC.InitialFaction);
                pendingNPC.Name                  = prefab.SubtypeId;
                pendingNPC.GridName              = MyDefinitionManager.Static.GetPrefabDefinition(prefab.SubtypeId).CubeGrids[0].DisplayName;
                pendingNPC.StartCoords           = finalCoords;
                pendingNPC.CurrentCoords         = finalCoords;
                pendingNPC.EndCoords             = finalCoords;
                pendingNPC.SpawnType             = "PlanetaryInstallation";
                pendingNPC.CleanupIgnore         = spawnGroup.IgnoreCleanupRules;
                pendingNPC.ForceStaticGrid       = spawnGroup.ForceStaticGrid;
                pendingNPC.KeenAiName            = prefab.Behaviour;
                pendingNPC.KeenAiTriggerDistance = prefab.BehaviourActivationDistance;

                if (spawnGroup.RandomizeWeapons == true)
                {
                    pendingNPC.ReplenishedSystems = false;
                    pendingNPC.ReplacedWeapons    = true;
                }
                else if ((MES_SessionCore.NPCWeaponUpgradesModDetected == true || Settings.General.EnableGlobalNPCWeaponRandomizer == true) && spawnGroup.IgnoreWeaponRandomizerMod == false)
                {
                    pendingNPC.ReplenishedSystems = false;
                    pendingNPC.ReplacedWeapons    = true;
                }
                else if (spawnGroup.ReplenishSystems == true)
                {
                    pendingNPC.ReplenishedSystems = false;
                }

                NPCWatcher.PendingNPCs.Add(pendingNPC);
            }

            if (spawnGroup.PlanetaryInstallationType == "Small")
            {
                int    mediumChance = 0;
                string varName      = "MES-" + planetEntity.EntityId.ToString() + "-Medium";
                if (MyAPIGateway.Utilities.GetVariable <int>(varName, out mediumChance) == true)
                {
                    mediumChance += Settings.PlanetaryInstallations.MediumSpawnChanceIncrement;
                    MyAPIGateway.Utilities.SetVariable <int>(varName, mediumChance);
                }

                Logger.AddMsg("Medium Installation Spawning Chance Now Set To: " + mediumChance.ToString() + " / 100", true);
            }

            if (spawnGroup.PlanetaryInstallationType == "Medium" || skippedAbsentMedium == true)
            {
                int    mediumChance = 0;
                string varName      = "MES-" + planetEntity.EntityId.ToString() + "-Medium";
                if (MyAPIGateway.Utilities.GetVariable <int>(varName, out mediumChance) == true)
                {
                    mediumChance = Settings.PlanetaryInstallations.MediumSpawnChanceBaseValue;
                    MyAPIGateway.Utilities.SetVariable <int>(varName, mediumChance);
                }

                Logger.AddMsg("Medium Installation Spawning Chance Now Set To: " + mediumChance.ToString() + " / 100", true);

                int largeChance = 0;
                varName = "MES-" + planetEntity.EntityId.ToString() + "-Large";
                if (MyAPIGateway.Utilities.GetVariable <int>(varName, out largeChance) == true)
                {
                    largeChance += Settings.PlanetaryInstallations.LargeSpawnChanceIncrement;
                    MyAPIGateway.Utilities.SetVariable <int>(varName, largeChance);
                }

                Logger.AddMsg("Large Installation Spawning Chance Now Set To: " + largeChance.ToString() + " / 100", true);
            }

            if (spawnGroup.PlanetaryInstallationType == "Large" || skippedAbsentLarge == true)
            {
                int    largeChance = 0;
                string varName     = "MES-" + planetEntity.EntityId.ToString() + "-Large";
                if (MyAPIGateway.Utilities.GetVariable <int>(varName, out largeChance) == true)
                {
                    largeChance = Settings.PlanetaryInstallations.LargeSpawnChanceBaseValue;
                    MyAPIGateway.Utilities.SetVariable <int>(varName, largeChance);
                }

                Logger.AddMsg("Large Installation Spawning Chance Now Set To: " + largeChance.ToString() + " / 100", true);
            }

            if (spawnGroup.UniqueEncounter == true)
            {
                SpawnGroupManager.UniqueGroupsSpawned.Add(spawnGroup.SpawnGroup.Id.SubtypeName);
                string[] uniqueSpawnedArray = SpawnGroupManager.UniqueGroupsSpawned.ToArray();
                MyAPIGateway.Utilities.SetVariable <string[]>("MES-UniqueGroupsSpawned", uniqueSpawnedArray);
            }

            Logger.SkipNextMessage = false;
            return("Spawning Group - " + spawnGroup.SpawnGroup.Id.SubtypeName);
        }
        public static NPCTerritory GetNewTerritoryDetails(MySpawnGroupDefinition spawnGroup)
        {
            var territory  = new NPCTerritory();
            var descSplit  = spawnGroup.DescriptionText.Split('\n');
            var tempCoords = Vector3D.Zero;

            foreach (var tag in descSplit)
            {
                //Name
                if (tag.Contains("[Name") == true)
                {
                    bool badParse = false;
                    territory.Name = SpawnGroupManager.TagStringCheck(tag, spawnGroup.Id.SubtypeName, out badParse);

                    if (territory.BadTerritory == false && badParse == true)
                    {
                        territory.BadTerritory = true;
                    }
                }

                //Type
                if (tag.Contains("[Type") == true)
                {
                    bool badParse = false;
                    territory.Type = SpawnGroupManager.TagStringCheck(tag, spawnGroup.Id.SubtypeName, out badParse);

                    if (territory.BadTerritory == false && badParse == true)
                    {
                        territory.BadTerritory = true;
                    }
                }

                //Active
                if (tag.Contains("[Active") == true)
                {
                    bool badParse = false;
                    territory.Active = SpawnGroupManager.TagBoolCheck(tag, spawnGroup.Id.SubtypeName, out badParse);

                    if (territory.BadTerritory == false && badParse == true)
                    {
                        territory.BadTerritory = true;
                    }
                }

                //Radius
                if (tag.Contains("[Radius") == true)
                {
                    bool badParse = false;
                    territory.Radius = SpawnGroupManager.TagDoubleCheck(tag, spawnGroup.Id.SubtypeName, territory.Radius, out badParse);

                    if (territory.BadTerritory == false && badParse == true)
                    {
                        territory.BadTerritory = true;
                    }
                }

                //ScaleRadiusWithPlanetSize
                if (tag.Contains("[ScaleRadiusWithPlanetSize") == true)
                {
                    bool badParse = false;
                    territory.ScaleRadiusWithPlanetSize = SpawnGroupManager.TagBoolCheck(tag, spawnGroup.Id.SubtypeName, out badParse);

                    if (territory.BadTerritory == false && badParse == true)
                    {
                        territory.BadTerritory = true;
                    }
                }

                //NoSpawnZone
                if (tag.Contains("[NoSpawnZone") == true)
                {
                    bool badParse = false;
                    territory.NoSpawnZone = SpawnGroupManager.TagBoolCheck(tag, spawnGroup.Id.SubtypeName, out badParse);

                    if (territory.BadTerritory == false && badParse == true)
                    {
                        territory.BadTerritory = true;
                    }
                }

                //StrictTerritory
                if (tag.Contains("[StrictTerritory") == true)
                {
                    bool badParse = false;
                    territory.StrictTerritory = SpawnGroupManager.TagBoolCheck(tag, spawnGroup.Id.SubtypeName, out badParse);

                    if (territory.BadTerritory == false && badParse == true)
                    {
                        territory.BadTerritory = true;
                    }
                }

                //FactionTagWhitelist
                if (tag.Contains("[FactionTagWhitelist") == true)
                {
                    bool badParse = false;
                    territory.FactionTagWhitelist = SpawnGroupManager.TagStringListCheck(tag, spawnGroup.Id.SubtypeName, out badParse);

                    if (territory.BadTerritory == false && badParse == true)
                    {
                        territory.BadTerritory = true;
                    }
                }

                //FactionTagBlacklist
                if (tag.Contains("[FactionTagBlacklist") == true)
                {
                    bool badParse = false;
                    territory.FactionTagBlacklist = SpawnGroupManager.TagStringListCheck(tag, spawnGroup.Id.SubtypeName, out badParse);

                    if (territory.BadTerritory == false && badParse == true)
                    {
                        territory.BadTerritory = true;
                    }
                }

                //CoordsX
                if (tag.Contains("[CoordsX") == true)
                {
                    bool badParse = false;
                    tempCoords.X = SpawnGroupManager.TagDoubleCheck(tag, spawnGroup.Id.SubtypeName, territory.Position.X, out badParse);

                    if (territory.BadTerritory == false && badParse == true)
                    {
                        territory.BadTerritory = true;
                    }
                }

                //CoordsY
                if (tag.Contains("[CoordsY") == true)
                {
                    bool badParse = false;
                    tempCoords.Y = SpawnGroupManager.TagDoubleCheck(tag, spawnGroup.Id.SubtypeName, territory.Position.Y, out badParse);

                    if (territory.BadTerritory == false && badParse == true)
                    {
                        territory.BadTerritory = true;
                    }
                }

                //CoordsZ
                if (tag.Contains("[CoordsZ") == true)
                {
                    bool badParse = false;
                    tempCoords.Z = SpawnGroupManager.TagDoubleCheck(tag, spawnGroup.Id.SubtypeName, territory.Position.Z, out badParse);

                    if (territory.BadTerritory == false && badParse == true)
                    {
                        territory.BadTerritory = true;
                    }
                }

                //AnnounceArriveDepart
                if (tag.Contains("[AnnounceArriveDepart") == true)
                {
                    bool badParse = false;
                    territory.AnnounceArriveDepart = SpawnGroupManager.TagBoolCheck(tag, spawnGroup.Id.SubtypeName, out badParse);

                    if (territory.BadTerritory == false && badParse == true)
                    {
                        territory.BadTerritory = true;
                    }
                }

                //CustomArriveMessage
                if (tag.Contains("[CustomArriveMessage") == true)
                {
                    bool badParse = false;
                    territory.CustomArriveMessage = SpawnGroupManager.TagStringCheck(tag, spawnGroup.Id.SubtypeName, out badParse);

                    if (territory.BadTerritory == false && badParse == true)
                    {
                        territory.BadTerritory = true;
                    }
                }

                //CustomDepartMessage
                if (tag.Contains("[CustomDepartMessage") == true)
                {
                    bool badParse = false;
                    territory.CustomDepartMessage = SpawnGroupManager.TagStringCheck(tag, spawnGroup.Id.SubtypeName, out badParse);

                    if (territory.BadTerritory == false && badParse == true)
                    {
                        territory.BadTerritory = true;
                    }
                }

                //PlanetGeneratorName
                if (tag.Contains("[PlanetGeneratorName") == true)
                {
                    bool badParse = false;
                    territory.PlanetGeneratorName = SpawnGroupManager.TagStringCheck(tag, spawnGroup.Id.SubtypeName, out badParse);

                    if (territory.BadTerritory == false && badParse == true)
                    {
                        territory.BadTerritory = true;
                    }
                }
            }

            territory.Position = tempCoords;

            return(territory);
        }
        public static string AttemptSpawn(Vector3D startCoords)
        {
            if (Settings.General.UseMaxNpcGrids == true)
            {
                var totalNPCs = NPCWatcher.ActiveNPCs.Count;

                if (totalNPCs >= Settings.General.MaxGlobalNpcGrids)
                {
                    return("Spawning Aborted. Max Global NPCs Limit Reached.");
                }
            }

            if (NPCWatcher.ActiveNpcTypeLimitReachedForArea("SpaceCargoShip", startCoords, Settings.SpaceCargoShips.MaxShipsPerArea, Settings.SpaceCargoShips.AreaSize) == true)
            {
                return("Too Many Space Cargo Ship Grids in Player Area");
            }

            var validFactions  = new Dictionary <string, List <string> >();
            var spawnGroupList = GetSpaceCargoShips(startCoords, out validFactions);

            if (Settings.General.UseModIdSelectionForSpawning == true)
            {
                spawnGroupList = SpawnResources.SelectSpawnGroupSublist(SpawnGroupSublists, EligibleSpawnsByModId);
            }

            if (spawnGroupList.Count == 0)
            {
                return("No Eligible Spawn Groups Could Be Found To Spawn Near Player.");
            }

            var      spawnGroup      = spawnGroupList[SpawnResources.rnd.Next(0, spawnGroupList.Count)];
            var      startPathCoords = Vector3D.Zero;
            var      endPathCoords   = Vector3D.Zero;
            bool     successfulPath  = false;
            MyPlanet planet          = SpawnResources.GetNearestPlanet(startCoords);

            if (SpawnResources.LunarSpawnEligible(startCoords) == false)
            {
                successfulPath = CalculateRegularTravelPath(spawnGroup.SpawnGroup, startCoords, out startPathCoords, out endPathCoords);
            }
            else
            {
                successfulPath = CalculateLunarTravelPath(spawnGroup.SpawnGroup, startCoords, out startPathCoords, out endPathCoords);
            }

            if (successfulPath == false)
            {
                return("Could Not Generate Safe Travel Path For SpawnGroup.");
            }

            //Get Directions
            var  spawnForwardDir = Vector3D.Normalize(endPathCoords - startPathCoords);
            var  spawnUpDir      = Vector3D.CalculatePerpendicularVector(spawnForwardDir);
            var  spawnMatrix     = MatrixD.CreateWorld(startPathCoords, spawnForwardDir, spawnUpDir);
            long gridOwner       = 0;
            var  randFactionTag  = spawnGroup.FactionOwner;

            if (validFactions.ContainsKey(spawnGroup.SpawnGroupName))
            {
                randFactionTag = validFactions[spawnGroup.SpawnGroupName][SpawnResources.rnd.Next(0, validFactions[spawnGroup.SpawnGroupName].Count)];
            }

            if (NPCWatcher.NPCFactionTagToFounder.ContainsKey(randFactionTag) == true)
            {
                gridOwner = NPCWatcher.NPCFactionTagToFounder[randFactionTag];
            }
            else
            {
                Logger.AddMsg("Could Not Find Faction Founder For: " + randFactionTag);
            }

            foreach (var prefab in spawnGroup.SpawnGroup.Prefabs)
            {
                var options       = SpawnGroupManager.CreateSpawningOptions(spawnGroup, prefab);
                var spawnPosition = Vector3D.Transform((Vector3D)prefab.Position, spawnMatrix);
                var speedL        = prefab.Speed * (Vector3)spawnForwardDir;
                var speedA        = Vector3.Zero;
                var gridList      = new List <IMyCubeGrid>();


                //Speed Management
                if (Settings.SpaceCargoShips.UseMinimumSpeed == true && prefab.Speed < Settings.SpaceCargoShips.MinimumSpeed)
                {
                    speedL = Settings.SpaceCargoShips.MinimumSpeed * (Vector3)spawnForwardDir;
                }

                if (Settings.SpaceCargoShips.UseSpeedOverride == true)
                {
                    speedL = Settings.SpaceCargoShips.SpeedOverride * (Vector3)spawnForwardDir;
                }



                //Grid Manipulation
                GridBuilderManipulation.ProcessPrefabForManipulation(prefab.SubtypeId, spawnGroup, "SpaceCargoShip", prefab.Behaviour);

                try{
                    MyAPIGateway.PrefabManager.SpawnPrefab(gridList, prefab.SubtypeId, spawnPosition, spawnForwardDir, spawnUpDir, speedL, speedA, prefab.BeaconText, options, gridOwner);
                }catch (Exception exc) {
                    Logger.AddMsg("Something Went Wrong With Prefab Spawn Manager.", true);
                }

                var pendingNPC = new ActiveNPC();
                pendingNPC.SpawnGroupName        = spawnGroup.SpawnGroupName;
                pendingNPC.SpawnGroup            = spawnGroup;
                pendingNPC.InitialFaction        = randFactionTag;
                pendingNPC.faction               = MyAPIGateway.Session.Factions.TryGetFactionByTag(pendingNPC.InitialFaction);
                pendingNPC.Name                  = prefab.SubtypeId;
                pendingNPC.GridName              = MyDefinitionManager.Static.GetPrefabDefinition(prefab.SubtypeId).CubeGrids[0].DisplayName;
                pendingNPC.StartCoords           = startPathCoords;
                pendingNPC.CurrentCoords         = startPathCoords;
                pendingNPC.EndCoords             = endPathCoords;
                pendingNPC.SpawnType             = "SpaceCargoShip";
                pendingNPC.AutoPilotSpeed        = speedL.Length();
                pendingNPC.CleanupIgnore         = spawnGroup.IgnoreCleanupRules;
                pendingNPC.ForceStaticGrid       = spawnGroup.ForceStaticGrid;
                pendingNPC.KeenAiName            = prefab.Behaviour;
                pendingNPC.KeenAiTriggerDistance = prefab.BehaviourActivationDistance;

                if (string.IsNullOrEmpty(pendingNPC.KeenAiName) == false)
                {
                    Logger.AddMsg("Stock AI Detected In Prefab: " + prefab.SubtypeId + " in SpawnGroup: " + spawnGroup.SpawnGroup.Id.SubtypeName);
                }

                if (spawnGroup.RandomizeWeapons == true)
                {
                    pendingNPC.ReplenishedSystems = false;
                    pendingNPC.ReplacedWeapons    = true;
                }
                else if ((MES_SessionCore.NPCWeaponUpgradesModDetected == true || Settings.General.EnableGlobalNPCWeaponRandomizer == true) && spawnGroup.IgnoreWeaponRandomizerMod == false)
                {
                    pendingNPC.ReplenishedSystems = false;
                    pendingNPC.ReplacedWeapons    = true;
                }
                else if (spawnGroup.ReplenishSystems == true)
                {
                    pendingNPC.ReplenishedSystems = false;
                }

                NPCWatcher.PendingNPCs.Add(pendingNPC);
            }

            Logger.SkipNextMessage = false;
            return("Spawning Group - " + spawnGroup.SpawnGroup.Id.SubtypeName);
        }
Esempio n. 7
0
        public static bool CustomSpawnRequest(List <string> spawnGroups, MatrixD spawningMatrix, Vector3 velocity, bool ignoreSafetyCheck, string factionOverride, string spawnProfileId)
        {
            Logger.AddMsg("Custom Spawn Request Received by ID: " + spawnProfileId);

            if (Settings.General.UseMaxNpcGrids == true)
            {
                var totalNPCs = NPCWatcher.ActiveNPCs.Count;

                if (totalNPCs >= Settings.General.MaxGlobalNpcGrids)
                {
                    Logger.AddMsg("Custom Spawn Request Aborted: Too Many NPC Grids In World");
                    return(false);
                }
            }

            KnownPlayerLocationManager.CleanExpiredLocations();
            var validFactions  = new Dictionary <string, List <string> >();
            var spawnGroupList = GetSpawnGroups(spawnGroups, spawningMatrix.Translation, factionOverride, out validFactions);

            if (spawnGroupList.Count == 0)
            {
                Logger.AddMsg("Custom Spawn Request Aborted: No Eligible Spawngroups");
                return(false);
                //return "No Eligible Spawn Groups Could Be Found To Spawn Near Player.";
            }

            var  spawnGroup   = spawnGroupList[SpawnResources.rnd.Next(0, spawnGroupList.Count)];
            bool badSpawnArea = false;

            if (ignoreSafetyCheck == false)
            {
            }

            if (badSpawnArea)
            {
                return(false);
            }

            var startPathCoords = Vector3D.Zero;
            var endPathCoords   = Vector3D.Zero;

            //Get Directions
            var  spawnForwardDir = spawningMatrix.Forward;
            var  spawnUpDir      = spawningMatrix.Up;
            var  spawnMatrix     = spawningMatrix;
            long gridOwner       = 0;
            var  randFactionTag  = spawnGroup.FactionOwner;

            if (validFactions.ContainsKey(spawnGroup.SpawnGroupName))
            {
                randFactionTag = validFactions[spawnGroup.SpawnGroupName][SpawnResources.rnd.Next(0, validFactions[spawnGroup.SpawnGroupName].Count)];
            }

            if (NPCWatcher.NPCFactionTagToFounder.ContainsKey(randFactionTag) == true)
            {
                gridOwner = NPCWatcher.NPCFactionTagToFounder[randFactionTag];
            }
            else
            {
                Logger.AddMsg("Could Not Find Faction Founder For: " + randFactionTag);
            }

            foreach (var prefab in spawnGroup.SpawnGroup.Prefabs)
            {
                if (spawnGroup.UseKnownPlayerLocations)
                {
                    KnownPlayerLocationManager.IncreaseSpawnCountOfLocations(spawnMatrix.Translation, randFactionTag);
                }

                var options       = SpawnGroupManager.CreateSpawningOptions(spawnGroup, prefab);
                var spawnPosition = Vector3D.Transform((Vector3D)prefab.Position, spawningMatrix);
                var speedL        = velocity;
                var speedA        = Vector3.Zero;
                var gridList      = new List <IMyCubeGrid>();

                //Grid Manipulation
                GridBuilderManipulation.ProcessPrefabForManipulation(prefab.SubtypeId, spawnGroup, "SpaceCargoShip", prefab.Behaviour);

                try{
                    MyAPIGateway.PrefabManager.SpawnPrefab(gridList, prefab.SubtypeId, spawnPosition, spawnForwardDir, spawnUpDir, speedL, speedA, !string.IsNullOrWhiteSpace(prefab.BeaconText) ? prefab.BeaconText : null, options, gridOwner);
                }catch (Exception exc) {
                    Logger.AddMsg("Something Went Wrong With Prefab Spawn Manager.", true);
                }

                var pendingNPC = new ActiveNPC();
                pendingNPC.SpawnGroupName        = spawnGroup.SpawnGroupName;
                pendingNPC.SpawnGroup            = spawnGroup;
                pendingNPC.InitialFaction        = randFactionTag;
                pendingNPC.faction               = MyAPIGateway.Session.Factions.TryGetFactionByTag(pendingNPC.InitialFaction);
                pendingNPC.Name                  = prefab.SubtypeId;
                pendingNPC.GridName              = MyDefinitionManager.Static.GetPrefabDefinition(prefab.SubtypeId).CubeGrids[0].DisplayName;
                pendingNPC.StartCoords           = startPathCoords;
                pendingNPC.CurrentCoords         = startPathCoords;
                pendingNPC.EndCoords             = endPathCoords;
                pendingNPC.SpawnType             = "Other";
                pendingNPC.AutoPilotSpeed        = speedL.Length();
                pendingNPC.CleanupIgnore         = spawnGroup.IgnoreCleanupRules;
                pendingNPC.ForceStaticGrid       = spawnGroup.ForceStaticGrid;
                pendingNPC.KeenAiName            = prefab.Behaviour;
                pendingNPC.KeenAiTriggerDistance = prefab.BehaviourActivationDistance;

                if (string.IsNullOrEmpty(pendingNPC.KeenAiName) == false)
                {
                    Logger.AddMsg("AI Detected In Prefab: " + prefab.SubtypeId + " in SpawnGroup: " + spawnGroup.SpawnGroup.Id.SubtypeName);
                }

                if (spawnGroup.RandomizeWeapons == true)
                {
                    pendingNPC.ReplenishedSystems = false;
                    pendingNPC.ReplacedWeapons    = true;
                }
                else if ((MES_SessionCore.NPCWeaponUpgradesModDetected == true || Settings.General.EnableGlobalNPCWeaponRandomizer == true) && spawnGroup.IgnoreWeaponRandomizerMod == false)
                {
                    pendingNPC.ReplenishedSystems = false;
                    pendingNPC.ReplacedWeapons    = true;
                }
                else if (spawnGroup.ReplenishSystems == true)
                {
                    pendingNPC.ReplenishedSystems = false;
                }

                NPCWatcher.PendingNPCs.Add(pendingNPC);
            }

            Logger.SkipNextMessage = false;
            //return "Spawning Group - " + spawnGroup.SpawnGroup.Id.SubtypeName;
            return(true);
        }
        public void SetupScript()
        {
            Logger.AddMsg("Loading Settings From Spawner Version: " + ModVersion.ToString());

            //Save File Validation
            SaveName = MyAPIGateway.Session.Name;

            //Some Faction BS - Temporary
            if (1 == 0)
            {
                var factions = MyDefinitionManager.Static.GetDefaultFactions();
                var sb       = new StringBuilder();
                sb.Append("Faction Data: ").AppendLine().AppendLine();

                foreach (var faction in factions)
                {
                    sb.Append(faction.Tag).AppendLine();
                    sb.Append(faction.DefaultRelation).AppendLine();
                    sb.Append(faction.DefaultRelationToPlayers).AppendLine().AppendLine();
                }

                Logger.AddMsg(sb.ToString());
            }

            //Rival AI Stuff
            Logger.AddMsg("Initializing RivalAI Helper");
            RivalAIHelper.SetupRivalAIHelper();

            //Setup Watchers and Handlers
            MyAPIGateway.Multiplayer.RegisterMessageHandler(8877, ChatCommand.MESMessageHandler);
            MyAPIGateway.Utilities.MessageEntered += ChatCommand.MESChatCommand;
            var thisPlayer = MyAPIGateway.Session.LocalHumanPlayer;

            //Disable Vanilla Spawners
            Logger.AddMsg("Checking World Settings.");
            if (MyAPIGateway.Session.SessionSettings.CargoShipsEnabled == true)
            {
                Logger.AddMsg("Disabling Cargo Ships World Setting. Spawner Handles This Functionality.");
                MyAPIGateway.Session.SessionSettings.CargoShipsEnabled = false;
            }

            if (MyAPIGateway.Session.SessionSettings.EnableEncounters == true)
            {
                Logger.AddMsg("Disabling Random Encounters World Setting. Spawner Handles This Functionality.");
                MyAPIGateway.Session.SessionSettings.EnableEncounters = false;
            }

            /*
             * if(MyAPIGateway.Multiplayer.IsServer == false){
             *
             *      if(thisPlayer == null){
             *
             *              Logger.AddMsg("Player Doesn't Exist. Cannot Search For Existing Boss GPS.");
             *              return;
             *
             *      }
             *
             *      Logger.AddMsg("Searching For Existing Boss Encounter GPS.");
             *      var chatMsg = "MESClientGetBossGPS\n" + thisPlayer.IdentityId.ToString() + "\n" + thisPlayer.SteamUserId.ToString() + "\n" + "Msg";
             *      var sendData = MyAPIGateway.Utilities.SerializeToBinary<string>(chatMsg);
             *      var sendMsg = MyAPIGateway.Multiplayer.SendMessageToServer(8877, sendData);
             *
             *      return;
             *
             * }
             */

            //All Block SubtypeIds
            try{
                var allDefs = MyDefinitionManager.Static.GetAllDefinitions();

                foreach (MyDefinitionBase definition in allDefs.Where(x => x is MyCubeBlockDefinition))
                {
                    var blockDef = definition as MyCubeBlockDefinition;
                    SpawnResources.BlockDefinitionIdList.Add(definition.Id.SubtypeName);

                    if (ChatCommand.BlockDefinitionList.Contains(blockDef) == false)
                    {
                        ChatCommand.BlockDefinitionList.Add(blockDef);
                    }
                }
            }catch (Exception exc) {
                Logger.AddMsg("Something Failed While Building List Of CubeBlock SubtypeIds.");
            }


            //Drop Containers Names
            var dropContainerErrorLog = new StringBuilder();

            try{
                dropContainerErrorLog.Append("Getting List of DropContainer Definitions").AppendLine();
                var dropContainerDefs = MyDefinitionManager.Static.GetDropContainerDefinitions();
                dropContainerErrorLog.Append("Beginning Loop Of Definition List").AppendLine();

                foreach (var dropContainer in dropContainerDefs.Keys)
                {
                    dropContainerErrorLog.Append("Checking Drop Container Prefab: ").Append(dropContainerDefs[dropContainer].Id.SubtypeName).AppendLine();

                    foreach (var grid in dropContainerDefs[dropContainer].Prefab.CubeGrids)
                    {
                        dropContainerErrorLog.Append("Checking Drop Container Prefab Name...").AppendLine();
                        if (string.IsNullOrEmpty(grid.DisplayName) == true)
                        {
                            dropContainerErrorLog.Append("Prefab Grid Name Null Or Empty - Skipping").AppendLine();
                            continue;
                        }

                        dropContainerErrorLog.Append("Added Prefab Grid Name To DropContainerNames: ").Append(grid.DisplayName).AppendLine();
                        NPCWatcher.DropContainerNames.Add(grid.DisplayName);
                    }
                }
            }catch (Exception exc) {
                Logger.AddMsg("Something Failed While Building List Of Drop Container (Unknown Signal) Prefab Names. See Below:");
                Logger.AddMsg(dropContainerErrorLog.ToString());
            }

            //Economy Stations

            Logger.AddMsg("The Following Economy Stations Will Not Be Monitored By Spawner Mod:", true);
            try {
                NPCWatcher.EconomyStationNames.Add("Economy_MiningStation_1");
                NPCWatcher.EconomyStationNames.Add("Economy_MiningStation_2");
                NPCWatcher.EconomyStationNames.Add("Economy_MiningStation_3");
                NPCWatcher.EconomyStationNames.Add("Economy_OrbitalStation_1");
                NPCWatcher.EconomyStationNames.Add("Economy_OrbitalStation_2");
                NPCWatcher.EconomyStationNames.Add("Economy_OrbitalStation_3");
                NPCWatcher.EconomyStationNames.Add("Economy_OrbitalStation_4");
                NPCWatcher.EconomyStationNames.Add("Economy_Outpost_1");
                NPCWatcher.EconomyStationNames.Add("Economy_Outpost_2");
                NPCWatcher.EconomyStationNames.Add("Economy_Outpost_3");
                NPCWatcher.EconomyStationNames.Add("Economy_Outpost_4");
                NPCWatcher.EconomyStationNames.Add("Economy_Outpost_5");
                NPCWatcher.EconomyStationNames.Add("Economy_Outpost_6");
                NPCWatcher.EconomyStationNames.Add("Economy_Outpost_7");
                NPCWatcher.EconomyStationNames.Add("Economy_SpaceStation_1");
                NPCWatcher.EconomyStationNames.Add("Economy_SpaceStation_2");
                NPCWatcher.EconomyStationNames.Add("Economy_SpaceStation_3");
                NPCWatcher.EconomyStationNames.Add("Economy_SpaceStation_4");
                NPCWatcher.EconomyStationNames.Add("Economy_SpaceStation_5");

                /*
                 * var ecoStationsDefs = new List<MyStationsListDefinition>(MyDefinitionManager.Static.GetDefinitionsOfType<MyStationsListDefinition>().ToList());
                 *
                 * foreach(var station in ecoStationsDefs) {
                 *
                 *  foreach(var stationPrefabName in station.StationNames) {
                 *
                 *      var stationNameString = stationPrefabName.ToString();
                 *
                 *      if(string.IsNullOrWhiteSpace(stationNameString) == true) {
                 *
                 *          continue;
                 *
                 *      }
                 *
                 *      if(NPCWatcher.EconomyStationNames.Contains(stationNameString) == false) {
                 *
                 *          NPCWatcher.EconomyStationNames.Add(stationNameString);
                 *          Logger.AddMsg("Economy Station: " + stationNameString);
                 *
                 *      }
                 *
                 *  }
                 *
                 * }
                 */
            } catch (Exception exc) {
                Logger.AddMsg("Something Failed While Building List Of Economy Station Prefab Names. See Below:");
                Logger.AddMsg(dropContainerErrorLog.ToString());
            }

            Logger.AddMsg("Registering Mod Message Handlers.");
            Logger.AddMsg("Mod Channel: " + MyAPIGateway.Utilities.GamePaths.ModScopeName);
            MyAPIGateway.Utilities.RegisterMessageHandler(1521905890, ModMessages.ModMessageHandler);
            MyAPIGateway.Utilities.RegisterMessageHandler(1521905890001, ModMessages.ModMessageReceiverBlockReplace);
            MyAPIGateway.Utilities.RegisterMessageHandler(1521905890002, ModMessages.ModMessageReceiverSpawnRequest);
            MyAPIGateway.Utilities.RegisterMessageHandler(1521905890003, ModMessages.ModMessageReceiverRivalAISpawnRequest);
            Logger.AddMsg("Initiating Main Settings.");
            Settings.InitSettings();
            NPCWatcher.InitFactionData();
            SpawnResources.PopulateNpcFactionLists();
            TerritoryManager.TerritoryRefresh();
            SpawnGroupManager.CreateSpawnLists();

            string[] uniqueSpawnedArray = new string[0];
            if (MyAPIGateway.Utilities.GetVariable <string[]>("MES-UniqueGroupsSpawned", out uniqueSpawnedArray) == true)
            {
                SpawnGroupManager.UniqueGroupsSpawned = new List <string>(uniqueSpawnedArray.ToList());
            }
            else
            {
                Logger.AddMsg("Failed To Retrieve Previously Spawned Unique Encounters List or No Unique Encounters Have Spawned Yet.");
            }

            //Setup Existing Boss Encounters
            string storedBossData = "";

            if (MyAPIGateway.Utilities.GetVariable <string>("MES-ActiveBossEncounters", out storedBossData) == true)
            {
                if (storedBossData != "")
                {
                    try{
                        var byteArray  = Convert.FromBase64String(storedBossData);
                        var storedData = MyAPIGateway.Utilities.SerializeFromBinary <BossEncounter[]>(byteArray);
                        NPCWatcher.BossEncounters = new List <BossEncounter>(storedData.ToList());
                        bool listChange = false;

                        if (NPCWatcher.BossEncounters.Count > 0)
                        {
                            for (int i = NPCWatcher.BossEncounters.Count - 1; i >= 0; i--)
                            {
                                var bossEncounter = NPCWatcher.BossEncounters[i];
                                bossEncounter.SpawnGroup = SpawnGroupManager.GetSpawnGroupByName(bossEncounter.SpawnGroupName);

                                if (bossEncounter.SpawnGroup == null)
                                {
                                    bossEncounter.RemoveGpsForPlayers();
                                    listChange = true;
                                    NPCWatcher.BossEncounters.RemoveAt(i);
                                }
                            }
                        }

                        if (listChange == true)
                        {
                            if (NPCWatcher.BossEncounters.Count > 0)
                            {
                                BossEncounter[] encounterArray = NPCWatcher.BossEncounters.ToArray();
                                byteArray      = MyAPIGateway.Utilities.SerializeToBinary <BossEncounter[]>(encounterArray);
                                storedBossData = Convert.ToBase64String(byteArray);
                                MyAPIGateway.Utilities.SetVariable <string>("MES-ActiveBossEncounters", storedBossData);
                            }
                            else
                            {
                                MyAPIGateway.Utilities.SetVariable <string>("MES-ActiveBossEncounters", "");
                            }
                        }
                    }catch (Exception e) {
                        Logger.AddMsg("Something went wrong while getting Boss Encounter Data from Storage.");
                        Logger.AddMsg(e.ToString(), true);
                    }
                }
            }

            //Get Active Mods
            Logger.AddMsg("Getting Active Mods.");
            foreach (var mod in MyAPIGateway.Session.Mods)
            {
                if (mod.PublishedFileId != 0)
                {
                    ActiveMods.Add(mod.PublishedFileId);
                }

                /*if(mod.PublishedFileId == 1135484377 || mod.PublishedFileId == 973528334){
                 *
                 *      string msgA = "Conflicting Mod Detected: " + mod.FriendlyName;
                 *      MyVisualScriptLogicProvider.ShowNotificationToAll(msgA, 15000, "Red");
                 *      Logger.AddMsg(msgA);
                 *      conflictingSettings = true;
                 *
                 * }*/
            }

            if (ActiveMods.Contains(1555044803) == true)
            {
                Logger.AddMsg("NPC Weapon Upgrades Mod Detected. Enabling Weapon Randomization.");
                NPCWeaponUpgradesModDetected = true;
            }

            if (ActiveMods.Contains(1773965697) == true)
            {
                Logger.AddMsg("Wave Spawner (Space) Mod Detected. Enabling Wave Spawning for SpaceCargoShips.");
                SpaceWaveSpawnerModDetected = true;
            }

            bool suppressCargo     = false;
            bool suppressEncounter = false;

            if (ActiveMods.Contains(888457124) == true)
            {
                suppressCargo = true;
            }

            if (ActiveMods.Contains(888457381) == true)
            {
                suppressEncounter = true;
            }

            SuppressGroups.ApplySuppression(suppressCargo, suppressEncounter);

            //Init Timers
            PlayerWatcherTimer = Settings.General.PlayerWatcherTimerTrigger;
            NPCWatcher.NpcDistanceCheckTimer  = Settings.General.NpcDistanceCheckTimerTrigger;
            NPCWatcher.NpcOwnershipCheckTimer = Settings.General.NpcOwnershipCheckTimerTrigger;
            NPCWatcher.NpcCleanupCheckTimer   = Settings.General.NpcCleanupCheckTimerTrigger;
            NPCWatcher.SpawnedVoxelCheckTimer = Settings.General.SpawnedVoxelCheckTimerTrigger;
            SpawnResources.RefreshEntityLists();

            //Setup Watchers and Handlers
            MyAPIGateway.Entities.OnEntityAdd += NPCWatcher.NewEntityDetected;

            //Get Initial Players
            PlayerList.Clear();
            MyAPIGateway.Players.GetPlayers(PlayerList);

            //Get Existing NPCs
            Logger.AddMsg("Check For Existing NPC Grids");
            NPCWatcher.StartupScan();

            //Setup Wave Spawners
            SpaceCargoShipWaveSpawner = new WaveSpawner("SpaceCargoShip");

            //Init Economy Stuff
            Logger.AddMsg("Initializing Economy Resources");
            EconomyHelper.Setup();

            //Get Spawned Voxels From Save
            try{
                string[] tempSpawnedVoxels = new string[0];

                if (MyAPIGateway.Utilities.GetVariable <string[]>("MES-SpawnedVoxels", out tempSpawnedVoxels) == true)
                {
                    foreach (var voxelId in tempSpawnedVoxels)
                    {
                        long tempId = 0;

                        if (long.TryParse(voxelId, out tempId) == false)
                        {
                            continue;
                        }

                        IMyEntity voxelEntity = null;

                        if (MyAPIGateway.Entities.TryGetEntityById(tempId, out voxelEntity) == false)
                        {
                            continue;
                        }

                        if (NPCWatcher.SpawnedVoxels.ContainsKey(voxelId) == false)
                        {
                            NPCWatcher.SpawnedVoxels.Add(voxelId, voxelEntity);
                        }
                    }
                }
            }catch (Exception exc) {
                Logger.AddMsg("Something went wrong while trying to retrieve previously spawned voxels.");
            }
        }
        public static string AttemptSpawn(Vector3D startCoords, List <string> eligibleNames = null)
        {
            if (Settings.General.UseMaxNpcGrids == true)
            {
                var totalNPCs = NPCWatcher.ActiveNPCs.Count;

                if (totalNPCs >= Settings.General.MaxGlobalNpcGrids)
                {
                    return("Spawning Aborted. Max Global NPCs Limit Reached.");
                }
            }

            if (NPCWatcher.ActiveNpcTypeLimitReachedForArea("RandomEncounter", startCoords, Settings.RandomEncounters.MaxShipsPerArea, Settings.RandomEncounters.AreaSize) == true)
            {
                return("Too Many Random Encounter Grids in Player Area");
            }

            KnownPlayerLocationManager.CleanExpiredLocations();
            var validFactions  = new Dictionary <string, List <string> >();
            var spawnGroupList = GetRandomEncounters(startCoords, eligibleNames, out validFactions);

            if (Settings.General.UseModIdSelectionForSpawning == true)
            {
                spawnGroupList = SpawnResources.SelectSpawnGroupSublist(SpawnGroupSublists, EligibleSpawnsByModId);
            }

            if (spawnGroupList.Count == 0)
            {
                return("No Eligible Spawn Groups Could Be Found To Spawn Near Player.");
            }

            var      spawnGroup  = spawnGroupList[SpawnResources.rnd.Next(0, spawnGroupList.Count)];
            Vector3D spawnCoords = Vector3D.Zero;

            if (GetSpawnCoords(spawnGroup, startCoords, out spawnCoords) == false)
            {
                return("Could Not Find Safe Position To Spawn Encounter");
            }

            //Get Directions
            var spawnMatrix          = MatrixD.CreateWorld(spawnCoords);
            var successfulVoxelSpawn = false;
            var centerVoxelOffset    = false;

            foreach (var voxel in spawnGroup.SpawnGroup.Voxels)
            {
                spawnGroup.RotateFirstCockpitToForward = false;
                var voxelSpawningPosition = Vector3D.Transform((Vector3D)voxel.Offset, spawnMatrix);

                try {
                    var voxelSpawn = MyAPIGateway.Session.VoxelMaps.CreateVoxelMapFromStorageName(voxel.StorageName, voxel.StorageName, voxelSpawningPosition);

                    if (Settings.RandomEncounters.RemoveVoxelsIfGridRemoved == true && spawnGroup.RemoveVoxelsIfGridRemoved == true)
                    {
                        NPCWatcher.SpawnedVoxels.Add(voxelSpawn.EntityId.ToString(), voxelSpawn as IMyEntity);
                    }

                    successfulVoxelSpawn = true;
                } catch (Exception exc) {
                    Logger.AddMsg("Voxel Spawning For " + voxel.StorageName + " Failed");
                }
            }

            if (successfulVoxelSpawn == true)
            {
                var      voxelIdList  = new List <string>(NPCWatcher.SpawnedVoxels.Keys.ToList());
                string[] voxelIdArray = voxelIdList.ToArray();
                MyAPIGateway.Utilities.SetVariable <string[]>("MES-SpawnedVoxels", voxelIdArray);
            }

            long gridOwner      = 0;
            var  randFactionTag = spawnGroup.FactionOwner;

            if (validFactions.ContainsKey(spawnGroup.SpawnGroupName))
            {
                randFactionTag = validFactions[spawnGroup.SpawnGroupName][SpawnResources.rnd.Next(0, validFactions[spawnGroup.SpawnGroupName].Count)];
            }

            if (NPCWatcher.NPCFactionTagToFounder.ContainsKey(randFactionTag) == true)
            {
                gridOwner = NPCWatcher.NPCFactionTagToFounder[randFactionTag];
            }
            else
            {
                Logger.AddMsg("Could Not Find Faction Founder For: " + randFactionTag);
            }

            foreach (var prefab in spawnGroup.SpawnGroup.Prefabs)
            {
                if (spawnGroup.UseKnownPlayerLocations)
                {
                    KnownPlayerLocationManager.IncreaseSpawnCountOfLocations(startCoords, randFactionTag);
                }

                var options       = SpawnGroupManager.CreateSpawningOptions(spawnGroup, prefab);
                var spawnPosition = Vector3D.Transform((Vector3D)prefab.Position * (centerVoxelOffset ? 1 : 1), spawnMatrix);

                Logger.CreateDebugGPS("Prefab Spawn Coords", spawnPosition);
                var speedL   = Vector3.Zero;
                var speedA   = Vector3.Zero;
                var gridList = new List <IMyCubeGrid>();

                //Grid Manipulation
                GridBuilderManipulation.ProcessPrefabForManipulation(prefab.SubtypeId, spawnGroup, "RandomEncounter", prefab.Behaviour);

                try{
                    MyAPIGateway.PrefabManager.SpawnPrefab(gridList, prefab.SubtypeId, spawnPosition, spawnMatrix.Forward, spawnMatrix.Up, speedL, speedA, !string.IsNullOrWhiteSpace(prefab.BeaconText) ? prefab.BeaconText : null, options, gridOwner);
                }catch (Exception exc) {
                }

                var pendingNPC = new ActiveNPC();
                pendingNPC.SpawnGroupName        = spawnGroup.SpawnGroupName;
                pendingNPC.SpawnGroup            = spawnGroup;
                pendingNPC.InitialFaction        = randFactionTag;
                pendingNPC.faction               = MyAPIGateway.Session.Factions.TryGetFactionByTag(pendingNPC.InitialFaction);
                pendingNPC.Name                  = prefab.SubtypeId;
                pendingNPC.GridName              = MyDefinitionManager.Static.GetPrefabDefinition(prefab.SubtypeId).CubeGrids[0].DisplayName;
                pendingNPC.StartCoords           = spawnCoords;
                pendingNPC.CurrentCoords         = spawnCoords;
                pendingNPC.EndCoords             = spawnCoords;
                pendingNPC.SpawnType             = "RandomEncounter";
                pendingNPC.CleanupIgnore         = spawnGroup.IgnoreCleanupRules;
                pendingNPC.ForceStaticGrid       = spawnGroup.ForceStaticGrid;
                pendingNPC.KeenAiName            = prefab.Behaviour;
                pendingNPC.KeenAiTriggerDistance = prefab.BehaviourActivationDistance;

                if (spawnGroup.RandomizeWeapons == true)
                {
                    pendingNPC.ReplenishedSystems = false;
                    pendingNPC.ReplacedWeapons    = true;
                }
                else if ((MES_SessionCore.NPCWeaponUpgradesModDetected == true || Settings.General.EnableGlobalNPCWeaponRandomizer == true) && spawnGroup.IgnoreWeaponRandomizerMod == false)
                {
                    pendingNPC.ReplenishedSystems = false;
                    pendingNPC.ReplacedWeapons    = true;
                }
                else if (spawnGroup.ReplenishSystems == true)
                {
                    pendingNPC.ReplenishedSystems = false;
                }

                NPCWatcher.PendingNPCs.Add(pendingNPC);
            }

            Logger.SkipNextMessage = false;
            return("Spawning Group - " + spawnGroup.SpawnGroup.Id.SubtypeName);
        }
        public static void AttemptSpawn(SpawnRequestMES spawnData)
        {
            if (Settings.General.UseMaxNpcGrids == true)
            {
                var totalNPCs = NPCWatcher.ActiveNPCs.Count;

                if (totalNPCs >= Settings.General.MaxGlobalNpcGrids)
                {
                    Logger.AddMsg("Spawning Aborted. Max Global NPCs Limit Reached.", true);
                    return;
                }
            }

            ImprovedSpawnGroup spawnGroup = null;

            foreach (var spawngroupItem in SpawnGroupManager.SpawnGroups)
            {
                if (spawngroupItem.SpawnGroupName == spawnData.SpawnGroupName)
                {
                    spawnGroup = spawngroupItem;
                    break;
                }
            }

            if (spawnGroup == null)
            {
                Logger.AddMsg("SpawnGroup with Name: " + spawnData.SpawnGroupName + " Not Found.", true);
                return;
            }

            //Get Directions
            var    spawnForwardDir = spawnData.SpawnDirectionForward;
            var    spawnUpDir      = spawnData.SpawnDirectionUp;
            var    spawnMatrix     = MatrixD.CreateWorld(spawnData.SpawnCoordinates, spawnForwardDir, spawnUpDir);
            string factionTag      = spawnGroup.FactionOwner;
            long   gridOwner       = 0;

            if (spawnData.FactionTagOverride != "")
            {
                factionTag = spawnData.FactionTagOverride;
            }

            if (NPCWatcher.NPCFactionTagToFounder.ContainsKey(factionTag) == true)
            {
                gridOwner = NPCWatcher.NPCFactionTagToFounder[factionTag];
            }
            else
            {
                Logger.AddMsg("Could Not Find Faction Founder For: " + factionTag);
            }

            foreach (var prefab in spawnGroup.SpawnGroup.Prefabs)
            {
                var options       = SpawnGroupManager.CreateSpawningOptions(spawnGroup, prefab);
                var spawnPosition = Vector3D.Transform((Vector3D)prefab.Position, spawnMatrix);
                var speedL        = (Vector3)spawnData.LinearVelocity;
                var speedA        = Vector3.Zero;
                var gridList      = new List <IMyCubeGrid>();

                //Grid Manipulation
                GridBuilderManipulation.ProcessPrefabForManipulation(prefab.SubtypeId, spawnGroup, "OtherNPC", prefab.Behaviour);

                try{
                    MyAPIGateway.PrefabManager.SpawnPrefab(gridList, prefab.SubtypeId, spawnPosition, spawnForwardDir, spawnUpDir, speedL, speedA, prefab.BeaconText, options, gridOwner);
                }catch (Exception exc) {
                    Logger.AddMsg("Something Went Wrong With Prefab Spawn Manager.", true);
                }

                var pendingNPC = new ActiveNPC();
                pendingNPC.SpawnGroup            = spawnGroup;
                pendingNPC.Name                  = prefab.SubtypeId;
                pendingNPC.InitialFaction        = factionTag;
                pendingNPC.faction               = MyAPIGateway.Session.Factions.TryGetFactionByTag(pendingNPC.InitialFaction);
                pendingNPC.GridName              = MyDefinitionManager.Static.GetPrefabDefinition(prefab.SubtypeId).CubeGrids[0].DisplayName;
                pendingNPC.SpawnType             = "OtherNPC";
                pendingNPC.CleanupIgnore         = spawnGroup.IgnoreCleanupRules;
                pendingNPC.ForceStaticGrid       = spawnGroup.ForceStaticGrid;
                pendingNPC.KeenAiName            = prefab.Behaviour;
                pendingNPC.KeenAiTriggerDistance = prefab.BehaviourActivationDistance;

                if (string.IsNullOrEmpty(pendingNPC.KeenAiName) == false)
                {
                    Logger.AddMsg("Stock AI Detected In Prefab: " + prefab.SubtypeId + " in SpawnGroup: " + spawnGroup.SpawnGroup.Id.SubtypeName, true);
                }

                if (spawnGroup.RandomizeWeapons == true)
                {
                    pendingNPC.ReplenishedSystems = false;
                    pendingNPC.ReplacedWeapons    = true;
                }
                else if ((MES_SessionCore.NPCWeaponUpgradesModDetected == true || Settings.General.EnableGlobalNPCWeaponRandomizer == true) && spawnGroup.IgnoreWeaponRandomizerMod == false)
                {
                    pendingNPC.ReplenishedSystems = false;
                    pendingNPC.ReplacedWeapons    = true;
                }
                else if (spawnGroup.ReplenishSystems == true)
                {
                    pendingNPC.ReplenishedSystems = false;
                }

                NPCWatcher.PendingNPCs.Add(pendingNPC);
            }

            Logger.AddMsg("Spawning Group - " + spawnGroup.SpawnGroup.Id.SubtypeName);
            return;
        }
        public static bool SpawnBossEncounter(BossEncounter encounter)
        {
            MyPlanet planet    = SpawnResources.GetNearestPlanet(encounter.Position);
            var      inGravity = SpawnResources.IsPositionInGravity(encounter.Position, planet);

            for (int i = 0; i < Settings.BossEncounters.PathCalculationAttempts; i++)
            {
                bool gotMatrix  = false;
                var  tempMatrix = MatrixD.CreateWorld(Vector3D.Zero, Vector3D.Forward, Vector3D.Up);

                if (inGravity == false)
                {
                    var randDir     = Vector3D.Normalize(MyUtils.GetRandomVector3D());
                    var randDist    = (double)SpawnResources.rnd.Next((int)Settings.BossEncounters.MinSpawnDistFromCoords, (int)Settings.BossEncounters.MaxSpawnDistFromCoords);
                    var spawnCoords = randDir * randDist + encounter.Position;

                    if (SpawnResources.IsPositionInGravity(spawnCoords, planet) == true)
                    {
                        randDir    *= -1;
                        spawnCoords = randDir * randDist + encounter.Position;

                        if (SpawnResources.IsPositionInGravity(spawnCoords, planet) == true)
                        {
                            continue;
                        }
                    }

                    var forwardDir = Vector3D.Normalize(encounter.Position - spawnCoords);
                    var upDir      = Vector3D.CalculatePerpendicularVector(forwardDir);
                    tempMatrix = MatrixD.CreateWorld(spawnCoords, forwardDir, upDir);
                    gotMatrix  = true;
                }
                else
                {
                    var planetEntity  = planet as IMyEntity;
                    var upDir         = Vector3D.Normalize(encounter.Position - planetEntity.GetPosition());
                    var randDir       = SpawnResources.GetRandomCompassDirection(encounter.Position, planet);
                    var randDist      = (double)SpawnResources.rnd.Next((int)Settings.BossEncounters.MinSpawnDistFromCoords, (int)Settings.BossEncounters.MaxSpawnDistFromCoords);
                    var roughCoords   = randDir * randDist + encounter.Position;
                    var surfaceCoords = SpawnResources.GetNearestSurfacePoint(roughCoords, planet);
                    var spawnCoords   = upDir * Settings.BossEncounters.MinPlanetAltitude + surfaceCoords;
                    tempMatrix = MatrixD.CreateWorld(spawnCoords, randDir * -1, upDir);
                    gotMatrix  = true;
                }

                if (gotMatrix == false)
                {
                    continue;
                }

                bool badCoords = false;

                foreach (var prefab in encounter.SpawnGroup.SpawnGroup.Prefabs)
                {
                    var offsetCoords = Vector3D.Transform((Vector3D)prefab.Position, tempMatrix);

                    foreach (var entity in SpawnResources.EntityList)
                    {
                        if (Vector3D.Distance(offsetCoords, entity.GetPosition()) < Settings.BossEncounters.MinSignalDistFromOtherEntities)
                        {
                            badCoords = true;
                            break;
                        }
                    }

                    if (badCoords == false)
                    {
                        if (SpawnResources.IsPositionInSafeZone(offsetCoords) == true)
                        {
                            badCoords = true;
                            break;
                        }
                    }

                    if (SpawnResources.IsPositionInGravity(offsetCoords, planet) == true)
                    {
                        if (SpawnResources.GetDistanceFromSurface(offsetCoords, planet) < Settings.BossEncounters.MinPlanetAltitude / 4)
                        {
                            badCoords = true;
                            break;
                        }
                    }
                }

                if (badCoords == true)
                {
                    continue;
                }

                //Spawn the things!
                Logger.SkipNextMessage = false;
                Logger.AddMsg("Boss Encounter SpawnGroup " + encounter.SpawnGroup.SpawnGroup.Id.SubtypeName + " Now Spawning.");

                foreach (var prefab in encounter.SpawnGroup.SpawnGroup.Prefabs)
                {
                    var  options       = SpawnGroupManager.CreateSpawningOptions(encounter.SpawnGroup, prefab);
                    var  spawnPosition = Vector3D.Transform((Vector3D)prefab.Position, tempMatrix);
                    var  speedL        = prefab.Speed * (Vector3)tempMatrix.Forward;
                    var  speedA        = Vector3.Zero;
                    var  gridList      = new List <IMyCubeGrid>();
                    long gridOwner     = 0;

                    //Speed Management
                    if (Settings.SpaceCargoShips.UseMinimumSpeed == true && prefab.Speed < Settings.SpaceCargoShips.MinimumSpeed)
                    {
                        speedL = Settings.SpaceCargoShips.MinimumSpeed * (Vector3)tempMatrix.Forward;
                    }

                    if (Settings.SpaceCargoShips.UseSpeedOverride == true)
                    {
                        speedL = Settings.SpaceCargoShips.SpeedOverride * (Vector3)tempMatrix.Forward;
                    }

                    if (NPCWatcher.NPCFactionTagToFounder.ContainsKey(encounter.SpawnGroup.FactionOwner) == true)
                    {
                        gridOwner = NPCWatcher.NPCFactionTagToFounder[encounter.SpawnGroup.FactionOwner];
                    }
                    else
                    {
                        Logger.AddMsg("Could Not Find Faction Founder For: " + encounter.SpawnGroup.FactionOwner);
                    }

                    //Grid Manipulation
                    GridBuilderManipulation.ProcessPrefabForManipulation(prefab.SubtypeId, encounter.SpawnGroup, "BossEncounter", prefab.Behaviour);

                    try{
                        MyAPIGateway.PrefabManager.SpawnPrefab(gridList, prefab.SubtypeId, spawnPosition, tempMatrix.Forward, tempMatrix.Up, speedL, speedA, prefab.BeaconText, options, gridOwner);
                    }catch (Exception exc) {
                    }

                    var pendingNPC = new ActiveNPC();
                    pendingNPC.SpawnGroup            = encounter.SpawnGroup;
                    pendingNPC.SpawnGroupName        = encounter.SpawnGroup.SpawnGroupName;
                    pendingNPC.InitialFaction        = encounter.SpawnGroup.FactionOwner;
                    pendingNPC.faction               = MyAPIGateway.Session.Factions.TryGetFactionByTag(pendingNPC.InitialFaction);
                    pendingNPC.Name                  = prefab.SubtypeId;
                    pendingNPC.GridName              = MyDefinitionManager.Static.GetPrefabDefinition(prefab.SubtypeId).CubeGrids[0].DisplayName;
                    pendingNPC.StartCoords           = spawnPosition;
                    pendingNPC.CurrentCoords         = spawnPosition;
                    pendingNPC.EndCoords             = spawnPosition;
                    pendingNPC.SpawnType             = "BossEncounter";
                    pendingNPC.CleanupIgnore         = encounter.SpawnGroup.IgnoreCleanupRules;
                    pendingNPC.ForceStaticGrid       = encounter.SpawnGroup.ForceStaticGrid;
                    pendingNPC.KeenAiName            = prefab.Behaviour;
                    pendingNPC.KeenAiTriggerDistance = prefab.BehaviourActivationDistance;

                    if (encounter.SpawnGroup.RandomizeWeapons == true)
                    {
                        pendingNPC.ReplenishedSystems = false;
                        pendingNPC.ReplacedWeapons    = true;
                    }
                    else if ((MES_SessionCore.NPCWeaponUpgradesModDetected == true || Settings.General.EnableGlobalNPCWeaponRandomizer == true) && encounter.SpawnGroup.IgnoreWeaponRandomizerMod == false)
                    {
                        pendingNPC.ReplenishedSystems = false;
                        pendingNPC.ReplacedWeapons    = true;
                    }
                    else if (encounter.SpawnGroup.ReplenishSystems == true)
                    {
                        pendingNPC.ReplenishedSystems = false;
                    }

                    if (inGravity == true)
                    {
                        pendingNPC.Planet = planet;
                    }

                    NPCWatcher.PendingNPCs.Add(pendingNPC);
                }

                return(true);
            }

            Logger.AddMsg("Could Not Find Safe Area To Spawn Boss Encounter");
            return(false);
        }
Esempio n. 12
0
        public static bool CheckCommonConditions(ImprovedSpawnGroup spawnGroup, Vector3D playerCoords, MyPlanet planet, bool specificSpawnRequest)
        {
            string planetName = "";

            if (planet != null)
            {
                planetName = planet.Generator.Id.SubtypeName;
            }

            if (spawnGroup.SpawnGroupEnabled == false)
            {
                if (spawnGroup.AdminSpawnOnly == false)
                {
                    return(false);
                }
            }

            if (CheckDefinitionProperties(spawnGroup.SpawnGroup) == false)
            {
                return(false);
            }

            if (spawnGroup.RandomNumberRoll > 1 && specificSpawnRequest == false)
            {
                var roll = rnd.Next(0, spawnGroup.RandomNumberRoll);

                if (roll != 0)
                {
                    return(false);
                }
            }

            if (SpawnGroupManager.ModRestrictionCheck(spawnGroup) == false)
            {
                return(false);
            }

            if (SpawnGroupManager.IsSpawnGroupInBlacklist(spawnGroup.SpawnGroup.Id.SubtypeName) == true)
            {
                return(false);
            }

            if (spawnGroup.UniqueEncounter == true && SpawnGroupManager.UniqueGroupsSpawned.Contains(spawnGroup.SpawnGroup.Id.SubtypeName) == true)
            {
                return(false);
            }

            if (SpawnGroupManager.DistanceFromCenterCheck(spawnGroup, playerCoords) == false)
            {
                return(false);
            }

            if (planetName != "")
            {
                if (SpawnGroupManager.CheckSpawnGroupPlanetLists(spawnGroup, planet) == false)
                {
                    return(false);
                }
            }

            if (CheckSandboxVariables(spawnGroup.SandboxVariables, spawnGroup.FalseSandboxVariables) == false)
            {
                return(false);
            }

            if (spawnGroup.ModBlockExists.Count > 0)
            {
                foreach (var modID in spawnGroup.ModBlockExists)
                {
                    if (string.IsNullOrEmpty(modID) == true)
                    {
                        continue;
                    }

                    if (BlockDefinitionIdList.Contains(modID) == false)
                    {
                        return(false);
                    }
                }
            }

            if (TerritoryValidation(spawnGroup, playerCoords) == false)
            {
                return(false);
            }

            if (spawnGroup.RequiredPlayersOnline.Count > 0)
            {
                foreach (var playerSteamId in spawnGroup.RequiredPlayersOnline)
                {
                    if (playerSteamId == 0)
                    {
                        continue;
                    }

                    bool foundPlayer = false;

                    foreach (var player in MES_SessionCore.PlayerList)
                    {
                        if (player.SteamUserId == playerSteamId)
                        {
                            foundPlayer = true;
                            break;
                        }
                    }

                    if (foundPlayer == false)
                    {
                        return(false);
                    }
                }
            }

            if (spawnGroup.UsePlayerCountCheck == true)
            {
                int totalPlayers = 0;

                foreach (var player in MES_SessionCore.PlayerList)
                {
                    if (player.IsBot || player.Character == null)
                    {
                        continue;
                    }

                    if (Vector3D.Distance(playerCoords, player.GetPosition()) < spawnGroup.PlayerCountCheckRadius || spawnGroup.PlayerCountCheckRadius < 0)
                    {
                        totalPlayers++;
                    }
                }

                if (totalPlayers < spawnGroup.MinimumPlayers && spawnGroup.MinimumPlayers > 0)
                {
                    return(false);
                }

                if (totalPlayers > spawnGroup.MaximumPlayers && spawnGroup.MaximumPlayers > 0)
                {
                    return(false);
                }

                return(true);
            }

            if (spawnGroup.UsePCUCheck == true)
            {
                var pcuLevel = GetPCULevel(spawnGroup, playerCoords);

                if (pcuLevel < (float)spawnGroup.PCUMinimum && (float)spawnGroup.PCUMinimum > 0)
                {
                    return(false);
                }

                if (pcuLevel > (float)spawnGroup.PCUMaximum && (float)spawnGroup.PCUMaximum > 0)
                {
                    return(false);
                }
            }

            if (spawnGroup.UseThreatLevelCheck == true)
            {
                var threatLevel = GetThreatLevel(spawnGroup, playerCoords);
                threatLevel -= (float)Settings.General.ThreatReductionHandicap;

                if (threatLevel < (float)spawnGroup.ThreatScoreMinimum && (float)spawnGroup.ThreatScoreMinimum > 0)
                {
                    return(false);
                }

                if (threatLevel > (float)spawnGroup.ThreatScoreMaximum && (float)spawnGroup.ThreatScoreMaximum > 0)
                {
                    return(false);
                }
            }

            if (spawnGroup.UsePlayerCredits == true)
            {
                long          totalCredits         = 0;
                long          highestPlayerCredits = 0;
                List <string> CheckedFactions      = new List <string>();

                foreach (var player in MES_SessionCore.PlayerList)
                {
                    if (player.IsBot == true || player.Character == null)
                    {
                        continue;
                    }

                    if (Vector3D.Distance(player.GetPosition(), playerCoords) > spawnGroup.PlayerCreditsCheckRadius)
                    {
                        continue;
                    }

                    IMyFaction faction        = null;
                    long       factionBalance = 0;

                    if (spawnGroup.IncludeFactionBalance == true)
                    {
                        faction = MyAPIGateway.Session.Factions.TryGetPlayerFaction(player.IdentityId);

                        if (faction != null)
                        {
                        }
                    }

                    long playerBalance = 0;
                    player.TryGetBalanceInfo(out playerBalance);

                    if (spawnGroup.IncludeAllPlayersInRadius == false)
                    {
                        if (factionBalance + playerBalance > totalCredits)
                        {
                            totalCredits = factionBalance + playerBalance;
                        }
                    }
                    else
                    {
                        if (faction != null)
                        {
                            if (CheckedFactions.Contains(faction.Tag) == false)
                            {
                                totalCredits += factionBalance;
                                CheckedFactions.Add(faction.Tag);
                            }

                            totalCredits += playerBalance;
                        }
                    }
                }

                if (totalCredits < spawnGroup.MinimumPlayerCredits && spawnGroup.MinimumPlayerCredits != -1)
                {
                    return(false);
                }

                if (totalCredits > spawnGroup.MaximumPlayerCredits && spawnGroup.MaximumPlayerCredits != -1)
                {
                    return(false);
                }
            }

            return(true);
        }