Ejemplo n.º 1
0
 public GroupInfo()
 {
     m_cost          = 0;
     m_spawnClass    = SpawnerClass.ANY;
     m_spawnType     = SpawnerType.ANY;
     m_spawnGroupDef = null;
 }
        public static NPCTerritory GetOldTerritoryDetails(MySpawnGroupDefinition spawnGroup)
        {
            var territory = new NPCTerritory();

            territory.Name     = spawnGroup.Id.SubtypeName;
            territory.TagOld   = spawnGroup.Prefabs[0].BeaconText;
            territory.Position = (Vector3D)spawnGroup.Prefabs[0].Position;
            territory.Radius   = (double)spawnGroup.Prefabs[0].Speed;
            return(territory);
        }
Ejemplo n.º 3
0
 public GroupInfo(
     int cost,
     SpawnerClass spawnClass,
     SpawnerType spawnType,
     MySpawnGroupDefinition spawnGroup)
 {
     m_cost          = cost;
     m_spawnClass    = spawnClass;
     m_spawnType     = spawnType;
     m_spawnGroupDef = spawnGroup;
 }
        private static BoundingBox GetEncounterBoundingBox(MySpawnGroupDefinition selectedEncounter)
        {
            BoundingBox encouterBoundingBox = new BoundingBox(Vector3.Zero, Vector3.Zero);

            selectedEncounter.ReloadPrefabs();
            foreach (var selectedPrefab in selectedEncounter.Prefabs)
            {
                var prefabDefinition = MyDefinitionManager.Static.GetPrefabDefinition(selectedPrefab.SubtypeId);
                encouterBoundingBox.Include(prefabDefinition.BoundingSphere);
            }
            return(encouterBoundingBox);
        }
Ejemplo n.º 5
0
 public static void SpawnSpawmGroup(string spawnGroup, MatrixD spawnOrigin, Options options = null)
 {
     MyAPIGateway.Parallel.Start(delegate
     {
         List <MySpawnGroupDefinition> spawnGroupDefinitions = new List <MySpawnGroupDefinition>(MyDefinitionManager.Static.GetSpawnGroupDefinitions());
         MySpawnGroupDefinition spawnGroupDefinition         = spawnGroupDefinitions.Find(x => x.Id.SubtypeName == spawnGroup);
         foreach (MySpawnGroupDefinition.SpawnGroupPrefab spawnGroupPrefab in spawnGroupDefinition.Prefabs)
         {
             Vector3D prefabSpawnPos       = Vector3D.Transform(spawnGroupPrefab.Position, spawnOrigin);
             MatrixD prefabSpawnMatrix     = spawnOrigin;
             prefabSpawnMatrix.Translation = prefabSpawnPos;
             SpawnPrefab(spawnGroupPrefab.SubtypeId, prefabSpawnMatrix, options);
             MyAPIGateway.Parallel.Sleep(1000);
         }
     });
 }
        public static bool IsSpawnGroupATerritory(MySpawnGroupDefinition spawnGroup)
        {
            if (spawnGroup.DescriptionText != null)
            {
                if (spawnGroup.DescriptionText.Contains("[Modular Encounters Territory]") == true)
                {
                    return(true);
                }
            }

            if (spawnGroup.Prefabs.Count > 0)
            {
                if (spawnGroup.Prefabs[0].SubtypeId == "TerritoryPlaceholder")
                {
                    return(true);
                }
            }

            return(false);
        }
        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);
        }
Ejemplo n.º 8
0
        public static void OnGlobalSpawnEvent(object senderEvent)
        {
            // Select a spawn group to spawn
            MySpawnGroupDefinition spawnGroup = PickRandomSpawnGroup();

            if (spawnGroup == null)
            {
                return;
            }

            spawnGroup.ReloadPrefabs();

            ProfilerShort.Begin("Generate position and direction");

            double   spawnDistance  = NEUTRAL_SHIP_SPAWN_DISTANCE;
            Vector3D playerPosition = Vector3D.Zero;
            bool     isWorldLimited = MyEntities.IsWorldLimited();
            int      numPlayers     = 0;

            if (isWorldLimited)
            {
                spawnDistance = Math.Min(spawnDistance, MyEntities.WorldSafeHalfExtent() - spawnGroup.SpawnRadius);
            }
            else
            {
                // In infinite worlds players can be thousands of kilometers away, so spawn ship around random player
                // so cargo ships will be spawned around every player at some time
                var players = MySession.Static.Players.GetOnlinePlayers();
                // In DS there can be no players connected
                numPlayers = Math.Max(0, players.Count - 1);
                int randomPlayerPosition = MyUtils.GetRandomInt(0, numPlayers);
                int i = 0;
                foreach (var player in players)
                {
                    if (i == randomPlayerPosition)
                    {
                        if (player.Character != null)
                        {
                            playerPosition = player.GetPosition();
                        }
                        break;
                    }
                    i++;
                }
            }
            if (spawnDistance < 0.0f)
            {
                MySandboxGame.Log.WriteLine("Not enough space in the world to spawn such a huge spawn group!");
                return;
            }

            double       forbiddenRadius = NEUTRAL_SHIP_FORBIDDEN_RADIUS;
            BoundingBoxD spawnBox;

            if (isWorldLimited)
            {
                spawnBox = new BoundingBoxD(new Vector3D(playerPosition - spawnDistance), new Vector3D(playerPosition + spawnDistance));
            }
            else
            {
                // We need to extend bouding box so cargo ships aren't spawned near other players
                GetSafeBoundingBoxForPlayers(playerPosition, spawnDistance, out spawnBox);
                // Forbidden radius is sphere around all players in box.
                // Bounding box is generated from players positions so their distance to center shall be same for all players
                forbiddenRadius += spawnBox.HalfExtents.Max() - NEUTRAL_SHIP_FORBIDDEN_RADIUS;
            }

            // Get the direction to the center and deviate it randomly
            Vector3D?origin = MyUtils.GetRandomBorderPosition(ref spawnBox);

            origin = MyEntities.TestPlaceInSpace(origin.Value, spawnGroup.SpawnRadius);
            if (!origin.HasValue)
            {
                if (++m_eventSpawnTry <= EVENT_SPAWN_TRY_MAX)
                {
                    MySandboxGame.Log.WriteLine("Could not spawn neutral ships - no free place found. Try " + m_eventSpawnTry + " of " + EVENT_SPAWN_TRY_MAX);

                    MyGlobalEvents.RescheduleEvent(senderEvent as MyGlobalEventBase, NEUTRAL_SHIP_RESCHEDULE_TIME);
                    ProfilerShort.End();
                    return;
                }
                else
                {
                    m_eventSpawnTry = 0;
                    return;
                }
            }
            m_eventSpawnTry = 0;

            // Radius in arc units of the forbidden sphere in the center, when viewed from origin
            float centerArcRadius = (float)Math.Atan(forbiddenRadius / (origin.Value - spawnBox.Center).Length());

            // Generate direction with elevation from centerArcRadius radians to (cAR + N_S_D_S) radians
            Vector3D direction = -Vector3D.Normalize(origin.Value);
            float    theta     = MyUtils.GetRandomFloat(centerArcRadius, centerArcRadius + NEUTRAL_SHIP_DIRECTION_SPREAD);
            float    phi       = MyUtils.GetRandomRadian();
            Vector3D cosVec    = Vector3D.CalculatePerpendicularVector(direction);
            Vector3D sinVec    = Vector3D.Cross(direction, cosVec);

            cosVec   *= (Math.Sin(theta) * Math.Cos(phi));
            sinVec   *= (Math.Sin(theta) * Math.Sin(phi));
            direction = direction * Math.Cos(theta) + cosVec + sinVec;

            Vector3D destination  = Vector3D.Zero;
            RayD     ray          = new RayD(origin.Value, direction);
            double?  intersection = ray.Intersects(spawnBox);
            Vector3D directionMult;

            if (!intersection.HasValue || intersection.Value < NEUTRAL_SHIP_MINIMAL_ROUTE_LENGTH)
            {
                directionMult = direction * NEUTRAL_SHIP_MINIMAL_ROUTE_LENGTH;
            }
            else
            {
                directionMult = direction * intersection.Value;
            }
            destination = origin.Value + directionMult;

            Vector3D upVector     = Vector3D.CalculatePerpendicularVector(direction);
            Vector3D rightVector  = Vector3D.Cross(direction, upVector);
            MatrixD  originMatrix = MatrixD.CreateWorld(origin.Value, direction, upVector);

            ProfilerShort.End();

            ProfilerShort.Begin("Check free space");

            // CH:TODO: Convex cast to detect collision
            // Check ships' path to avoid possible collisions. (TODO: But only if it is said in the definitions)
            m_raycastHits.Clear();
            foreach (var shipPrefab in spawnGroup.Prefabs)
            {
                var prefabDef = MyDefinitionManager.Static.GetPrefabDefinition(shipPrefab.SubtypeId);
                Debug.Assert(prefabDef != null);

                Vector3D shipPosition    = Vector3.Transform(shipPrefab.Position, originMatrix);
                Vector3D shipDestination = shipPosition + directionMult;
                float    radius          = prefabDef == null ? 10.0f : prefabDef.BoundingSphere.Radius;

                //these point checks could be done in the trajectory intersect, but checking points is faster than ray intersect
                if (MyGravityProviderSystem.IsPositionInNaturalGravity(shipPosition, spawnGroup.SpawnRadius))
                {
                    if (!MyFinalBuildConstants.IS_OFFICIAL)
                    {
                        MySandboxGame.Log.WriteLine("Could not spawn neutral ships: spawn point is inside gravity well");
                    }
                    MyGlobalEvents.RescheduleEvent(senderEvent as MyGlobalEventBase, NEUTRAL_SHIP_RESCHEDULE_TIME);
                    ProfilerShort.End();
                    return;
                }
                if (MyGravityProviderSystem.IsPositionInNaturalGravity(shipDestination, spawnGroup.SpawnRadius))
                {
                    if (!MyFinalBuildConstants.IS_OFFICIAL)
                    {
                        MySandboxGame.Log.WriteLine("Could not spawn neutral ships: destination point is inside gravity well");
                    }
                    MyGlobalEvents.RescheduleEvent(senderEvent as MyGlobalEventBase, NEUTRAL_SHIP_RESCHEDULE_TIME);
                    ProfilerShort.End();
                    return;
                }
                if (MyGravityProviderSystem.DoesTrajectoryIntersectNaturalGravity(shipPosition, shipDestination, spawnGroup.SpawnRadius + NEUTRAL_SHIP_SPAWN_OFFSET))
                {
                    if (!MyFinalBuildConstants.IS_OFFICIAL)
                    {
                        MySandboxGame.Log.WriteLine("Could not spawn neutral ships: flight path intersects gravity well");
                    }
                    MyGlobalEvents.RescheduleEvent(senderEvent as MyGlobalEventBase, NEUTRAL_SHIP_RESCHEDULE_TIME);
                    ProfilerShort.End();
                    return;
                }

                MyPhysics.CastRay(shipPosition, shipDestination, m_raycastHits, MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer);
                if (m_raycastHits.Count > 0)
                {
                    if (!MyFinalBuildConstants.IS_OFFICIAL)
                    {
                        MySandboxGame.Log.WriteLine("Could not spawn neutral ships due to collision");
                    }
                    MyGlobalEvents.RescheduleEvent(senderEvent as MyGlobalEventBase, NEUTRAL_SHIP_RESCHEDULE_TIME);
                    ProfilerShort.End();
                    return;
                }

                for (int i = 0; i < 4; ++i)
                {
                    Vector3D shiftVector = upVector * m_upVecMultipliers[i] * radius + rightVector * m_rightVecMultipliers[i] * radius;
                    MyPhysics.CastRay(shipPosition + shiftVector, shipDestination + shiftVector, m_raycastHits, MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer);

                    if (m_raycastHits.Count > 0)
                    {
                        if (!MyFinalBuildConstants.IS_OFFICIAL)
                        {
                            MySandboxGame.Log.WriteLine("Could not spawn neutral ships due to collision");
                        }
                        MyGlobalEvents.RescheduleEvent(senderEvent as MyGlobalEventBase, NEUTRAL_SHIP_RESCHEDULE_TIME);
                        ProfilerShort.End();
                        return;
                    }
                }
            }

            ProfilerShort.End();

            ProfilerShort.Begin("Spawn ships");

            long spawnGroupId = MyPirateAntennas.GetPiratesId();

            // The ships were collision-free. Now spawn them
            foreach (var shipPrefab in spawnGroup.Prefabs)
            {
                ProfilerShort.Begin(shipPrefab.BeaconText);

                // Yes, this could have been saved in the previous loop, but compared to (e.g.) raycasts, this does not take too much time to recalculate
                Vector3D shipPosition    = Vector3D.Transform((Vector3D)shipPrefab.Position, originMatrix);
                Vector3D shipDestination = shipPosition + directionMult;
                Vector3D up = Vector3D.CalculatePerpendicularVector(-direction);

                List <MyCubeGrid> tmpGridList = new List <MyCubeGrid>();

                // CH: We don't want a new identity for each ship anymore. We should handle that in a better way...

                /*if (shipPrefab.ResetOwnership)
                 * {
                 *  if (spawnGroupId == 0)
                 *  {
                 *      //This is not an NPC so that it doesn't show up in assign ownership drop down menu
                 *      MyIdentity spawnGroupIdentity = Sync.Players.CreateNewIdentity("Neutral NPC");
                 *      spawnGroupId = spawnGroupIdentity.IdentityId;
                 *  }
                 * }*/

                // Deploy ship
                ProfilerShort.Begin("Spawn cargo ship");
                Stack <Action> callbacks = new Stack <Action>();
                callbacks.Push(delegate()
                {
                    InitAutopilot(tmpGridList, shipDestination, direction);
                    foreach (var grid in tmpGridList)
                    {
                        Debug.Assert(grid.Physics.Enabled);
                        grid.ActivatePhysics(); //last chance to activate physics
                    }
                });
                MyPrefabManager.Static.SpawnPrefab(
                    resultList: tmpGridList,
                    prefabName: shipPrefab.SubtypeId,
                    position: shipPosition,
                    forward: direction,
                    up: up,
                    initialLinearVelocity: shipPrefab.Speed * direction,
                    beaconName: shipPrefab.BeaconText,
                    spawningOptions: VRage.Game.ModAPI.SpawningOptions.RotateFirstCockpitTowardsDirection |
                    VRage.Game.ModAPI.SpawningOptions.SpawnRandomCargo |
                    VRage.Game.ModAPI.SpawningOptions.DisableDampeners,
                    ownerId: shipPrefab.ResetOwnership ? spawnGroupId : 0,
                    callbacks: callbacks);
                ProfilerShort.End();
                ProfilerShort.End();
            }

            ProfilerShort.End();
        }
Ejemplo n.º 9
0
        private bool SpawnDrone(MyRadioAntenna antenna, long ownerId, Vector3D position, MySpawnGroupDefinition spawnGroup, Vector3?spawnUp = null, Vector3?spawnForward = null)
        {
            long     antennaEntityId = antenna.EntityId;
            Vector3D antennaPos      = antenna.PositionComp.GetPosition();

            Vector3D upVector;

            var planet = MyGamePruningStructure.GetClosestPlanet(position);

            if (planet != null)
            {
                if (!MyGravityProviderSystem.IsPositionInNaturalGravity(antennaPos))
                {
                    MySandboxGame.Log.WriteLine("Couldn't spawn drone; antenna is not in natural gravity but spawn location is.");
                    return(false);
                }
                planet.CorrectSpawnLocation(ref position, spawnGroup.SpawnRadius * 2.0);
                upVector = position - planet.PositionComp.GetPosition();
                upVector.Normalize();
            }
            else
            {
                var totalGravityInPoint = MyGravityProviderSystem.CalculateTotalGravityInPoint(position);
                if (totalGravityInPoint != Vector3.Zero)
                {
                    upVector = -totalGravityInPoint;
                    upVector.Normalize();
                }
                else if (spawnUp != null)
                {
                    upVector = spawnUp.Value;
                }
                else
                {
                    upVector = MyUtils.GetRandomVector3Normalized();
                }
            }

            Vector3D direction = MyUtils.GetRandomPerpendicularVector(ref upVector);

            if (spawnForward != null)
            {
                // Align forward to up vector.
                Vector3 forward = spawnForward.Value;
                if (Math.Abs(Vector3.Dot(forward, upVector)) >= 0.98f)
                {
                    forward = Vector3.CalculatePerpendicularVector(upVector);
                }
                else
                {
                    Vector3 right = Vector3.Cross(forward, upVector);
                    right.Normalize();
                    forward = Vector3.Cross(upVector, right);
                    forward.Normalize();
                }

                direction = forward;
            }

            MatrixD originMatrix = MatrixD.CreateWorld(position, direction, upVector);

            foreach (var shipPrefab in spawnGroup.Prefabs)
            {
                Vector3D shipPosition = Vector3D.Transform((Vector3D)shipPrefab.Position, originMatrix);

                List <MyCubeGrid> tmpGridList = new List <MyCubeGrid>();

                Stack <Action> callback = new Stack <Action>();
                callback.Push(delegate() { ChangeDroneOwnership(tmpGridList, ownerId, antennaEntityId); });

                MyPrefabManager.Static.SpawnPrefab(
                    resultList: tmpGridList,
                    prefabName: shipPrefab.SubtypeId,
                    position: shipPosition,
                    forward: direction,
                    up: upVector,
                    initialLinearVelocity: default(Vector3),
                    beaconName: null,
                    spawningOptions: VRage.Game.ModAPI.SpawningOptions.None,
                    ownerId: ownerId,
                    updateSync: true, callbacks: callback);
            }
            return(true);
        }
        public static bool CalculateRegularTravelPath(MySpawnGroupDefinition spawnGroup, Vector3D startCoords, out Vector3D startPathCoords, out Vector3D endPathCoords)
        {
            startPathCoords = Vector3D.Zero;
            endPathCoords   = Vector3D.Zero;
            SpawnResources.RefreshEntityLists();
            MyPlanet         planet         = SpawnResources.GetNearestPlanet(startCoords);
            List <IMyEntity> nearbyEntities = new List <IMyEntity>();

            for (int i = 0; i < Settings.SpaceCargoShips.MaxSpawnAttempts; i++)
            {
                var randDir = Vector3D.Normalize(MyUtils.GetRandomVector3D());

                var closestPathDist  = (double)SpawnResources.rnd.Next((int)Settings.SpaceCargoShips.MinPathDistanceFromPlayer, (int)Settings.SpaceCargoShips.MaxPathDistanceFromPlayer);
                var closestPathPoint = randDir * closestPathDist + startCoords;

                bool tryInvertedDir = SpawnResources.IsPositionInGravity(closestPathPoint, planet);

                if (tryInvertedDir == true)
                {
                    randDir          = randDir * -1;
                    closestPathPoint = randDir * closestPathDist + startCoords;

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

                var pathDist     = (double)SpawnResources.rnd.Next((int)Settings.SpaceCargoShips.MinPathDistance, (int)Settings.SpaceCargoShips.MaxPathDistance);
                var pathDir      = Vector3D.Normalize(MyUtils.GetRandomPerpendicularVector(ref randDir));
                var pathHalfDist = pathDist / 2;

                var tempPathStart = pathDir * pathHalfDist + closestPathPoint;
                pathDir = pathDir * -1;
                var tempPathEnd = pathDir * pathHalfDist + closestPathPoint;

                bool badPath = false;

                IHitInfo hitInfo = null;

                if (MyAPIGateway.Physics.CastLongRay(tempPathStart, tempPathEnd, out hitInfo, true) == true)
                {
                    continue;
                }

                foreach (var entity in SpawnResources.EntityList)
                {
                    if (Vector3D.Distance(tempPathStart, entity.GetPosition()) < Settings.SpaceCargoShips.MinSpawnDistFromEntities)
                    {
                        badPath = true;
                        break;
                    }
                }

                if (badPath == true)
                {
                    continue;
                }

                var upDir      = Vector3D.CalculatePerpendicularVector(pathDir);
                var pathMatrix = MatrixD.CreateWorld(tempPathStart, pathDir, upDir);

                foreach (var prefab in spawnGroup.Prefabs)
                {
                    double stepDistance    = 0;
                    var    tempPrefabStart = Vector3D.Transform((Vector3D)prefab.Position, pathMatrix);

                    while (stepDistance < pathDist)
                    {
                        stepDistance += Settings.SpaceCargoShips.PathCheckStep;
                        var pathCheckCoords = pathDir * stepDistance + tempPrefabStart;

                        if (SpawnResources.IsPositionInSafeZone(pathCheckCoords) == true || SpawnResources.IsPositionInGravity(pathCheckCoords, planet) == true)
                        {
                            badPath = true;
                            break;
                        }
                    }

                    if (badPath == true)
                    {
                        break;
                    }
                }

                if (badPath == true)
                {
                    continue;
                }

                startPathCoords = tempPathStart;
                endPathCoords   = tempPathEnd;
                return(true);
            }

            return(false);
        }
Ejemplo n.º 11
0
        public ImprovedSpawnGroup()
        {
            SpawnGroupEnabled = true;
            SpawnGroupName    = "";
            SpawnGroup        = null;

            SpaceCargoShip       = false;
            LunarCargoShip       = false;
            AtmosphericCargoShip = false;

            SpaceRandomEncounter = false;

            PlanetaryInstallation     = false;
            PlanetaryInstallationType = "Small";
            SkipTerrainCheck          = false;
            RotateInstallations       = new List <Vector3D>();
            ReverseForwardDirections  = new List <bool>();

            CutVoxelsAtAirtightCells = false;

            BossEncounterSpace = false;
            BossEncounterAtmo  = false;
            BossEncounterAny   = false;

            RivalAiSpawn            = false;
            RivalAiSpaceSpawn       = false;
            RivalAiAtmosphericSpawn = false;
            RivalAiAnySpawn         = false;

            Frequency                    = 0;
            UniqueEncounter              = false;
            FactionOwner                 = "SPRT";
            UseRandomMinerFaction        = false;
            UseRandomBuilderFaction      = false;
            UseRandomTraderFaction       = false;
            IgnoreCleanupRules           = false;
            ReplenishSystems             = false;
            UseNonPhysicalAmmo           = false;
            RemoveContainerContents      = false;
            InitializeStoreBlocks        = false;
            ContainerTypesForStoreOrders = new List <string>();
            ForceStaticGrid              = false;
            AdminSpawnOnly               = false;
            SandboxVariables             = new List <string>();
            FalseSandboxVariables        = new List <string>();
            RandomNumberRoll             = 1;
            UseCommonConditions          = true;

            UseAutoPilotInSpace            = false;
            PauseAutopilotAtPlayerDistance = -1;

            PreventOwnershipChange = false;

            RandomizeWeapons          = false;
            IgnoreWeaponRandomizerMod = false;
            IgnoreWeaponRandomizerTargetGlobalBlacklist = false;
            IgnoreWeaponRandomizerTargetGlobalWhitelist = false;
            IgnoreWeaponRandomizerGlobalBlacklist       = false;
            IgnoreWeaponRandomizerGlobalWhitelist       = false;
            WeaponRandomizerTargetBlacklist             = new List <string>();
            WeaponRandomizerTargetWhitelist             = new List <string>();
            WeaponRandomizerBlacklist = new List <string>();
            WeaponRandomizerWhitelist = new List <string>();

            AddDefenseShieldBlocks  = false;
            IgnoreShieldProviderMod = false;

            UseBlockReplacer      = false;
            ReplaceBlockReference = new Dictionary <MyDefinitionId, MyDefinitionId>();

            UseBlockReplacerProfile   = false;
            BlockReplacerProfileNames = new List <string>();

            RelaxReplacedBlocksSize = false;
            AlwaysRemoveBlock       = false;

            IgnoreGlobalBlockReplacer = false;

            ConvertToHeavyArmor = false;

            UseRandomNameGenerator = false;
            RandomGridNamePrefix   = "";
            RandomGridNamePattern  = "";
            ReplaceAntennaNameWithRandomizedName = "";

            UseBlockNameReplacer       = false;
            BlockNameReplacerReference = new Dictionary <string, string>();

            AssignContainerTypesToAllCargo = new List <string>();

            UseContainerTypeAssignment       = false;
            ContainerTypeAssignmentReference = new Dictionary <string, string>();

            OverrideBlockDamageModifier = false;
            BlockDamageModifier         = 1;

            GridsAreEditable     = true;
            GridsAreDestructable = true;

            ShiftBlockColorsHue   = false;
            RandomHueShift        = false;
            ShiftBlockColorAmount = 0;

            AssignGridSkin = new List <string>();

            RecolorGrid             = false;
            ColorReferencePairs     = new Dictionary <Vector3, Vector3>();
            ColorSkinReferencePairs = new Dictionary <Vector3, string>();

            ReduceBlockBuildStates   = false;
            AffectNonFunctionalBlock = true;
            AffectFunctionalBlock    = false;
            MinimumBlocksPercent     = 10;
            MaximumBlocksPercent     = 40;
            MinimumBuildPercent      = 10;
            MaximumBuildPercent      = 75;

            UseRivalAi = false;
            RivalAiReplaceRemoteControl = false;

            EraseIngameScripts    = false;
            DisableTimerBlocks    = false;
            DisableSensorBlocks   = false;
            DisableWarheads       = false;
            DisableThrustOverride = false;
            DisableGyroOverride   = false;
            EraseLCDs             = false;
            UseTextureLCD         = new List <string>();

            EnableBlocksWithName  = new List <string>();
            DisableBlocksWithName = new List <string>();
            AllowPartialNames     = false;

            ChangeTurretSettings   = false;
            TurretRange            = 800;
            TurretIdleRotation     = false;
            TurretTargetMeteors    = true;
            TurretTargetMissiles   = true;
            TurretTargetCharacters = true;
            TurretTargetSmallGrids = true;
            TurretTargetLargeGrids = true;
            TurretTargetStations   = true;
            TurretTargetNeutrals   = true;

            ClearAuthorship = false;

            MinSpawnFromWorldCenter  = -1;
            MaxSpawnFromWorldCenter  = -1;
            DirectionFromWorldCenter = Vector3D.Zero;
            MinAngleFromDirection    = -1;
            MaxAngleFromDirection    = -1;

            MinSpawnFromPlanetSurface = -1;
            MaxSpawnFromPlanetSurface = -1;

            UseDayOrNightOnly = false;
            SpawnOnlyAtNight  = false;

            UseWeatherSpawning    = false;
            AllowedWeatherSystems = new List <string>();

            UseTerrainTypeValidation = false;
            AllowedTerrainTypes      = new List <string>();

            MinAirDensity = -1;
            MaxAirDensity = -1;
            MinGravity    = -1;
            MaxGravity    = -1;

            PlanetBlacklist      = new List <string>();
            PlanetWhitelist      = new List <string>();
            PlanetRequiresVacuum = false;
            PlanetRequiresAtmo   = false;
            PlanetRequiresOxygen = false;
            PlanetMinimumSize    = -1;
            PlanetMaximumSize    = -1;

            UsePlayerCountCheck    = false;
            PlayerCountCheckRadius = -1;
            MinimumPlayers         = -1;
            MaximumPlayers         = -1;

            UseThreatLevelCheck         = false;
            ThreatLevelCheckRange       = 5000;
            ThreatIncludeOtherNpcOwners = false;
            ThreatScoreMinimum          = -1;
            ThreatScoreMaximum          = -1;

            UsePCUCheck    = false;
            PCUCheckRadius = 5000;
            PCUMinimum     = -1;
            PCUMaximum     = -1;

            UsePlayerCredits          = false;
            IncludeAllPlayersInRadius = false;
            IncludeFactionBalance     = false;
            PlayerCreditsCheckRadius  = 15000;
            MinimumPlayerCredits      = -1;
            MaximumPlayerCredits      = -1;

            UsePlayerFactionReputation            = false;
            PlayerReputationCheckRadius           = 15000;
            CheckReputationAgainstOtherNPCFaction = "";
            MinimumReputation = -1501;
            MaximumReputation = 1501;

            RequireAllMods = new List <ulong>();
            RequireAnyMods = new List <ulong>();
            ExcludeAllMods = new List <ulong>();
            ExcludeAnyMods = new List <ulong>();

            ModBlockExists = new List <string>();

            RequiredPlayersOnline = new List <ulong>();

            AttachModStorageComponentToGrid = false;
            StorageKey   = new Guid("00000000-0000-0000-0000-000000000000");
            StorageValue = "";

            UseKnownPlayerLocations                 = false;
            KnownPlayerLocationMustMatchFaction     = false;
            KnownPlayerLocationMinSpawnedEncounters = -1;
            KnownPlayerLocationMaxSpawnedEncounters = -1;

            Territory = "";
            MinDistanceFromTerritoryCenter = -1;
            MaxDistanceFromTerritoryCenter = -1;

            BossCustomAnnounceEnable  = false;
            BossCustomAnnounceAuthor  = "";
            BossCustomAnnounceMessage = "";
            BossCustomGPSLabel        = "Dangerous Encounter";
            BossMusicId = "";

            RotateFirstCockpitToForward = true;
            PositionAtFirstCockpit      = false;
            SpawnRandomCargo            = true;
            DisableDampeners            = false;
            ReactorsOn                = true;
            UseBoundingBoxCheck       = false;
            RemoveVoxelsIfGridRemoved = true;
        }
Ejemplo n.º 12
0
        public static void SpawnCargoShip(bool checkGravity)
        {
            Init(  );
            Wrapper.GameAction(() =>
            {
                if (ExtenderOptions.IsDebugging)
                {
                    Essentials.Log.Info("Spawn cargo ship");
                }
                // Select a spawn group to spawn
                MySpawnGroupDefinition spawnGroup = PickRandomSpawnGroup( );
                if (spawnGroup == null)
                {
                    return;
                }

                spawnGroup.ReloadPrefabs( );

                double spawnDistance    = NEUTRAL_SHIP_SPAWN_DISTANCE;
                Vector3D playerPosition = Vector3D.Zero;
                bool isWorldLimited     = MyEntities.IsWorldLimited( );
                int numPlayers          = 0;

                if (isWorldLimited)
                {
                    spawnDistance = Math.Min(spawnDistance, MyEntities.WorldSafeHalfExtent( ) - spawnGroup.SpawnRadius);
                }
                else
                {
                    // In infinite worlds players can be thousands of kilometers away, so spawn ship around random player
                    // so cargo ships will be spawned around every player at some time
                    var players = MySession.Static.Players.GetOnlinePlayers( );
                    // In DS there can be no players connected
                    numPlayers = Math.Max(0, players.Count - 1);
                    int randomPlayerPosition = MyUtils.GetRandomInt(0, numPlayers);
                    int i = 0;
                    foreach (var player in players)
                    {
                        if (i == randomPlayerPosition)
                        {
                            if (player.Character != null)
                            {
                                playerPosition = player.GetPosition( );
                            }
                            break;
                        }
                        i++;
                    }
                }

                if (spawnDistance < 0.0f)
                {
                    if (ExtenderOptions.IsDebugging)
                    {
                        Essentials.Log.Info("Not enough space in the world to spawn such a huge spawn group!");
                    }
                    return;
                }

                double forbiddenRadius = NEUTRAL_SHIP_FORBIDDEN_RADIUS;
                BoundingBoxD spawnBox;
                if (isWorldLimited)
                {
                    spawnBox = new BoundingBoxD(new Vector3D(playerPosition - spawnDistance), new Vector3D(playerPosition + spawnDistance));
                }
                else
                {
                    // We need to extend bouding box so cargo ships aren't spawned near other players
                    GetSafeBoundingBoxForPlayers(playerPosition, spawnDistance, out spawnBox);
                    // Forbidden radius is sphere around all players in box.
                    // Bounding box is generated from players positions so their distance to center shall be same for all players
                    forbiddenRadius += spawnBox.HalfExtents.Max( ) - NEUTRAL_SHIP_FORBIDDEN_RADIUS;
                }
                // Get the direction to the center and deviate it randomly
                Vector3D?origin = MyUtils.GetRandomBorderPosition(ref spawnBox);

                origin = MyEntities.FindFreePlace(origin.Value, spawnGroup.SpawnRadius);
                if (!origin.HasValue)
                {
                    if (ExtenderOptions.IsDebugging)
                    {
                        Essentials.Log.Info("Couldn't find free place for cargo spawn");
                    }
                    return;
                }

                // Radius in arc units of the forbidden sphere in the center, when viewed from origin
                float centerArcRadius = (float)Math.Atan(forbiddenRadius / (origin.Value - spawnBox.Center).Length( ));

                // Generate direction with elevation from centerArcRadius radians to (cAR + N_S_D_S) radians
                Vector3D direction = -Vector3D.Normalize(origin.Value);
                float theta        = MyUtils.GetRandomFloat(centerArcRadius, centerArcRadius + NEUTRAL_SHIP_DIRECTION_SPREAD);
                float phi          = MyUtils.GetRandomRadian( );
                Vector3D cosVec    = Vector3D.CalculatePerpendicularVector(direction);
                Vector3D sinVec    = Vector3D.Cross(direction, cosVec);
                cosVec            *= (Math.Sin(theta) * Math.Cos(phi));
                sinVec            *= (Math.Sin(theta) * Math.Sin(phi));
                direction          = direction * Math.Cos(theta) + cosVec + sinVec;

                Vector3D destination = Vector3D.Zero;
                RayD ray             = new RayD(origin.Value, direction);
                double?intersection  = ray.Intersects(spawnBox);
                Vector3D directionMult;
                if (!intersection.HasValue || intersection.Value < NEUTRAL_SHIP_MINIMAL_ROUTE_LENGTH)
                {
                    directionMult = direction * NEUTRAL_SHIP_MINIMAL_ROUTE_LENGTH;
                }
                else
                {
                    directionMult = direction * intersection.Value;
                }
                destination = origin.Value + directionMult;

                Vector3D upVector    = Vector3D.CalculatePerpendicularVector(direction);
                Vector3D rightVector = Vector3D.Cross(direction, upVector);
                MatrixD originMatrix = MatrixD.CreateWorld(origin.Value, direction, upVector);

                // CH:TODO: Convex cast to detect collision
                // Check ships' path to avoid possible collisions. (TODO: But only if it is said in the definitions)
                m_raycastHits.Clear( );
                foreach (var shipPrefab in spawnGroup.Prefabs)
                {
                    var prefabDef = MyDefinitionManager.Static.GetPrefabDefinition(shipPrefab.SubtypeId);
                    Debug.Assert(prefabDef != null);

                    Vector3D shipPosition    = Vector3.Transform(shipPrefab.Position, originMatrix);
                    Vector3D shipDestination = shipPosition + directionMult;
                    float radius             = prefabDef == null ? 10.0f : prefabDef.BoundingSphere.Radius;

                    if (checkGravity)
                    {
                        //these point checks could be done in the trajectory intersect, but checking points is faster than ray intersect
                        if (MyGravityProviderSystem.IsPositionInNaturalGravity(shipPosition, spawnGroup.SpawnRadius))
                        {
                            if (ExtenderOptions.IsDebugging)
                            {
                                Essentials.Log.Info("Failed to spawn cargo ship: Spawn location is in gravity well");
                            }
                            return;
                        }
                        if (MyGravityProviderSystem.IsPositionInNaturalGravity(shipDestination, spawnGroup.SpawnRadius))
                        {
                            if (ExtenderOptions.IsDebugging)
                            {
                                Essentials.Log.Info("Failed to spawn cargo ship: Destination is in gravity well");
                            }
                        }
                        if (MyGravityProviderSystem.DoesTrajectoryIntersectNaturalGravity(shipPosition, shipDestination, spawnGroup.SpawnRadius + 500))
                        {
                            if (ExtenderOptions.IsDebugging)
                            {
                                Essentials.Log.Info("Failed to spawn cargo ship: Ship path intersects gravity well");
                            }
                            return;
                        }
                    }

                    MyPhysics.CastRay(shipPosition, shipDestination, m_raycastHits, MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer);
                    if (m_raycastHits.Count > 0)
                    {
                        if (ExtenderOptions.IsDebugging)
                        {
                            Essentials.Log.Info("Failed to spawn cargo ship: Ship path intersects another object");
                        }
                        return;
                    }

                    for (int i = 0; i < 4; ++i)
                    {
                        Vector3D shiftVector = upVector * m_upVecMultipliers[i] * radius + rightVector * m_rightVecMultipliers[i] * radius;
                        MyPhysics.CastRay(shipPosition + shiftVector, shipDestination + shiftVector, m_raycastHits, MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer);

                        if (m_raycastHits.Count > 0)
                        {
                            if (ExtenderOptions.IsDebugging)
                            {
                                Essentials.Log.Info("Failed to spawn cargo ship: Ship path intersects another object");
                            }
                            return;
                        }
                    }
                }

                long spawnGroupId = MyPirateAntennas.GetPiratesId( );

                // The ships were collision-free. Now spawn them
                foreach (var shipPrefab in spawnGroup.Prefabs)
                {
                    // Yes, this could have been saved in the previous loop, but compared to (e.g.) raycasts, this does not take too much time to recalculate
                    Vector3D shipPosition    = Vector3D.Transform((Vector3D)shipPrefab.Position, originMatrix);
                    Vector3D shipDestination = shipPosition + directionMult;
                    Vector3D up = Vector3D.CalculatePerpendicularVector(-direction);

                    m_tmpGridList.Clear( );

                    // CH: We don't want a new identity for each ship anymore. We should handle that in a better way...

                    /*if (shipPrefab.ResetOwnership)
                     * {
                     * if (spawnGroupId == 0)
                     * {
                     * //This is not an NPC so that it doesn't show up in assign ownership drop down menu
                     * MyIdentity spawnGroupIdentity = Sync.Players.CreateNewIdentity("Neutral NPC");
                     * spawnGroupId = spawnGroupIdentity.IdentityId;
                     * }
                     * }*/

                    // Deploy ship
                    MyPrefabManager.Static.SpawnPrefab(
                        resultList: m_tmpGridList,
                        prefabName: shipPrefab.SubtypeId,
                        position: shipPosition,
                        forward: direction,
                        up: up,
                        initialLinearVelocity: shipPrefab.Speed * direction,
                        beaconName: shipPrefab.BeaconText,
                        spawningOptions: VRage.Game.ModAPI.SpawningOptions.RotateFirstCockpitTowardsDirection |
                        VRage.Game.ModAPI.SpawningOptions.SpawnRandomCargo |
                        VRage.Game.ModAPI.SpawningOptions.DisableDampeners,
                        ownerId: shipPrefab.ResetOwnership ? spawnGroupId : 0,
                        updateSync: true);

                    /*
                     * foreach (var grid in m_tmpGridList)
                     * {
                     * var cockpit = grid.GetFirstBlockOfType<MyCockpit>();
                     * if (cockpit != null)
                     * {
                     * MySimpleAutopilot ai = new MySimpleAutopilot(shipDestination, (Vector3)direction);
                     * cockpit.AttachAutopilot(ai);
                     * break;
                     * }
                     * }
                     */
                    m_tmpGridList.Clear( );
                }
            });
        }
Ejemplo n.º 13
0
        private bool SpawnDrone(long antennaEntityId, long ownerId, Vector3D position, MySpawnGroupDefinition spawnGroup)
        {
            Vector3D direction    = MyUtils.GetRandomVector3Normalized();
            Vector3D upVector     = Vector3D.CalculatePerpendicularVector(direction);
            MatrixD  originMatrix = MatrixD.CreateWorld(position, direction, upVector);

            foreach (var shipPrefab in spawnGroup.Prefabs)
            {
                Vector3D shipPosition = Vector3D.Transform((Vector3D)shipPrefab.Position, originMatrix);

                m_tmpGridList.Clear();

                MyPrefabManager.Static.SpawnPrefab(
                    resultList: m_tmpGridList,
                    prefabName: shipPrefab.SubtypeId,
                    position: shipPosition,
                    forward: direction,
                    up: upVector,
                    initialLinearVelocity: default(Vector3),
                    beaconName: null,
                    spawningOptions: Sandbox.ModAPI.SpawningOptions.None,
                    ownerId: ownerId,
                    updateSync: true);

                foreach (var grid in m_tmpGridList)
                {
                    grid.ChangeGridOwnership(ownerId, MyOwnershipShareModeEnum.None);

                    MyRemoteControl firstRemote = null;

                    foreach (var block in grid.CubeBlocks)
                    {
                        if (block.FatBlock == null)
                        {
                            continue;
                        }

                        var pb = block.FatBlock as MyProgrammableBlock;
                        if (pb != null)
                        {
                            pb.SendRecompile();
                        }

                        var remote = block.FatBlock as MyRemoteControl;
                        if (firstRemote == null)
                        {
                            firstRemote = remote;
                        }
                    }

                    // If there's no remote control on the grid, we have to register it as is
                    RegisterDrone(antennaEntityId, (MyEntity)firstRemote ?? (MyEntity)grid);
                }

                m_tmpGridList.Clear();
            }
            return(true);
        }
        public void SpawnCargoShipGroup(Vector3 startPosition, Vector3 stopPosition, ulong remoteUserId = 0)
        {
            try
            {
                //Calculate lowest and highest frequencies
                float lowestFrequency  = 999999;
                float highestFrequency = 0;
                foreach (MySpawnGroupDefinition entry in MyDefinitionManager.Static.GetSpawnGroupDefinitions())
                {
                    if (entry.Frequency < lowestFrequency)
                    {
                        lowestFrequency = entry.Frequency;
                    }
                    if (entry.Frequency > highestFrequency)
                    {
                        highestFrequency = entry.Frequency;
                    }
                }
                if (lowestFrequency <= 0)
                {
                    lowestFrequency = 1;
                }

                //Get a list of which groups *could* spawn
                Random random       = new Random((int)DateTime.Now.ToBinary());
                double randomChance = random.NextDouble();
                randomChance = randomChance * (highestFrequency / lowestFrequency);
                List <MySpawnGroupDefinition> possibleGroups = new List <MySpawnGroupDefinition>();
                foreach (MySpawnGroupDefinition entry in MyDefinitionManager.Static.GetSpawnGroupDefinitions())
                {
                    if (entry.Frequency >= randomChance)
                    {
                        possibleGroups.Add(entry);
                    }
                }

                //Determine which group *will* spawn
                randomChance = random.NextDouble();
                int randomShipIndex = Math.Max(0, Math.Min((int)Math.Round(randomChance * possibleGroups.Count, 0), possibleGroups.Count - 1));
                MySpawnGroupDefinition randomSpawnGroup = possibleGroups[randomShipIndex];

                ChatManager.Instance.SendPrivateChatMessage(remoteUserId, "Spawning cargo group '" + randomSpawnGroup.DisplayNameText.ToString() + "' ...");

                //Spawn the ships in the group
                Matrix orientation = Matrix.CreateLookAt(startPosition, stopPosition, new Vector3(0, 1, 0));
                foreach (MySpawnGroupDefinition.SpawnGroupPrefab entry in randomSpawnGroup.Prefabs)
                {
                    MyPrefabDefinition matchedPrefab = null;
                    foreach (var prefabEntry in MyDefinitionManager.Static.GetPrefabDefinitions())
                    {
                        MyPrefabDefinition prefabDefinition = prefabEntry.Value;
                        if (prefabDefinition.Id.SubtypeId.ToString() == entry.SubtypeId)
                        {
                            matchedPrefab = prefabDefinition;
                            break;
                        }
                    }
                    if (matchedPrefab == null)
                    {
                        continue;
                    }

                    //TODO - Build this to iterate through all cube grids in the prefab
                    MyObjectBuilder_CubeGrid objectBuilder = matchedPrefab.CubeGrids[0];

                    //Create the ship
                    CubeGridEntity cubeGrid = new CubeGridEntity(objectBuilder);

                    //Set the ship position and orientation
                    Vector3 shipPosition = Vector3.Transform(entry.Position, orientation) + startPosition;
                    orientation.Translation = shipPosition;
                    MyPositionAndOrientation newPositionOrientation = new MyPositionAndOrientation(orientation);
                    cubeGrid.PositionAndOrientation = newPositionOrientation;

                    //Set the ship velocity
                    //Speed is clamped between 1.0f and the max cube grid speed
                    Vector3 travelVector = stopPosition - startPosition;
                    travelVector.Normalize();
                    Vector3 shipVelocity = travelVector * (float)Math.Min(cubeGrid.MaxLinearVelocity, Math.Max(1.0f, entry.Speed));
                    cubeGrid.LinearVelocity = shipVelocity;

                    cubeGrid.IsDampenersEnabled = false;

                    foreach (MyObjectBuilder_CubeBlock cubeBlock in cubeGrid.BaseCubeBlocks)
                    {
                        //Set the beacon names
                        if (cubeBlock.TypeId == typeof(MyObjectBuilder_Beacon))
                        {
                            MyObjectBuilder_Beacon beacon = (MyObjectBuilder_Beacon)cubeBlock;
                            beacon.CustomName = entry.BeaconText;
                        }

                        //Set the owner of every block
                        //TODO - Find out if setting to an arbitrary non-zero works for this
                        //cubeBlock.Owner = PlayerMap.Instance.GetServerVirtualPlayerId();
                        cubeBlock.Owner     = 0;
                        cubeBlock.ShareMode = MyOwnershipShareModeEnum.Faction;
                    }

                    //And add the ship to the world
                    SectorObjectManager.Instance.AddEntity(cubeGrid);
                }

                ChatManager.Instance.SendPrivateChatMessage(remoteUserId, "Cargo group '" + randomSpawnGroup.DisplayNameText.ToString() + "' spawned with " + randomSpawnGroup.Prefabs.Count.ToString() + " ships at " + startPosition.ToString());
            }
            catch (Exception ex)
            {
                LogManager.ErrorLog.WriteLine(ex);
            }
        }
        public static bool CalculateLunarTravelPath(MySpawnGroupDefinition spawnGroup, Vector3D startCoords, out Vector3D startPathCoords, out Vector3D endPathCoords)
        {
            startPathCoords = Vector3D.Zero;
            endPathCoords   = Vector3D.Zero;
            SpawnResources.RefreshEntityLists();
            MyPlanet planet = SpawnResources.GetNearestPlanet(startCoords);

            if (planet == null)
            {
                return(false);
            }

            var planetEntity = planet as IMyEntity;

            for (int i = 0; i < Settings.SpaceCargoShips.MaxSpawnAttempts; i++)
            {
                var spawnAltitude = (double)SpawnResources.rnd.Next((int)Settings.SpaceCargoShips.MinLunarSpawnHeight, (int)Settings.SpaceCargoShips.MaxLunarSpawnHeight);
                var abovePlayer   = SpawnResources.CreateDirectionAndTarget(planetEntity.GetPosition(), startCoords, startCoords, spawnAltitude);
                var midpointDist  = (double)SpawnResources.rnd.Next((int)Settings.SpaceCargoShips.MinPathDistanceFromPlayer, (int)Settings.SpaceCargoShips.MaxPathDistanceFromPlayer);
                var pathMidpoint  = SpawnResources.GetRandomCompassDirection(abovePlayer, planet) * midpointDist + abovePlayer;
                var pathDist      = (double)SpawnResources.rnd.Next((int)Settings.SpaceCargoShips.MinPathDistance, (int)Settings.SpaceCargoShips.MaxPathDistance);
                var pathDir       = SpawnResources.GetRandomCompassDirection(abovePlayer, planet);
                var pathHalfDist  = pathDist / 2;

                var tempPathStart = pathDir * pathHalfDist + pathMidpoint;
                pathDir = pathDir * -1;
                var tempPathEnd = pathDir * pathHalfDist + pathMidpoint;

                bool badPath = false;

                IHitInfo hitInfo = null;

                if (MyAPIGateway.Physics.CastLongRay(tempPathStart, tempPathEnd, out hitInfo, true) == true)
                {
                    continue;
                }


                foreach (var entity in SpawnResources.EntityList)
                {
                    if (Vector3D.Distance(tempPathStart, entity.GetPosition()) < Settings.SpaceCargoShips.MinSpawnDistFromEntities)
                    {
                        badPath = true;
                        break;
                    }
                }

                if (badPath == true)
                {
                    continue;
                }

                var upDir      = Vector3D.CalculatePerpendicularVector(pathDir);
                var pathMatrix = MatrixD.CreateWorld(tempPathStart, pathDir, upDir);

                foreach (var prefab in spawnGroup.Prefabs)
                {
                    double stepDistance    = 0;
                    var    tempPrefabStart = Vector3D.Transform((Vector3D)prefab.Position, pathMatrix);

                    while (stepDistance < pathDist)
                    {
                        stepDistance += Settings.SpaceCargoShips.PathCheckStep;
                        var pathCheckCoords = pathDir * stepDistance + tempPrefabStart;

                        if (SpawnResources.IsPositionInSafeZone(pathCheckCoords) == true || SpawnResources.IsPositionInGravity(pathCheckCoords, planet) == true)
                        {
                            badPath = true;
                            break;
                        }
                    }

                    if (badPath == true)
                    {
                        break;
                    }
                }

                if (badPath == true)
                {
                    continue;
                }

                startPathCoords = tempPathStart;
                endPathCoords   = tempPathEnd;

                return(true);
            }

            return(false);
        }
Ejemplo n.º 16
0
        private bool SpawnDrone(MyRadioAntenna antenna, long ownerId, Vector3D position, MySpawnGroupDefinition spawnGroup)
        {
            long     antennaEntityId = antenna.EntityId;
            Vector3D antennaPos      = antenna.PositionComp.GetPosition();

            var planet = MyGravityProviderSystem.GetStrongestGravityWell(position);

            Vector3D upVector;

            if (planet != null && planet.IsPositionInGravityWell(position))
            {
                if (!MyGravityProviderSystem.IsPositionInNaturalGravity(antennaPos))
                {
                    MySandboxGame.Log.WriteLine("Couldn't spawn drone; antenna is not in natural gravity but spawn location is.");
                    return(false);
                }
                planet.CorrectSpawnLocation(ref position, spawnGroup.SpawnRadius * 2.0);
                upVector = -planet.GetWorldGravityNormalized(ref position);
            }
            else
            {
                upVector = MyUtils.GetRandomVector3Normalized();
            }

            Vector3D direction    = MyUtils.GetRandomPerpendicularVector(ref upVector);
            MatrixD  originMatrix = MatrixD.CreateWorld(position, direction, upVector);

            foreach (var shipPrefab in spawnGroup.Prefabs)
            {
                Vector3D shipPosition = Vector3D.Transform((Vector3D)shipPrefab.Position, originMatrix);

                m_tmpGridList.Clear();

                MyPrefabManager.Static.SpawnPrefab(
                    resultList: m_tmpGridList,
                    prefabName: shipPrefab.SubtypeId,
                    position: shipPosition,
                    forward: direction,
                    up: upVector,
                    initialLinearVelocity: default(Vector3),
                    beaconName: null,
                    spawningOptions: VRage.Game.ModAPI.SpawningOptions.None,
                    ownerId: ownerId,
                    updateSync: true);

                foreach (var grid in m_tmpGridList)
                {
                    grid.ChangeGridOwnership(ownerId, MyOwnershipShareModeEnum.None);

                    MyRemoteControl firstRemote = null;

                    foreach (var block in grid.CubeBlocks)
                    {
                        if (block.FatBlock == null)
                        {
                            continue;
                        }

                        var pb = block.FatBlock as MyProgrammableBlock;
                        if (pb != null)
                        {
                            pb.SendRecompile();
                        }

                        var remote = block.FatBlock as MyRemoteControl;
                        if (firstRemote == null)
                        {
                            firstRemote = remote;
                        }
                    }

                    // If there's no remote control on the grid, we have to register it as is
                    RegisterDrone(antennaEntityId, (MyEntity)firstRemote ?? (MyEntity)grid);
                }

                m_tmpGridList.Clear();
            }
            return(true);
        }
Ejemplo n.º 17
0
        public void SpawnCargoShipGroup(Vector3 startPosition, Vector3 stopPosition, ulong remoteUserId = 0)
        {
            try
            {
                //Calculate lowest and highest frequencies
                double lowestFrequency  = double.MaxValue;
                double highestFrequency = 0d;
                foreach (MySpawnGroupDefinition entry in MyDefinitionManager.Static.GetSpawnGroupDefinitions( ))
                {
                    if (entry.Frequency < lowestFrequency)
                    {
                        lowestFrequency = entry.Frequency;
                    }
                    if (entry.Frequency > highestFrequency)
                    {
                        highestFrequency = entry.Frequency;
                    }
                }
                if (lowestFrequency <= 0d)
                {
                    lowestFrequency = 1d;
                }

                //Get a list of which groups *could* spawn
                Random random       = new Random( );
                double randomChance = random.NextDouble( );
                randomChance = randomChance * (highestFrequency / lowestFrequency);
                List <MySpawnGroupDefinition> possibleGroups = MyDefinitionManager.Static.GetSpawnGroupDefinitions( ).Where(entry => entry.Frequency >= randomChance).ToList( );

                //Determine which group *will* spawn
                randomChance = random.NextDouble( );
                int randomShipIndex = Math.Max(0, Math.Min((int)Math.Round(randomChance * possibleGroups.Count, 0), possibleGroups.Count - 1));
                MySpawnGroupDefinition randomSpawnGroup = possibleGroups[randomShipIndex];

                ChatManager.Instance.SendPrivateChatMessage(remoteUserId, string.Format("Spawning cargo group '{0}' ...", randomSpawnGroup.DisplayNameText));

                //Spawn the ships in the group
                Matrix orientation = Matrix.CreateLookAt(startPosition, stopPosition, new Vector3(0, 1, 0));
                foreach (MySpawnGroupDefinition.SpawnGroupPrefab entry in randomSpawnGroup.Prefabs)
                {
                    MyPrefabDefinition matchedPrefab =
                        MyDefinitionManager.Static.GetPrefabDefinitions( ).Select(prefabEntry => prefabEntry.Value).FirstOrDefault(prefabDefinition => prefabDefinition.Id.SubtypeId.ToString( ) == entry.SubtypeId);
                    if (matchedPrefab == null)
                    {
                        continue;
                    }

                    foreach (MyObjectBuilder_CubeGrid objectBuilder in matchedPrefab.CubeGrids)
                    {
                        //Create the ship
                        CubeGridEntity cubeGrid = new CubeGridEntity(objectBuilder);

                        //Set the ship position and orientation
                        Vector3 shipPosition = Vector3.Transform(entry.Position, orientation) + startPosition;
                        orientation.Translation = shipPosition;
                        MyPositionAndOrientation newPositionOrientation = new MyPositionAndOrientation(orientation);
                        cubeGrid.PositionAndOrientation = newPositionOrientation;

                        //Set the ship velocity
                        //Speed is clamped between 1.0f and the max cube grid speed
                        Vector3 travelVector = stopPosition - startPosition;
                        travelVector.Normalize( );
                        Vector3 shipVelocity = travelVector * Math.Min(cubeGrid.MaxLinearVelocity, Math.Max(1.0f, entry.Speed));
                        cubeGrid.LinearVelocity = shipVelocity;

                        //cubeGrid.IsDampenersEnabled = false;

                        foreach (MyObjectBuilder_CubeBlock cubeBlock in cubeGrid.BaseCubeBlocks)
                        {
                            //Set the beacon names
                            MyObjectBuilder_Beacon beacon = cubeBlock as MyObjectBuilder_Beacon;
                            if (beacon != null)
                            {
                                beacon.CustomName = entry.BeaconText;
                            }

                            //Set the owner of every block
                            //TODO - Find out if setting to an arbitrary non-zero works for this
                            //cubeBlock.Owner = PlayerMap.Instance.GetServerVirtualPlayerId();
                            cubeBlock.Owner     = 0;
                            cubeBlock.ShareMode = MyOwnershipShareModeEnum.Faction;
                        }

                        //And add the ship to the world
                        SectorObjectManager.Instance.AddEntity(cubeGrid);
                    }
                }

                ChatManager.Instance.SendPrivateChatMessage(remoteUserId,
                                                            string.Format("Cargo group '{0}' spawned with {1} ships at {2}", randomSpawnGroup.DisplayNameText, randomSpawnGroup.Prefabs.Count, startPosition));
            }
            catch (ArgumentOutOfRangeException ex)
            {
                ApplicationLog.BaseLog.Error(ex);
            }
            catch (ArgumentNullException ex)
            {
                ApplicationLog.BaseLog.Error(ex);
            }
            catch (FormatException ex)
            {
                ApplicationLog.BaseLog.Error(ex);
            }
            catch (Exception ex)
            {
                ApplicationLog.BaseLog.Error(ex);
            }
        }
Ejemplo n.º 18
0
        public static void OnGlobalSpawnEvent(object senderEvent)
        {
            // Select a spawn group to spawn
            MySpawnGroupDefinition spawnGroup = PickRandomSpawnGroup();

            if (spawnGroup == null)
            {
                return;
            }

            spawnGroup.ReloadPrefabs();

            ProfilerShort.Begin("Generate position and direction");

            double   spawnDistance  = NEUTRAL_SHIP_SPAWN_DISTANCE;
            Vector3D playerPosition = Vector3D.Zero;
            bool     isWorldLimited = MyEntities.IsWorldLimited();
            int      numPlayers     = 0;

            if (isWorldLimited)
            {
                spawnDistance = Math.Min(spawnDistance, MyEntities.WorldSafeHalfExtent() - spawnGroup.SpawnRadius);
            }
            else
            {
                // In infinite worlds players can be thousands of kilometers away, so spawn ship around random player
                // so cargo ships will be spawned around every player at some time
                var players = MySession.Static.Players.GetOnlinePlayers();
                // In DS there can be no players connected
                numPlayers = Math.Max(0, players.Count - 1);
                int randomPlayerPosition = MyUtils.GetRandomInt(0, numPlayers);
                int i = 0;
                foreach (var player in players)
                {
                    if (i == randomPlayerPosition)
                    {
                        if (player.Character != null)
                        {
                            playerPosition = player.GetPosition();
                        }
                        break;
                    }
                    i++;
                }
            }
            if (spawnDistance < 0.0f)
            {
                MySandboxGame.Log.WriteLine("Not enough space in the world to spawn such a huge spawn group!");
                return;
            }

            double       forbiddenRadius = NEUTRAL_SHIP_FORBIDDEN_RADIUS;
            BoundingBoxD spawnBox;

            if (isWorldLimited)
            {
                spawnBox = new BoundingBoxD(new Vector3D(playerPosition - spawnDistance), new Vector3D(playerPosition + spawnDistance));
            }
            else
            {
                // We need to extend bouding box so cargo ships aren't spawned near other players
                GetSafeBoundingBoxForPlayers(playerPosition, spawnDistance, out spawnBox);
                // Forbidden radius is sphere around all players in box.
                // Bounding box is generated from players positions so their distance to center shall be same for all players
                forbiddenRadius += spawnBox.HalfExtents.Max() - NEUTRAL_SHIP_FORBIDDEN_RADIUS;
            }

            // Get the direction to the center and deviate it randomly
            Vector3D?origin = MyUtils.GetRandomBorderPosition(ref spawnBox);

            origin = MyEntities.FindFreePlace(origin.Value, spawnGroup.SpawnRadius);
            if (!origin.HasValue)
            {
                MySandboxGame.Log.WriteLine("Could not spawn neutral ships - no free place found");
                MyGlobalEvents.RescheduleEvent(senderEvent as MyGlobalEventBase, NEUTRAL_SHIP_RESCHEDULE_TIME);
                ProfilerShort.End();
                return;
            }

            // Radius in arc units of the forbidden sphere in the center, when viewed from origin
            float centerArcRadius = (float)Math.Atan(forbiddenRadius / (origin.Value - spawnBox.Center).Length());

            // Generate direction with elevation from centerArcRadius radians to (cAR + N_S_D_S) radians
            Vector3D direction = -Vector3D.Normalize(origin.Value);
            float    theta     = MyUtils.GetRandomFloat(centerArcRadius, centerArcRadius + NEUTRAL_SHIP_DIRECTION_SPREAD);
            float    phi       = MyUtils.GetRandomRadian();
            Vector3D cosVec    = Vector3D.CalculatePerpendicularVector(direction);
            Vector3D sinVec    = Vector3D.Cross(direction, cosVec);

            cosVec   *= (Math.Sin(theta) * Math.Cos(phi));
            sinVec   *= (Math.Sin(theta) * Math.Sin(phi));
            direction = direction * Math.Cos(theta) + cosVec + sinVec;

            Vector3D destination  = Vector3D.Zero;
            RayD     ray          = new RayD(origin.Value, direction);
            double?  intersection = ray.Intersects(spawnBox);
            Vector3D directionMult;

            if (!intersection.HasValue || intersection.Value < NEUTRAL_SHIP_MINIMAL_ROUTE_LENGTH)
            {
                directionMult = direction * NEUTRAL_SHIP_MINIMAL_ROUTE_LENGTH;
            }
            else
            {
                directionMult = direction * intersection.Value;
            }
            destination = origin.Value + directionMult;

            Vector3D upVector     = Vector3D.CalculatePerpendicularVector(direction);
            Vector3D rightVector  = Vector3D.Cross(direction, upVector);
            MatrixD  originMatrix = MatrixD.CreateWorld(origin.Value, direction, upVector);

            ProfilerShort.End();

            ProfilerShort.Begin("Check free space");

            // CH:TODO: Convex cast to detect collision
            // Check ships' path to avoid possible collisions. (TODO: But only if it is said in the definitions)
            m_raycastHits.Clear();
            foreach (var shipPrefab in spawnGroup.Prefabs)
            {
                var prefabDef = MyDefinitionManager.Static.GetPrefabDefinition(shipPrefab.SubtypeId);
                Debug.Assert(prefabDef != null);

                Vector3D shipPosition    = Vector3.Transform(shipPrefab.Position, originMatrix);
                Vector3D shipDestination = shipPosition + directionMult;
                float    radius          = prefabDef == null ? 10.0f : prefabDef.BoundingSphere.Radius;

                MyPhysics.CastRay(shipPosition, shipDestination, m_raycastHits, MyPhysics.ObjectDetectionCollisionLayer);
                if (m_raycastHits.Count() > 0)
                {
                    MySandboxGame.Log.WriteLine("Could not spawn neutral ships due to collision");
                    MyGlobalEvents.RescheduleEvent(senderEvent as MyGlobalEventBase, NEUTRAL_SHIP_RESCHEDULE_TIME);
                    ProfilerShort.End();
                    return;
                }

                for (int i = 0; i < 4; ++i)
                {
                    Vector3D shiftVector = upVector * m_upVecMultipliers[i] * radius + rightVector * m_rightVecMultipliers[i] * radius;
                    MyPhysics.CastRay(shipPosition + shiftVector, shipDestination + shiftVector, m_raycastHits, MyPhysics.ObjectDetectionCollisionLayer);

                    if (m_raycastHits.Count() > 0)
                    {
                        MySandboxGame.Log.WriteLine("Could not spawn neutral ships due to collision");
                        MyGlobalEvents.RescheduleEvent(senderEvent as MyGlobalEventBase, NEUTRAL_SHIP_RESCHEDULE_TIME);
                        ProfilerShort.End();
                        return;
                    }
                }
            }

            ProfilerShort.End();

            ProfilerShort.Begin("Spawn ships");

            //This is not an NPC so that it doesn't show up in assign ownership drop down menu
            MyIdentity spawnGroupIdentity = Sync.Players.CreateNewIdentity("Neutral NPC");
            long       spawnGroupId       = spawnGroupIdentity.IdentityId;

            // The ships were collision-free. Now spawn them
            foreach (var shipPrefab in spawnGroup.Prefabs)
            {
                ProfilerShort.Begin(shipPrefab.BeaconText);

                // Yes, this could have been saved in the previous loop, but compared to (e.g.) raycasts, this does not take too much time to recalculate
                Vector3D shipPosition    = Vector3D.Transform((Vector3D)shipPrefab.Position, originMatrix);
                Vector3D shipDestination = shipPosition + directionMult;
                Vector3D up = Vector3D.CalculatePerpendicularVector(-direction);

                m_tmpGridList.Clear();

                // Deploy ship
                ProfilerShort.Begin("Spawn cargo ship");
                MyPrefabManager.Static.SpawnPrefab(
                    resultList: m_tmpGridList,
                    prefabName: shipPrefab.SubtypeId,
                    position: shipPosition,
                    forward: direction,
                    up: up,
                    initialLinearVelocity: shipPrefab.Speed * direction,
                    beaconName: shipPrefab.BeaconText,
                    spawningOptions: Sandbox.ModAPI.SpawningOptions.RotateFirstCockpitTowardsDirection |
                    Sandbox.ModAPI.SpawningOptions.SpawnRandomCargo |
                    Sandbox.ModAPI.SpawningOptions.DisableDampeners,
                    updateSync: true);
                ProfilerShort.End();

                foreach (var grid in m_tmpGridList)
                {
                    grid.ChangeGridOwnership(spawnGroupId, MyOwnershipShareModeEnum.None);

                    var cockpit = grid.GetFirstBlockOfType <MyCockpit>();
                    if (cockpit != null)
                    {
                        MySimpleAutopilot ai = new MySimpleAutopilot(shipDestination, (Vector3)direction);
                        cockpit.AttachAutopilot(ai);
                        break;
                    }
                }

                m_tmpGridList.Clear();

                ProfilerShort.End();
            }

            ProfilerShort.End();
        }
Ejemplo n.º 19
0
        private bool SpawnDrone(MyRadioAntenna antenna, long ownerId, Vector3D position, MySpawnGroupDefinition spawnGroup, Vector3?spawnUp = null, Vector3?spawnForward = null)
        {
            long     antennaEntityId = antenna.EntityId;
            Vector3D antennaPos      = antenna.PositionComp.GetPosition();

            Vector3D upVector;

            var planet = MyGamePruningStructure.GetClosestPlanet(position);

            if (planet != null)
            {
                if (!MyGravityProviderSystem.IsPositionInNaturalGravity(antennaPos))
                {
                    MySandboxGame.Log.WriteLine("Couldn't spawn drone; antenna is not in natural gravity but spawn location is.");
                    return(false);
                }
                planet.CorrectSpawnLocation(ref position, spawnGroup.SpawnRadius * 2.0);
                upVector = position - planet.PositionComp.GetPosition();
                upVector.Normalize();
            }
            else
            {
                var totalGravityInPoint = MyGravityProviderSystem.CalculateTotalGravityInPoint(position);
                if (totalGravityInPoint != Vector3.Zero)
                {
                    upVector = -totalGravityInPoint;
                    upVector.Normalize();
                }
                else if (spawnUp != null)
                {
                    upVector = spawnUp.Value;
                }
                else
                {
                    upVector = MyUtils.GetRandomVector3Normalized();
                }
            }

            Vector3D direction = MyUtils.GetRandomPerpendicularVector(ref upVector);

            if (spawnForward != null)
            {
                // Align forward to up vector.
                Vector3 forward = spawnForward.Value;
                if (Math.Abs(Vector3.Dot(forward, upVector)) >= 0.98f)
                {
                    forward = Vector3.CalculatePerpendicularVector(upVector);
                }
                else
                {
                    Vector3 right = Vector3.Cross(forward, upVector);
                    right.Normalize();
                    forward = Vector3.Cross(upVector, right);
                    forward.Normalize();
                }

                direction = forward;
            }

            MatrixD originMatrix = MatrixD.CreateWorld(position, direction, upVector);

            foreach (var shipPrefab in spawnGroup.Prefabs)
            {
                Vector3D shipPosition = Vector3D.Transform((Vector3D)shipPrefab.Position, originMatrix);

                m_tmpGridList.Clear();

                MyPrefabManager.Static.SpawnPrefab(
                    resultList: m_tmpGridList,
                    prefabName: shipPrefab.SubtypeId,
                    position: shipPosition,
                    forward: direction,
                    up: upVector,
                    initialLinearVelocity: default(Vector3),
                    beaconName: null,
                    spawningOptions: VRage.Game.ModAPI.SpawningOptions.None,
                    ownerId: ownerId,
                    updateSync: true);

                foreach (var grid in m_tmpGridList)
                {
                    grid.ChangeGridOwnership(ownerId, MyOwnershipShareModeEnum.None);

                    MyRemoteControl firstRemote = null;

                    foreach (var block in grid.CubeBlocks)
                    {
                        if (block.FatBlock == null)
                        {
                            continue;
                        }

                        var pb = block.FatBlock as MyProgrammableBlock;
                        if (pb != null)
                        {
                            pb.SendRecompile();
                        }

                        var remote = block.FatBlock as MyRemoteControl;
                        if (firstRemote == null)
                        {
                            firstRemote = remote;
                        }
                    }

                    // If there's no remote control on the grid, we have to register it as is
                    RegisterDrone(antennaEntityId, (MyEntity)firstRemote ?? (MyEntity)grid);
                }

                m_tmpGridList.Clear();
            }
            return(true);
        }