private static void SpawnEncounter(MyEncounterId encounterPosition, Vector3D placePosition, List <MySpawnGroupDefinition> candidates, int selectedEncounter)
        {
            var spawnGroup = candidates[selectedEncounter];

            long ownerId = 0; // 0 means that the owner won't be changed

            if (spawnGroup.IsPirate)
            {
                ownerId = MyPirateAntennas.GetPiratesId();
            }

            foreach (var selectedPrefab in spawnGroup.Prefabs)
            {
                List <MyCubeGrid> createdGrids = new List <MyCubeGrid>();
                Vector3D          direction    = Vector3D.Forward;
                Vector3D          upVector     = Vector3D.Up;

                var spawningOptions = spawnGroup.ReactorsOn ? VRage.Game.ModAPI.SpawningOptions.None : VRage.Game.ModAPI.SpawningOptions.TurnOffReactors;
                if (selectedPrefab.Speed > 0.0f)
                {
                    spawningOptions = VRage.Game.ModAPI.SpawningOptions.RotateFirstCockpitTowardsDirection |
                                      VRage.Game.ModAPI.SpawningOptions.SpawnRandomCargo |
                                      VRage.Game.ModAPI.SpawningOptions.DisableDampeners;

                    float centerArcRadius = (float)Math.Atan(MyNeutralShipSpawner.NEUTRAL_SHIP_FORBIDDEN_RADIUS / placePosition.Length());
                    direction = -Vector3D.Normalize(placePosition);
                    float    theta  = m_random.NextFloat(centerArcRadius, centerArcRadius + MyNeutralShipSpawner.NEUTRAL_SHIP_DIRECTION_SPREAD);
                    float    phi    = m_random.NextFloat(0, 2 * MathHelper.Pi);
                    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;

                    upVector = Vector3D.CalculatePerpendicularVector(direction);
                }
                spawningOptions |= VRage.Game.ModAPI.SpawningOptions.DisableSave;

                if (selectedPrefab.PlaceToGridOrigin)
                {
                    spawningOptions |= SpawningOptions.UseGridOrigin;
                }

                Stack <Action> callback = new Stack <Action>();
                callback.Push(delegate() { ProcessCreatedGrids(ref encounterPosition, selectedPrefab.Speed, createdGrids); });

                MyPrefabManager.Static.SpawnPrefab(
                    resultList: createdGrids,
                    prefabName: selectedPrefab.SubtypeId,
                    position: placePosition + selectedPrefab.Position,
                    forward: direction,
                    up: upVector,
                    beaconName: selectedPrefab.BeaconText,
                    initialLinearVelocity: direction * selectedPrefab.Speed,
                    spawningOptions: spawningOptions | SpawningOptions.UseGridOrigin,
                    ownerId: ownerId,
                    updateSync: true,
                    callbacks: callback);
            }
        }
Exemple #2
0
        private bool OwnedBy(MyCubeGrid grid, string str)
        {
            long identityId;

            if (string.Compare(str, "nobody", StringComparison.InvariantCultureIgnoreCase) == 0)
            {
                return(grid.BigOwners.Count == 0);
            }

            if (string.Compare(str, "pirates", StringComparison.InvariantCultureIgnoreCase) == 0)
            {
                identityId = MyPirateAntennas.GetPiratesId();
            }
            else
            {
                var player = Utilities.GetPlayerByNameOrId(str);
                if (player == null)
                {
                    return(false);
                }

                identityId = player.IdentityId;
            }

            return(grid.BigOwners.Contains(identityId));
        }
        void UpdatePirateAntenna(bool forceRemove = false)
        {
            bool isActive = IsWorking && Sync.Players.GetNPCIdentities().Contains(OwnerId);
            bool doRemove = !isActive || forceRemove;

            MyPirateAntennas.UpdatePirateAntenna(this.EntityId, doRemove, this.CustomName);
        }
Exemple #4
0
        public bool IsExcluded(ConcealGroup group)
        {
            var pirateId = MyPirateAntennas.GetPiratesId();

            foreach (var grid in group.Grids)
            {
                if (_keepAliveTimers.ContainsKey(grid.EntityId))
                {
                    Log.Trace($"{group.GridNames} is kept alive by PB action");
                    return(true);
                }

                if (!Settings.Data.ConcealPirates && grid.BigOwners.Contains(pirateId))
                {
                    Log.Trace($"{group.GridNames} is kept alive by pirate ownership");
                    return(true);
                }
            }

            var exclude = false;

            Parallel.ForEach(group.Grids, grid =>
            {
                foreach (var block in grid.CubeBlocks.Select(x => x.FatBlock))
                {
                    if (block == null)
                    {
                        continue;
                    }

                    if (block is IMyProductionBlock p && !Settings.Data.ConcealProduction && p.IsProducing)
                    {
                        Log.Trace($"{group.GridNames} exempted production ({p.CustomName} active)");
                        exclude = true;
                        break;
                    }

                    if (Settings.Data.ExcludedSubtypes.Contains(block.BlockDefinition.Id.SubtypeName))
                    {
                        Log.Trace($"{group.GridNames} exempted subtype {block.BlockDefinition.Id.SubtypeName}");
                        exclude = true;
                        break;
                    }
                }
Exemple #5
0
        public void UpdatePirateAntenna(bool remove = false)
        {
            bool isActive = IsWorking && Sync.Players.GetNPCIdentities().Contains(OwnerId);

            MyPirateAntennas.UpdatePirateAntenna(this.EntityId, remove, isActive, this.CustomName);
        }
Exemple #6
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( );
                }
            });
        }
Exemple #7
0
        public void UpdatePirateAntenna(bool remove = false)
        {
            bool activeState = base.IsWorking && Sync.Players.GetNPCIdentities().Contains(base.OwnerId);

            MyPirateAntennas.UpdatePirateAntenna(base.EntityId, remove, activeState, (this.HudText.Length > 0) ? this.HudText : base.CustomName);
        }