private Vector3D?FindFreePlace(Vector3D start, float rad, float step)
        {
            var probe = _positionComponent.WorldMatrix.Up;

            var direction = Definition.SpawnOffset.Translation;
            var len       = direction.Length();

            if (len >= 1e-6f)
            {
                probe = Vector3D.TransformNormal(direction / len, _positionComponent.WorldMatrix);
            }

            for (var i = 0; i < 20; i++)
            {
                var test = start + i * step * probe;
                if (MyEntities.FindFreePlace(test, rad, -1, 1, 1f, true).HasValue)
                {
                    // cast ray back inwards (because silly, silly phantoms)
                    IHitInfo hit;
                    if (!MyAPIGateway.Physics.CastRay(test, start, out hit, 9))
                    {
                        return(start);
                    }
                    return(hit.Position + Vector3.Normalize(test - start) * rad);
                }
            }

            return(null);
        }
Пример #2
0
        public override bool HandleInputAfterSimulation()
        {
            if (m_respawnsTable.SelectedRow != null && MySession.Static.GetCameraControllerEnum() != MyCameraControllerEnum.Entity)
            {
                MyMedicalRoomInfo userData = m_respawnsTable.SelectedRow.UserData as MyMedicalRoomInfo;

                if (userData != null)
                {
                    m_respawnButton.Enabled = false;
                    MyMedicalRoom medicalRoom;
                    if (MyEntities.TryGetEntityById <MyMedicalRoom>(userData.MedicalRoomId, out medicalRoom))
                    {
                        m_respawnButton.Enabled = true;
                        Vector3D medRoomPosition         = (Vector3D)medicalRoom.PositionComp.GetPosition();
                        Vector3D preferredCameraPosition = medRoomPosition + medicalRoom.WorldMatrix.Up * 20 + medicalRoom.WorldMatrix.Right * 20 + medicalRoom.WorldMatrix.Forward * 20;
                        Vector3D?cameraPosition          = MyEntities.FindFreePlace(preferredCameraPosition, 1);

                        if (!cameraPosition.HasValue)
                        {
                            cameraPosition = preferredCameraPosition;
                        }

                        MySpectatorCameraController.Static.Position = cameraPosition.Value;
                        MySpectatorCameraController.Static.SetTarget(medRoomPosition, medicalRoom.WorldMatrix.Up);
                    }
                }
            }

            return(true);
        }
Пример #3
0
        private void OnTableItemSelected(MyGuiControlTable sender, MyGuiControlTable.EventArgs eventArgs)
        {
            if (m_respawnsTable.SelectedRow != null)
            {
                m_respawnButton.Enabled = true;

                if (m_respawnsTable.SelectedRow.UserData == null || m_respawnsTable.SelectedRow.UserData as MyMedicalRoom == null)
                {
                    MySession.SetCameraController(MyCameraControllerEnum.Spectator, null, new Vector3D(1000000)); //just somewhere out of the game area to see our beautiful skybox
                    return;
                }

                MyMedicalRoom medicalRoom             = (MyMedicalRoom)m_respawnsTable.SelectedRow.UserData;
                Vector3D      medRoomPosition         = (Vector3D)medicalRoom.PositionComp.GetPosition();
                Vector3D      preferredCameraPosition = medRoomPosition + medicalRoom.WorldMatrix.Up * 20 + medicalRoom.WorldMatrix.Right * 20 + medicalRoom.WorldMatrix.Forward * 20;
                Vector3D?     cameraPosition          = MyEntities.FindFreePlace(preferredCameraPosition, 1);
                if (!cameraPosition.HasValue)
                {
                    cameraPosition = preferredCameraPosition;
                }

                MySession.SetCameraController(MyCameraControllerEnum.Spectator, null, cameraPosition);
                MySpectatorCameraController.Static.Target = (Vector3D)medRoomPosition;
            }
            else
            {
                m_respawnButton.Enabled = false;
            }
        }
        // /admin movefrom x y z x y z radius
        public override bool HandleCommand(ulong userId, string[] words)
        {
            if (words.Count() != 4 && words.Count() != 0)
            {
                return(false);
            }

            if (words.Count() != 4)
            {
                Communication.SendPrivateInformation(userId, GetHelp());
                return(true);
            }

            // Test Input
            float test = 0;

            for (int r = 1; r < 4; r++)
            {
                if (!float.TryParse(words[r], out test))
                {
                    Communication.SendPrivateInformation(userId, string.Format("The value at position {0} - '{1}' is invalid.  Please try the command again.", r + 1, words[r]));
                    return(true);
                }
            }

            string   userName      = words[0];
            Vector3D startPosition = new Vector3D(double.Parse(words[1]), double.Parse(words[2]), double.Parse(words[3]));

            List <IMyPlayer> players = new List <IMyPlayer>();

            MyAPIGateway.Players.GetPlayers(players, x => x.DisplayName.Contains(userName, StringComparison.CurrentCultureIgnoreCase));
            if (players[0] == null)
            {
                Communication.SendPrivateInformation(userId, $"Couldn't find player with name {userName}.");
                return(true);
            }
            MyEntity controlledEntity = ((MyEntity)players[0].Controller.ControlledEntity).GetTopMostParent( );

            float size = 2.5f;

            if (controlledEntity is MyCubeGrid)
            {
                size = (float)((MyCubeGrid)controlledEntity).PositionComp.WorldAABB.Extents.Max(  );
            }
            //make sure we aren't moving the player inside a planet or something
            Vector3D?testPos = null;

            Wrapper.GameAction(() => testPos = MyEntities.FindFreePlace(startPosition, size));

            if (testPos == null)
            {
                Communication.SendPrivateInformation(userId, $"Could not move player: {userName}. Position is not empty, try another.");
                return(true);
            }

            //server controls movement now
            Wrapper.GameAction(() => controlledEntity.PositionComp.SetPosition(testPos.Value));

            return(true);
        }
        public static void GetSpawnPosition(float collisionRadius, out Vector3 direction, out Vector3 position)
        {
            float distance = 0;

            foreach (var entity in MyEntities.GetEntities())
            {
                // Include only voxels
                if (entity is MyVoxelMap)
                {
                    distance = (float)MathHelper.Max(distance, entity.PositionComp.WorldVolume.Center.Length() + entity.PositionComp.WorldVolume.Radius);
                }
            }

            // 500 - 650m from last voxel
            distance += MyUtils.GetRandomFloat(500, 650);

            if (MyEntities.IsWorldLimited())
            {
                distance = Math.Min(distance, MyEntities.WorldSafeHalfExtent());
            }
            else
            {
                distance = Math.Min(distance, 20000); // limited spawn area in infinite worlds
            }
            direction = MyUtils.GetRandomVector3Normalized();
            var searchPosition = MyEntities.FindFreePlace((Vector3D)(direction * distance), collisionRadius);

            if (!searchPosition.HasValue)
            {
                searchPosition = (Vector3D)(direction * distance); // Spawn in existing place (better than crash)
            }
            position = (Vector3)searchPosition.Value;
        }
Пример #6
0
        private void SpawnBot(SpawnInfo spawnInfo, MyPlanet planet, MyPlanetAnimalSpawnInfo animalSpawnInfo)
        {
            PlanetAIInfo planetInfo = null;

            if (!m_planets.TryGetValue(planet.EntityId, out planetInfo))
            {
                Debug.Assert(false, "Could not get planet info!");
                return;
            }

            if (planetInfo.BotNumber >= MAX_BOTS_PER_PLANET)
            {
                return;
            }

            Debug.Assert(animalSpawnInfo != null);
            double   spawnDistMin     = animalSpawnInfo.SpawnDistMin;
            double   spawnDistMax     = animalSpawnInfo.SpawnDistMax;
            Vector3D center           = spawnInfo.Position;
            Vector3D planetGravityVec = MyGravityProviderSystem.CalculateNaturalGravityInPoint(center);

            //GR: if gravity is zero provide a random Vector to normalize
            if (planetGravityVec == Vector3D.Zero)
            {
                planetGravityVec = Vector3D.Up;
            }
            planetGravityVec.Normalize();
            Vector3D planetTangent   = Vector3D.CalculatePerpendicularVector(planetGravityVec);
            Vector3D planetBitangent = Vector3D.Cross(planetGravityVec, planetTangent);

            planetTangent.Normalize();
            planetBitangent.Normalize();
            Vector3D spawnPos = MyUtils.GetRandomDiscPosition(ref center, spawnDistMin, spawnDistMax, ref planetTangent, ref planetBitangent);

            spawnPos = planet.GetClosestSurfacePointGlobal(ref spawnPos);
            Vector3D?spawnPosCorrected = MyEntities.FindFreePlace(spawnPos, 2.0f);

            if (spawnPosCorrected.HasValue)
            {
                spawnPos = spawnPosCorrected.Value;
            }

            planet.CorrectSpawnLocation(ref spawnPos, 2.0f);

            MyAgentDefinition botBehavior = GetAnimalDefinition(animalSpawnInfo) as MyAgentDefinition;

            if (botBehavior != null)
            {
                if (botBehavior.Id.SubtypeName == Wolf_SUBTYPE_ID && MySession.Static.EnableWolfs)
                {
                    MyAIComponent.Static.SpawnNewBot(botBehavior, spawnPos);
                }
                else if (botBehavior.Id.SubtypeName != Wolf_SUBTYPE_ID && MySession.Static.EnableSpiders)
                {
                    MyAIComponent.Static.SpawnNewBot(botBehavior, spawnPos);
                }
            }
        }
Пример #7
0
        private Vector3D?FindPastePosition(MyObjectBuilder_CubeGrid[] grids, Vector3D playerPosition)
        {
            BoundingSphere sphere = FindBoundingSphere(grids);

            /*
             * Now we know the radius that can house all grids which will now be
             * used to determine the perfect place to paste the grids to.
             */
            return(MyEntities.FindFreePlace(playerPosition, sphere.Radius));
        }
Пример #8
0
        /// <summary>
        /// Returns a position that should be safe to spawn at given the radius and position.
        /// </summary>
        /// <param name="collisionRadius">The radius of the object that is trying to spawn.</param>
        /// <param name="position">The position the object would like to spawn at.</param>
        /// <param name="forward">(Out) The forward vector the object should spawn with.</param>
        /// <param name="up">(Out) The up vector the object should spawn with.</param>
        /// <param name="planetSpawnHeightRatio">The ratio within the planet's max radius and atmosphere radius you are positioned in.</param>
        /// <param name="randomRangeMin">The minimum randomized distance that is added.</param>
        /// <param name="randomRangeMax">The minimum randomized distance that is added.</param>
        public static void GetSpawnPosition(float collisionRadius, ref Vector3D position, out Vector3D forward, out Vector3D up, float planetSpawnHeightRatio = 0.3f, float randomRangeMin = 500, float randomRangeMax = 650)
        {
            // Are we spawning near a planet?
            MyPlanet planet = MyGamePruningStructure.GetClosestPlanet(position);

            if (planet != null)
            {
                GetSpawnPositionNearPlanet(planet, collisionRadius, ref position, out forward, out up, planetSpawnHeightRatio, randomRangeMin, randomRangeMax);
                return;
            }

            // Old logic, testing for asteroids and other objects
            double distance = 0;

            foreach (var entity in MyEntities.GetEntities())
            {
                MyVoxelMap voxelMap = entity as MyVoxelMap;

                // Only test against voxels
                if (entity == null)
                {
                    continue;
                }

                distance = MathHelper.Max(distance, entity.PositionComp.WorldVolume.Center.Length() + entity.PositionComp.WorldVolume.Radius);
            }

            // Random range from last voxel
            distance += MyUtils.GetRandomFloat(randomRangeMin, randomRangeMax);

            if (MyEntities.IsWorldLimited())
            {
                distance = Math.Min(distance, MyEntities.WorldSafeHalfExtent());
            }
            else
            {
                distance = Math.Min(distance, 20000); // limited spawn area in infinite worlds
            }
            // Compute random position
            forward = MyUtils.GetRandomVector3Normalized();
            up      = Vector3D.CalculatePerpendicularVector(forward);
            Vector3D randomizedPosition = position + (forward * distance);

            // Test if we can spawn here
            Vector3D?searchPosition = MyEntities.FindFreePlace(randomizedPosition, collisionRadius);

            if (searchPosition.HasValue)
            {
                randomizedPosition = searchPosition.Value;
            }

            position = randomizedPosition;
        }
Пример #9
0
        public void SpawnAt(MatrixD worldMatrix, Vector3 velocity, MyEntity spawnedBy, MyBotDefinition botDefinition, bool findFreePlace = true)
        {
            Debug.Assert(Sync.IsServer, "Spawning can be called only on the server!");
            Debug.Assert(Identity != null, "Spawning with empty identity!");
            if (!Sync.IsServer || Identity == null)
            {
                return;
            }

            var character = MyCharacter.CreateCharacter(worldMatrix, velocity, Identity.DisplayName, Identity.Model,
                                                        Identity.ColorMask, findNearPos: false, useInventory: Id.SerialId == 0, playerSteamId: this.Id.SteamId,
                                                        botDefinition: botDefinition);

            if (findFreePlace)
            {
                float   radius;
                MyModel model = character.Render.GetModel();
                radius = model.BoundingBox.Size.Length() / 2;
                const float SPHERE_REDUCTION_RATE = 0.9f;
                radius *= SPHERE_REDUCTION_RATE;

                // Offset from bottom position to center.
                Vector3 up = worldMatrix.Up;
                up.Normalize();
                const float RISE_STEP = 0.01f; // 1cm
                Vector3     offset    = up * (radius + RISE_STEP);
                MatrixD     matrix    = worldMatrix;
                matrix.Translation = worldMatrix.Translation + offset;

                // Attempt first to rotate around the given spawn location (matrix.Up axis rotation)
                // NOTE: A proper orbital search would be better here
                Vector3D?correctedPos = MyEntities.FindFreePlace(ref matrix, matrix.GetDirectionVector(Base6Directions.Direction.Up), radius, 200, 15, 0.2f);
                if (!correctedPos.HasValue)
                {
                    // Attempt secondly to rotate around matrix.Right axis
                    correctedPos = MyEntities.FindFreePlace(ref matrix, matrix.GetDirectionVector(Base6Directions.Direction.Right), radius, 200, 15, 0.2f);
                    if (!correctedPos.HasValue)
                    {
                        // If everything fails attempt the old FindFreePlace
                        correctedPos = MyEntities.FindFreePlace(worldMatrix.Translation + offset, radius, 200, 15, 0.2f);
                    }
                }

                if (correctedPos.HasValue)
                {
                    worldMatrix.Translation = correctedPos.Value - offset;
                    character.PositionComp.SetWorldMatrix(worldMatrix);
                }
            }

            Sync.Players.SetPlayerCharacter(this, character, spawnedBy);
            Sync.Players.RevivePlayer(this);
        }
        public static void GetSpawnPosition(float collisionRadius, out Vector3 direction, out Vector3D position)
        {
            float distance = 0;

            foreach (var entity in MyEntities.GetEntities())
            {
                // Include only voxels
                if (entity is MyVoxelMap)
                {
                    distance = (float)MathHelper.Max(distance, entity.PositionComp.WorldVolume.Center.Length() + entity.PositionComp.WorldVolume.Radius);
                }
            }

            // 500 - 650m from last voxel
            distance += MyUtils.GetRandomFloat(500, 650);

            if (MyEntities.IsWorldLimited())
            {
                distance = Math.Min(distance, MyEntities.WorldSafeHalfExtent());
            }
            else
            {
                distance = Math.Min(distance, 20000); // limited spawn area in infinite worlds
            }
            direction = MyUtils.GetRandomVector3Normalized();
            var searchPosition = MyEntities.FindFreePlace((Vector3D)(direction * distance), collisionRadius);

            if (!searchPosition.HasValue)
            {
                searchPosition = (Vector3D)(direction * distance); // Spawn in existing place (better than crash)
            }
            Vector3D globalPoint = (Vector3D)searchPosition;

            position = globalPoint;

            if (MyGravityProviderSystem.CalculateNaturalGravityInPoint(globalPoint) != null && MyGravityProviderSystem.CalculateNaturalGravityInPoint(globalPoint).Length() != 0)
            {
                MyPlanet planet     = MyGravityProviderSystem.GetStrongestGravityWell(globalPoint);
                double   multiplier = planet.MaximumRadius / globalPoint.Length();
                globalPoint *= multiplier;
                Vector3D closestPoint = planet.GetClosestSurfacePointGlobal(ref globalPoint) * 1.25;
                searchPosition = MyEntities.FindFreePlace(closestPoint, collisionRadius);
                if (searchPosition.HasValue)
                {
                    position = searchPosition.Value;
                }
            }
            else
            {
                position = searchPosition.Value;
            }
        }
Пример #11
0
        private Vector3D?FindPastePosition(Vector3D Target)
        {
            BoundingSphereD sphere = FindBoundingSphere(_grids);

            sphere.Center = Target;

            /*
             * Now we know the radius that can house all grids which will now be
             * used to determine the perfect place to paste the grids to.
             */

            return(MyEntities.FindFreePlace(sphere.Center, (float)sphere.Radius, 60, 8, 1.5f));
        }
Пример #12
0
        static void GetAvailableMedicalRooms(long playerId, List <MyMedicalRoomInfo> medicalRooms)
        {
            List <MyCubeGrid> cubeGrids = MyEntities.GetEntities().OfType <MyCubeGrid>().ToList();

            foreach (var grid in cubeGrids)
            {
                grid.GridSystems.UpdatePower();

                foreach (var slimBlock in grid.GetBlocks())
                {
                    MyMedicalRoom medicalRoom = slimBlock.FatBlock as MyMedicalRoom;
                    if (medicalRoom != null)
                    {
                        medicalRoom.UpdateIsWorking();

                        if (medicalRoom.IsWorking)
                        {
                            if (medicalRoom.HasPlayerAccess(playerId) || medicalRoom.SetFactionToSpawnee)
                            {
                                MyMedicalRoomInfo info = new MyMedicalRoomInfo();
                                info.MedicalRoomId   = medicalRoom.EntityId;
                                info.MedicalRoomName = medicalRoom.CustomName != null?medicalRoom.CustomName.ToString() : (medicalRoom.Name != null ? medicalRoom.Name : medicalRoom.ToString());

                                info.OxygenLevel = medicalRoom.GetOxygenLevel();
                                info.OwnerId     = medicalRoom.IDModule.Owner;

                                Vector3D medRoomPosition         = medicalRoom.PositionComp.GetPosition();
                                Vector3D preferredCameraPosition = medRoomPosition + medicalRoom.WorldMatrix.Up * 20 + medicalRoom.WorldMatrix.Right * 20 + medicalRoom.WorldMatrix.Forward * 20;
                                Vector3D?cameraPosition          = MyEntities.FindFreePlace(preferredCameraPosition, 1);

                                if (!cameraPosition.HasValue)
                                {
                                    cameraPosition = preferredCameraPosition;
                                }

                                info.PrefferedCameraPosition = cameraPosition.Value;
                                info.MedicalRoomPosition     = medRoomPosition;
                                info.MedicalRoomUp           = medicalRoom.PositionComp.WorldMatrix.Up;
                                if (medicalRoom.CubeGrid.Physics != null)
                                {
                                    info.MedicalRoomVelocity = medicalRoom.CubeGrid.Physics.LinearVelocity;
                                }

                                medicalRooms.Add(info);
                            }
                        }
                    }
                }
            }
        }
Пример #13
0
        private Vector3D?FindPastePosition(MyObjectBuilder_CubeGrid[] grids, Vector3D pos, string playername)
        {
            var     player = utils.GetPlayerByNameOrId(playername);
            Vector3?vector = null;
            float   radius = 0F;

            foreach (var grid in grids)
            {
                var gridSphere = grid.CalculateBoundingSphere();

                /* If this is the first run, we use the center of that grid, and its radius as it is */
                if (vector == null)
                {
                    vector = gridSphere.Center;
                    radius = gridSphere.Radius;
                    continue;
                }

                /*
                 * If its not the first run, we use the vector we already have and
                 * figure out how far it is away from the center of the subgrids sphere.
                 */
                float distance = Vector3.Distance(vector.Value, gridSphere.Center);

                /*
                 * Now we figure out how big our new radius must be to house both grids
                 * so the distance between the center points + the radius of our subgrid.
                 */
                float newRadius = distance + gridSphere.Radius;

                /*
                 * If the new radius is bigger than our old one we use that, otherwise the subgrid
                 * is contained in the other grid and therefore no need to make it bigger.
                 */
                if (newRadius > radius)
                {
                    radius = newRadius;
                }
            }

            /*
             * Now we know the radius that can house all grids which will now be
             * used to determine the perfect place to paste the grids to.
             */

            return(MyEntities.FindFreePlace(player.GetPosition(), radius));
        }
Пример #14
0
        public void Teleport(string entityToMove, string destination)
        {
            IMyEntity destEntity;

            if (string.IsNullOrEmpty(destination))
            {
                destEntity = Context.Player?.Controller.ControlledEntity.Entity;
            }
            else
            {
                Utilities.TryGetEntityByNameOrId(destination, out destEntity);
            }

            if (destEntity == null)
            {
                Context.Respond("Destination entity not found");
                return;
            }

            IMyEntity targetEntity;

            if (string.IsNullOrEmpty(entityToMove))
            {
                targetEntity = Context.Player?.Controller.ControlledEntity.Entity;
            }
            else
            {
                Utilities.TryGetEntityByNameOrId(entityToMove, out targetEntity);
            }

            if (targetEntity == null)
            {
                Context.Respond("Target entity not found.");
                return;
            }

            var targetPos = MyEntities.FindFreePlace(destEntity.GetPosition(), (float)targetEntity.WorldAABB.Extents.Max());

            if (targetPos == null)
            {
                Context.Respond("No free place to teleport.");
                return;
            }

            targetEntity.SetPosition(targetPos.Value);
        }
Пример #15
0
        private static void spawnBarbarian(Vector3D position)
        {
            var newPos = MyEntities.FindFreePlace(position, 1f, 200, 5, 5f);

            if (!newPos.HasValue)
            {
                return;
            }
            var botPosition   = newPos.Value;
            var botDefinition = (MyAgentDefinition)MyDefinitionManager.Get <MyBotDefinition>(barbarianId);
            var createdEntity = MySession.Static.Scene.CreateEntity(botDefinition.BotEntity);

            createdEntity.PositionComp.SetWorldMatrix(MatrixD.CreateWorld(botPosition));
            botDefinition.RaiseBeforeBotSpawned(createdEntity);
            MySession.Static.Scene.ActivateEntity(createdEntity);
            botDefinition.AfterBotSpawned(createdEntity);
        }
Пример #16
0
        public void Import(string gridName, string targetName = null)
        {
            Directory.CreateDirectory("ExportedGrids");
            if (targetName == null)
            {
                if (Context.Player == null)
                {
                    Context.Respond("Target entity must be specified.");
                    return;
                }

                targetName = Context.Player.Controller.ControlledEntity.Entity.DisplayName;
            }

            if (!Utilities.TryGetEntityByNameOrId(targetName, out var ent))
            {
                Context.Respond("Target entity not found.");
                return;
            }

            var path = string.Format(ExportPath, gridName);

            if (!File.Exists(path))
            {
                Context.Respond("File does not exist.");
                return;
            }

            if (MyObjectBuilderSerializer.DeserializeXML(path, out MyObjectBuilder_CubeGrid grid))
            {
                Context.Respond($"Importing grid from {path}");
                MyEntities.RemapObjectBuilder(grid);
                var pos = MyEntities.FindFreePlace(ent.GetPosition(), grid.CalculateBoundingSphere().Radius);
                if (pos == null)
                {
                    Context.Respond("No free place.");
                    return;
                }

                var x = grid.PositionAndOrientation ?? new MyPositionAndOrientation();
                x.Position = pos.Value;
                grid.PositionAndOrientation = x;
                MyEntities.CreateFromObjectBuilderParallel(grid, true);
            }
        }
Пример #17
0
        protected MyBehaviorTreeState Teleport()
        {
            if (Bot.Player.Character.HasAnimation("Deburrow"))
            {
                Bot.Player.Character.PlayCharacterAnimation("Deburrow", MyBlendOption.Immediate, MyFrameOption.JustFirstFrame, 0.0f, 1, sync: true);
                Bot.AgentEntity.DisableAnimationCommands();
            }

            MatrixD teleportPos;
            bool    success = MySpaceBotFactory.GetSpiderSpawnPosition(out teleportPos, Bot.Player.GetPosition());

            if (!success)
            {
                return(MyBehaviorTreeState.FAILURE);
            }

            Vector3D pos    = teleportPos.Translation;
            float    radius = (float)Bot.AgentEntity.PositionComp.WorldVolume.Radius;
            var      planet = MyGravityProviderSystem.GetNearestPlanet(pos);

            if (planet != null)
            {
                planet.CorrectSpawnLocation(ref pos, radius);
                teleportPos.Translation = pos;
            }
            else
            {
                Vector3D?freePlace = MyEntities.FindFreePlace(teleportPos.Translation, radius, stepSize: 0.2f);
                if (freePlace.HasValue)
                {
                    teleportPos.Translation = freePlace.Value;
                }
            }

            Bot.AgentEntity.SetPhysicsEnabled(false);

            Bot.AgentEntity.WorldMatrix = teleportPos;
            Bot.AgentEntity.Physics.CharacterProxy.Up      = teleportPos.Up;
            Bot.AgentEntity.Physics.CharacterProxy.Forward = teleportPos.Forward;

            Bot.AgentEntity.SetPhysicsEnabled(true);

            return(MyBehaviorTreeState.SUCCESS);
        }
        void CircleGps(bool reset, bool forward)
        {
            if (MySession.Static != null && MySession.Static.Gpss != null && MySession.Static.LocalHumanPlayer != null)
            {
                if (forward)
                {
                    m_currentGpsIndex--;
                }
                else
                {
                    m_currentGpsIndex++;
                }

                m_gpsList.Clear();
                MySession.Static.Gpss.GetGpsList(MySession.Static.LocalPlayerId, m_gpsList);

                if (m_gpsList.Count == 0)
                {
                    m_currentGpsIndex = 0;
                    return;
                }

                if (m_currentGpsIndex < 0)
                {
                    m_currentGpsIndex = m_gpsList.Count - 1;
                }

                if (m_gpsList.Count <= m_currentGpsIndex || reset)
                {
                    m_currentGpsIndex = 0;
                }

                Vector3D gpsPosition = m_gpsList[m_currentGpsIndex].Coords;

                MySession.Static.SetCameraController(MyCameraControllerEnum.Spectator);
                Vector3D?cameraPosition = MyEntities.FindFreePlace(gpsPosition + Vector3D.One, 2.0f, 30);

                MySpectatorCameraController.Static.Position = cameraPosition.HasValue ? cameraPosition.Value : (gpsPosition + Vector3D.One);
                MySpectatorCameraController.Static.Target   = gpsPosition;
            }
        }
Пример #19
0
        /// <summary>
        /// Returns a position adjusted for planets that should be safe to spawn at given the radius and position.
        /// </summary>
        /// <param name="collisionRadius">The radius of the object that is trying to spawn.</param>
        /// <param name="position">The position the object would like to spawn at.</param>
        /// <param name="forward">(Out) The forward vector the object should spawn with.</param>
        /// <param name="up">(Out) The up vector the object should spawn with.</param>
        /// <param name="planetAtmosphereRatio">The ratio within the planet's max radius and atmosphere radius you are positioned in.</param>
        /// <param name="randomRangeMin">The minimum randomized distance that is added.</param>
        /// <param name="randomRangeMax">The minimum randomized distance that is added.</param>
        private static void GetSpawnPositionNearPlanet(MyPlanet planet, float collisionRadius, ref Vector3D position, out Vector3D forward, out Vector3D up, float planetAtmosphereRatio = 0.3f, float randomRangeMin = 500, float randomRangeMax = 650)
        {
            // Position us at a desirable height on the planet
            // Roughl halfway the planet's upper atmosphere and outer radius
            float randomHeightAdjustment = MyUtils.GetRandomFloat(randomRangeMin, randomRangeMax);
            float height = planet.MaximumRadius + planetAtmosphereRatio * (planet.AtmosphereRadius - planet.MaximumRadius) + randomHeightAdjustment;

            // Compute random position
            position = planet.PositionComp.WorldVolume.Center + MyUtils.GetRandomVector3Normalized() * height;
            Vector3D?freePlace   = MyEntities.FindFreePlace(position, collisionRadius);
            int      numAttempts = 1;

            // While we have no valid spawn position, try again 3 more times
            while (!freePlace.HasValue && numAttempts <= 3)
            {
                position     = planet.PositionComp.WorldVolume.Center + MyUtils.GetRandomVector3Normalized() * height;
                freePlace    = MyEntities.FindFreePlace(position, collisionRadius);
                numAttempts += 1;
            }

            // If we have a valid position, use it
            if (freePlace.HasValue)
            {
                position = freePlace.Value;
            }

            // Return orientation perpendicular to planet surface
            Vector3 gravityAtPosition = MyGravityProviderSystem.CalculateNaturalGravityInPoint(position);

            if (Vector3.IsZero(gravityAtPosition)) // If we are somehow randomized outside of gravity range, make sure some orientation is used
            {
                gravityAtPosition = Vector3.Up;
            }

            Vector3D normalizedGravityVector = Vector3D.Normalize(gravityAtPosition);

            forward = Vector3.CalculatePerpendicularVector(-normalizedGravityVector);
            up      = -normalizedGravityVector;
        }
Пример #20
0
        public void SpawnAt(MatrixD worldMatrix, Vector3 velocity, bool findFreePlace = true)
        {
            Debug.Assert(Sync.IsServer, "Spawning can be called only on the server!");
            Debug.Assert(Identity != null, "Spawning with empty identity!");
            if (!Sync.IsServer || Identity == null)
            {
                return;
            }

            if (findFreePlace)
            {
                Vector3D?correctedPos = MyEntities.FindFreePlace(worldMatrix.Translation, 0.5f, 200);
                if (correctedPos.HasValue)
                {
                    worldMatrix.Translation = correctedPos.Value;
                }
            }

            var character = MyCharacter.CreateCharacter(worldMatrix, velocity, Identity.DisplayName, Identity.Model, Identity.ColorMask, findNearPos: false, useInventory: Id.SerialId == 0);

            Sync.Players.SetPlayerCharacter(this, character);
            Sync.Players.RevivePlayer(this);
        }
Пример #21
0
        // /admin movefrom x y z x y z radius
        public override bool HandleCommand(ulong userId, string[] words)
        {
            if (words.Count() < 2)
            {
                Communication.SendPrivateInformation(userId, GetHelp());
                return(true);
            }

            string sourceName = words[0];
            float  distance   = 50f;

            // TODO Allow quotes so we can do distance?
            bool parse = false;

            if (words.Count() > 2)
            {
                parse = float.TryParse(words[words.Count() - 1], out distance);
            }

            string targetName;

            if (parse)
            {
                targetName = string.Join(" ", words.Skip(1).Take(words.Count() - 2).ToArray());
            }
            else
            {
                targetName = string.Join(" ", words.Skip(1).ToArray());
            }

            Communication.SendPrivateInformation(userId, $"Moving {sourceName} to within {distance}m of {targetName}.");

            Vector3D position;
            MyEntity entity = (MyEntity)Player.FindControlledEntity(targetName);

            if (entity == null)
            {
                entity = CubeGrids.Find(targetName);
                if (entity == null)
                {
                    Communication.SendPrivateInformation(userId, $"Can not find user or grid with the name: {targetName}");
                    return(true);
                }
                position = entity.PositionComp.GetPosition();
            }
            else
            {
                position = entity.PositionComp.GetPosition();
            }

            MyEntity gridToMove = CubeGrids.Find(sourceName);

            if (gridToMove == null)
            {
                Communication.SendPrivateInformation(userId, $"Unable to find: {sourceName}");
                return(true);
            }
            Vector3D?testPos = null;

            Wrapper.GameAction(() => testPos = MyEntities.FindFreePlace(position, (float)gridToMove.PositionComp.WorldAABB.Extents.Max(  ) + distance));

            if (testPos == null)
            {
                Communication.SendPrivateInformation(userId, $"Could not find valid location to move: {sourceName}. Try increasing distance.");
                return(true);
            }

            Wrapper.GameAction(() => gridToMove.PositionComp.SetPosition(testPos.Value));

            Communication.SendPrivateInformation(userId, $"Moved {sourceName} to within {(int)Math.Round( Vector3D.Distance(testPos.Value, position ) )}m of {targetName}");
            return(true);
        }
Пример #22
0
        protected MyBehaviorTreeState Teleport()
        {
            if (Bot.Player.Character.HasAnimation("Deburrow"))
            {
                Bot.Player.Character.PlayCharacterAnimation("Deburrow", MyBlendOption.Immediate, MyFrameOption.JustFirstFrame, 0.0f, 1, sync: true);
                Bot.AgentEntity.DisableAnimationCommands();
            }

            MatrixD teleportPos;
            bool    success = MySpaceBotFactory.GetSpiderSpawnPosition(out teleportPos, Bot.Player.GetPosition());

            if (!success)
            {
                return(MyBehaviorTreeState.FAILURE);
            }

            Vector3D pos = teleportPos.Translation;

            //GR: Added simple check so burrowing (and Teleport) functions should happen only when on Voxel physics.
            //Not sure though if this check should be somewhere else (e.g. behaviour Tree)
            //Check position of Teleport if is clear
            var resultOnTeleportPos = Sandbox.Engine.Physics.MyPhysics.CastRay(pos + 3 * Bot.AgentEntity.WorldMatrix.Up, pos - 3 * Bot.AgentEntity.WorldMatrix.Up, Sandbox.Engine.Physics.MyPhysics.CollisionLayers.NoVoxelCollisionLayer);

            if (resultOnTeleportPos != null)
            {
                return(MyBehaviorTreeState.NOT_TICKED);
            }

            //GR: Also check current position of spider if on CubeGrid do not teleport
            var resultOnSpiderPos = Sandbox.Engine.Physics.MyPhysics.CastRay(Bot.AgentEntity.WorldMatrix.Translation - 3 * Bot.AgentEntity.WorldMatrix.Up, Bot.AgentEntity.WorldMatrix.Translation + 3 * Bot.AgentEntity.WorldMatrix.Up, Sandbox.Engine.Physics.MyPhysics.CollisionLayers.NoVoxelCollisionLayer);

            if (resultOnSpiderPos != null && (resultOnSpiderPos as VRage.Game.ModAPI.IHitInfo).HitEntity != Bot.AgentEntity)
            {
                resultOnSpiderPos = Sandbox.Engine.Physics.MyPhysics.CastRay(Bot.AgentEntity.WorldMatrix.Translation - 3 * Bot.AgentEntity.WorldMatrix.Up, Bot.AgentEntity.WorldMatrix.Translation + 3 * Bot.AgentEntity.WorldMatrix.Up, Sandbox.Engine.Physics.MyPhysics.CollisionLayers.NoVoxelCollisionLayer);
                return(MyBehaviorTreeState.NOT_TICKED);
            }

            float radius = (float)Bot.AgentEntity.PositionComp.WorldVolume.Radius;
            var   planet = MyGamePruningStructure.GetClosestPlanet(pos);

            if (planet != null)
            {
                planet.CorrectSpawnLocation(ref pos, radius);
                teleportPos.Translation = pos;
            }
            else
            {
                Vector3D?freePlace = MyEntities.FindFreePlace(teleportPos.Translation, radius, stepSize: 0.2f);
                if (freePlace.HasValue)
                {
                    teleportPos.Translation = freePlace.Value;
                }
            }

            Bot.AgentEntity.SetPhysicsEnabled(false);

            Bot.AgentEntity.WorldMatrix = teleportPos;
            Bot.AgentEntity.Physics.CharacterProxy.Up      = teleportPos.Up;
            Bot.AgentEntity.Physics.CharacterProxy.Forward = teleportPos.Forward;

            Bot.AgentEntity.SetPhysicsEnabled(true);

            return(MyBehaviorTreeState.SUCCESS);
        }
        public bool HandleRespawnRequest(bool joinGame, bool newIdentity, long medicalRoomId, string respawnShipId, MyPlayer.PlayerId playerId, Vector3D?spawnPosition)
        {
            MyPlayer player = Sync.Players.TryGetPlayerById(playerId);

            bool spawnAsNewPlayer = newIdentity || player == null;

            Debug.Assert(player == null || player.Identity != null, "Respawning player has no identity!");

            if (!MySessionComponentMissionTriggers.CanRespawn(playerId))
            {
                return(false);
            }

            Vector3D currentPosition = Vector3D.Zero;

            if (player != null && player.Character != null)
            {
                currentPosition = player.Character.PositionComp.GetPosition();
            }

            if (TryFindCryoChamberCharacter(player))
            {
                //Player found in chamber;
                return(true);
            }

            if (!spawnAsNewPlayer)
            {
                // Find medical room to spawn at
                MyMedicalRoom medicalRoom = null;
                if (medicalRoomId == 0 || !MyFakes.SHOW_FACTIONS_GUI)
                {
                    List <MyMedicalRoom> medRooms = new List <MyMedicalRoom>();
                    medicalRoom = GetNearestMedRoom(currentPosition, out medRooms, MySession.Static.CreativeMode ? (long?)null : player.Identity.IdentityId);
                    if (joinGame && medRooms.Count > 0)
                    {
                        medicalRoom = medRooms[MyRandom.Instance.Next(0, medRooms.Count)];
                    }
                }
                else
                {
                    medicalRoom = FindRespawnMedicalRoom(medicalRoomId, player);
                    if (medicalRoom == null)
                    {
                        return(false);
                    }
                }

                // If spawning in medical room fails, we will spawn as a new player
                if (medicalRoom != null)
                {
                    SpawnInMedicalRoom(player, medicalRoom, joinGame);
                }
                else
                {
                    spawnAsNewPlayer = true;
                }
            }

            if (spawnAsNewPlayer)
            {
                bool resetIdentity = MySession.Static.Settings.PermanentDeath.Value;
                if (player == null)
                {
                    var identity = Sync.Players.CreateNewIdentity(player.DisplayName);
                    player        = Sync.Players.CreateNewPlayer(identity, playerId, player.DisplayName);
                    resetIdentity = false;
                }

                if (MySession.Static.CreativeMode)
                {
                    Vector3D?correctedPos = MyEntities.FindFreePlace(currentPosition, 1, 200);
                    if (correctedPos.HasValue)
                    {
                        currentPosition = correctedPos.Value;
                    }
                    player.SpawnAt(Matrix.CreateTranslation(currentPosition), Vector3.Zero);
                }
                else
                {
                    SpawnAsNewPlayer(player, currentPosition, respawnShipId, resetIdentity);
                }
            }

            return(true);
        }
Пример #24
0
 VRageMath.Vector3D?IMyEntities.FindFreePlace(VRageMath.Vector3D basePos, float radius, int maxTestCount, int testsPerDistance, float stepSize)
 {
     return(MyEntities.FindFreePlace(basePos, radius, maxTestCount, testsPerDistance, stepSize));
 }
Пример #25
0
        private void UpdateDroneSpawning()
        {
            int currentTime = MySandboxGame.TotalGamePlayTimeInMilliseconds;

            m_iteratingAntennas = true;
            foreach (var antennaEntry in m_pirateAntennas)
            {
                PirateAntennaInfo antennaInfo = antennaEntry.Value;
                if (!antennaInfo.IsActive)
                {
                    continue;
                }
                if (currentTime - antennaInfo.LastGenerationGameTime <= antennaInfo.AntennaDefinition.SpawnTimeMs)
                {
                    continue;
                }

                MyRadioAntenna antenna = null;
                MyEntities.TryGetEntityById(antennaEntry.Key, out antenna);
                Debug.Assert(antenna != null, "Could not find antenna for spawning enemy drones!");
                if (antennaInfo.AntennaDefinition.SpawnGroupSampler == null)
                {
                    return;
                }

                var spawnGroup = antennaInfo.AntennaDefinition.SpawnGroupSampler.Sample();
                Debug.Assert(spawnGroup != null, "Could not find spawnGroup for spawning enemy drones!");
                if
                (
                    !MySession.Static.Settings.EnableDrones ||
                    antennaInfo.SpawnedDrones >= antennaInfo.AntennaDefinition.MaxDrones ||
                    antenna == null ||
                    spawnGroup == null ||
                    (m_droneInfos.Reader.Count() >= MySession.Static.Settings.MaxDrones)
                )
                {
                    antennaInfo.LastGenerationGameTime = currentTime;
                    continue;
                }

                spawnGroup.ReloadPrefabs();

                BoundingSphereD antennaSphere = new BoundingSphereD(antenna.WorldMatrix.Translation, antenna.GetRadius());

                var  players         = MySession.Static.Players.GetOnlinePlayers();
                bool successfulSpawn = false;
                foreach (var player in players)
                {
                    if (antennaSphere.Contains(player.GetPosition()) == ContainmentType.Contains)
                    {
                        Vector3D?spawnPosition = null;
                        for (int i = 0; i < 10; ++i)
                        {
                            Vector3D position = antenna.WorldMatrix.Translation + MyUtils.GetRandomVector3Normalized() * antennaInfo.AntennaDefinition.SpawnDistance;
                            spawnPosition = MyEntities.FindFreePlace(position, spawnGroup.SpawnRadius);
                            if (spawnPosition.HasValue)
                            {
                                break;
                            }
                        }
                        successfulSpawn = SpawnDrone(antenna, antenna.OwnerId, spawnPosition.Value, spawnGroup);

                        break;
                    }
                }

                // Don't reschedule if there was no player inside
                if (successfulSpawn)
                {
                    antennaInfo.LastGenerationGameTime = currentTime;
                }
            }
            m_pirateAntennas.ApplyChanges();
            m_iteratingAntennas = false;
        }
Пример #26
0
        public override bool HandleRespawnRequest(bool joinGame, bool newIdentity, long medicalRoomId, string respawnShipId, MyPlayer.PlayerId playerId, Vector3D?spawnPosition, VRage.ObjectBuilders.SerializableDefinitionId?botDefinitionId)
        {
            MyPlayer player = Sync.Players.GetPlayerById(playerId);

            bool spawnAsNewPlayer = newIdentity || player == null;

            Debug.Assert(player == null || player.Identity != null, "Respawning player has no identity!");

            if (!MySessionComponentMissionTriggers.CanRespawn(playerId))
            {
                return(false);
            }

            Vector3D currentPosition = Vector3D.Zero;

            if (player != null && player.Character != null)
            {
                currentPosition = player.Character.PositionComp.GetPosition();
            }

            if (TryFindCryoChamberCharacter(player))
            {
                //Player found in chamber;
                return(true);
            }

            MyBotDefinition botDefinition = null;

            if (botDefinitionId != null)
            {
                MyDefinitionManager.Static.TryGetBotDefinition((MyDefinitionId)botDefinitionId, out botDefinition);
            }

            if (!spawnAsNewPlayer)
            {
                if (respawnShipId != null)
                {
                    SpawnAtShip(player, respawnShipId, botDefinition);
                    return(true);
                }

                if (spawnPosition.HasValue)
                {
                    Vector3D gravity = MyGravityProviderSystem.CalculateTotalGravityInPoint(spawnPosition.Value);
                    if (Vector3D.IsZero(gravity))
                    {
                        gravity = Vector3D.Down;
                    }
                    else
                    {
                        gravity.Normalize();
                    }
                    Vector3D perpendicular;
                    gravity.CalculatePerpendicularVector(out perpendicular);
                    player.SpawnAt(MatrixD.CreateWorld(spawnPosition.Value, perpendicular, -gravity), Vector3.Zero, null, botDefinition, true);

                    return(true);
                }

                // Find respawn block to spawn at
                MyRespawnComponent foundRespawn = null;
                if (medicalRoomId == 0 || !MyFakes.SHOW_FACTIONS_GUI)
                {
                    List <MyRespawnComponent> respawns = null;
                    var nearestRespawn = GetNearestRespawn(currentPosition, out respawns, MySession.Static.CreativeMode ? (long?)null : player.Identity.IdentityId);
                    if (joinGame && respawns.Count > 0)
                    {
                        foundRespawn = respawns[MyRandom.Instance.Next(0, respawns.Count)];
                    }
                }
                else
                {
                    foundRespawn = FindRespawnById(medicalRoomId, player);
                    if (foundRespawn == null)
                    {
                        return(false);
                    }
                }

                // If spawning in respawn block fails, we will spawn as a new player
                if (foundRespawn != null)
                {
                    SpawnInRespawn(player, foundRespawn, botDefinition);
                }
                else
                {
                    spawnAsNewPlayer = true;
                }
            }

            if (spawnAsNewPlayer)
            {
                bool resetIdentity = false;
                if (MySession.Static.Settings.PermanentDeath.Value)
                {
                    var oldIdentity = Sync.Players.TryGetPlayerIdentity(playerId);
                    resetIdentity = oldIdentity.FirstSpawnDone;
                }

                if (player == null)
                {
                    var identity = Sync.Players.CreateNewIdentity(player.DisplayName);
                    player        = Sync.Players.CreateNewPlayer(identity, playerId, player.DisplayName);
                    resetIdentity = false;
                }

                if (MySession.Static.CreativeMode)
                {
                    Vector3D?correctedPos = MyEntities.FindFreePlace(currentPosition, 2, 200);
                    if (correctedPos.HasValue)
                    {
                        currentPosition = correctedPos.Value;
                    }
                    player.SpawnAt(Matrix.CreateTranslation(currentPosition), Vector3.Zero, null, botDefinition);
                }
                else
                {
                    SpawnAsNewPlayer(player, currentPosition, respawnShipId, resetIdentity, botDefinition);
                }
            }

            return(true);
        }
        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();
        }
Пример #28
0
        internal void ChangeSlotInternal(EquiPlayerAttachmentComponent.Slot slot, float randSeed)
        {
            this.GetLogger().Debug($"Changing slot for {Entity} to {slot?.Controllable?.Entity}#{slot?.Definition.Name}");
            var old = _controlledSlot;

            _controlledSlot = slot;

            var oldAnimData = old?.Definition.ByIndex(_saveData.AnimationId);

            EquiPlayerAttachmentComponentDefinition.AnimationDesc?newAnimData = null;
            if (slot != null && _saveData.ControlledSlot == slot.Definition.Name)
            {
                newAnimData = slot.Definition.ByIndex(_saveData.AnimationId);
            }
            if (!newAnimData.HasValue)
            {
                newAnimData = slot?.Definition.SelectAnimation(Entity.DefinitionId ?? default(MyDefinitionId), randSeed, out _saveData.AnimationId);
            }

            // Handles animation controller switching
            var animController = Entity.Components.Get <MyAnimationControllerComponent>();

            if (animController != null)
            {
                if (oldAnimData.HasValue)
                {
                    animController.TriggerAction(oldAnimData.Value.Stop);
                }
                if (newAnimData.HasValue)
                {
                    AddScheduledCallback(CommitAnimationStart);
                }
            }

            // Handle restoring character's position
            if (slot == null && old?.Controllable?.Entity != null && old.Controllable.Entity.InScene)
            {
                var relMatrix = _saveData.RelativeOrientation.GetMatrix();
                if (relMatrix.Scale.AbsMax() < 1)
                {
                    relMatrix = MatrixD.Identity;
                }
                var outPos            = relMatrix * old.AttachMatrix;
                var transformedCenter = Vector3.TransformNormal(Entity.PositionComp.LocalAABB.Center, outPos);
                var orientation       = Quaternion.CreateFromRotationMatrix(Entity.PositionComp.WorldMatrix.GetOrientation());
                var halfExtents       = Entity.PositionComp.LocalAABB.HalfExtents;
                halfExtents.X *= 0.25f;
                halfExtents.Z *= 0.25f;
                var translate = MyEntities.FindFreePlace(outPos.Translation + transformedCenter, orientation,
                                                         halfExtents, 200, 20, 0.1f, false);
                if (translate.HasValue)
                {
                    outPos.Translation = translate.Value - transformedCenter;
                }
                else
                {
                    outPos = old.AttachMatrix;
                }
                var gravity = Vector3.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(outPos.Translation));
                if (MyAPIGateway.Physics.CastRay(outPos.Translation - gravity, outPos.Translation + 10 * gravity, out var hit))
                {
                    outPos.Translation = hit.Position;
                }

                Entity.PositionComp.SetWorldMatrix(outPos, Entity.Parent, true);
            }

            // Handles storing the character's position when attaching
            if (slot != null)
            {
                _saveData.RelativeOrientation = new MyPositionAndOrientation(MatrixD.Normalize(Entity.WorldMatrix * MatrixD.Invert(slot.AttachMatrix)));
            }


            // Handle keeping the physics in check
            if (Entity.Physics != null)
            {
                var wantsPhysicsEnabled = slot == null;
                if (wantsPhysicsEnabled && !Entity.Physics.Enabled)
                {
                    Entity.Physics.Activate();
                }
                else if (!wantsPhysicsEnabled && Entity.Physics.Enabled)
                {
                    Entity.Physics.Deactivate();
                }
                if (slot == null)
                {
                    var oldPhys = old?.Controllable?.Entity.ParentedPhysics();
                    if (oldPhys != null)
                    {
                        Entity.Physics.LinearVelocity = oldPhys.GetVelocityAtPoint(old.Controllable.Entity.WorldMatrix.Translation);
                    }
                }
            }

            _saveData.ControlledEntity = slot?.Controllable.Entity.EntityId ?? 0;
            _saveData.ControlledSlot   = slot?.Definition.Name;
            if (slot == null)
            {
                _tracker.Unlink(Entity.EntityId);
            }
            else
            {
                _tracker.Link(Entity.EntityId, new ControlledId(slot));
            }

            if (old?.Controllable != null)
            {
                RemoveFixedUpdate(FixPosition);
            }

            if (slot?.Controllable != null)
            {
                AddFixedUpdate(FixPosition, PriorityOverride);
            }

            FixPosition();

            if (old != null)
            {
                old.AttachedCharacter = null;
            }
            if (slot != null)
            {
                slot.AttachedCharacter = Entity;
            }
            ControlledChanged?.Invoke(this, old, slot);
            _tracker.RaiseControlledChange(this, old, slot);
        }
Пример #29
0
        public override bool Update(bool hasFocus)
        {
            /*if (m_respawnsTable.RowsCount == 0 && State != MyGuiScreenState.CLOSING && MySession.Static.LocalHumanPlayer != null)
             * {
             *  MyPlayerCollection.RespawnRequest(joinGame: true, newPlayer: true, medicalId: 0, shipPrefabId: null);
             *  CloseScreen();
             * }*/
            UpdateSpawnShipTimes();
            bool retval = base.Update(hasFocus);

            if (m_selectedRespawnShip != null)
            {
                var rc       = MySpaceRespawnComponent.Static;
                int cooldown = rc.GetRespawnCooldownSeconds(MySession.Static.LocalHumanPlayer.Id, m_selectedRespawnShip.Id.SubtypeName);
                if (rc.IsSynced && cooldown == 0)
                {
                    RespawnShipImmediately(m_selectedRespawnShip.Id.SubtypeName);
                }
            }

            if (m_respawnsTable.RowsCount == 0)
            {
                RefreshRespawnPoints();//because medical rooms are not powered when the map starts
            }

            if (m_respawnsTable.SelectedRow != null && MySession.Static.GetCameraControllerEnum() != MyCameraControllerEnum.Entity)
            {
                MyMedicalRoomInfo userData = m_respawnsTable.SelectedRow.UserData as MyMedicalRoomInfo;

                if (userData != null)
                {
                    m_respawnButton.Enabled = false;
                    MyMedicalRoom medicalRoom;
                    if (MyEntities.TryGetEntityById <MyMedicalRoom>(userData.MedicalRoomId, out medicalRoom))
                    {
                        m_respawnButton.Enabled = true;
                        Vector3D medRoomPosition         = (Vector3D)medicalRoom.PositionComp.GetPosition();
                        Vector3D preferredCameraPosition = medRoomPosition + medicalRoom.WorldMatrix.Up * 20 + medicalRoom.WorldMatrix.Right * 20 + medicalRoom.WorldMatrix.Forward * 20;
                        Vector3D?cameraPosition          = MyEntities.FindFreePlace(preferredCameraPosition, 1);

                        if (!cameraPosition.HasValue)
                        {
                            cameraPosition = preferredCameraPosition;
                        }

                        MySession.Static.SetCameraController(MyCameraControllerEnum.Spectator, null, cameraPosition.Value);
                        MySpectatorCameraController.Static.Target = medRoomPosition;
                    }
                }
            }


            if (m_labelNoRespawn.Text == null)
            {
                m_labelNoRespawn.Visible = false;
            }
            else
            {
                m_labelNoRespawn.Visible = true;
            }

            return(retval);
        }
Пример #30
0
        public override void Execute(Data.Data data, Dictionary <string, object> parameters)
        {
            SessionHandler.EnqueueAction(() =>
            {
                var player = Utils.GetPlayer();
                if (player != null)
                {
                    var id = new MyDefinitionId((MyObjectBuilderType)typeof(MyObjectBuilder_RadioAntenna), "SmallBlockRadioAntenna");
                    var up = player.Character.PositionComp.GetOrientation().Up;
                    up.Normalize();
                    var definitionBase = (MyRadioAntennaDefinition)MyDefinitionManager.Static.GetCubeBlockDefinition(id);
                    var pos            = player.GetPosition() + up * 50;
                    var world          = MatrixD.CreateWorld(pos, Vector3.Forward, Vector3.Up);
                    var color          = Color.Red.ColorToHSV();
                    var pirateFaction  = MySession.Static.Factions.TryGetFactionByTag("SPRT");
                    MyCubeBuilder.SpawnDynamicGrid(definitionBase, player.Character, world, color,
                                                   MyStringHash.NullOrEmpty,
                                                   0L, MyCubeBuilder.SpawnFlags.Default | MyCubeBuilder.SpawnFlags.SpawnAsMaster,
                                                   pirateFaction.FounderId, entity =>
                    {
                        var grid           = (MyCubeGrid)entity;
                        var pirateAntennas = MySession.Static.GetComponent <MyPirateAntennas>();
                        if (pirateAntennas != null)
                        {
                            var drones = Utils.IsInSpace(pos) ? Configuration.Plugin.Get(c => c.SpaceDrones): Configuration.Plugin.Get(c => c.PlanetDrones);
                            var drone  = (string.IsNullOrEmpty(Drone) ? drones[_random.Next(drones.Length)]: Drone) ?? "Vulture Drone";

                            MyDefinitionManager.Static.TryGetDefinition(
                                new MyDefinitionId(
                                    (MyObjectBuilderType)typeof(MyObjectBuilder_SpawnGroupDefinition),
                                    drone), out MySpawnGroupDefinition spawnGroup);
                            if (spawnGroup != null)
                            {
                                Vector3D?nullable = new Vector3D?();
                                for (int index = 0; index < 10; ++index)
                                {
                                    world    = entity.WorldMatrix;
                                    nullable = MyEntities.FindFreePlace(
                                        world.Translation + MyUtils.GetRandomVector3Normalized() * 1500,
                                        spawnGroup.SpawnRadius);
                                    if (nullable.HasValue)
                                    {
                                        break;
                                    }
                                }

                                foreach (var antenna in grid.GetFatBlocks <MyRadioAntenna>())
                                {
                                    _spawnDrone.Invoke(pirateAntennas,
                                                       new object[]
                                    {
                                        antenna, pirateFaction.FounderId, nullable.Value, spawnGroup,
                                        new Vector3?(), new Vector3?()
                                    });
                                }

                                var spawns = spawnGroup.Prefabs.Select(prefab => prefab.SubtypeId.ToSplitCase())
                                             .GroupBy(s => s).Select(grouping =>
                                                                     (grouping.Count() > 1 ? grouping.Count() + "x " : "") + grouping.Key)
                                             .Join();
                                var msg = "Spawned " + spawns;
                                Utils.SendChat(msg);
                                ActionNotification.SendActionMessage(msg, Color.Red, "ArcHudGPSNotification1");
                            }
                        }
                        grid.CubeBlocks.ToList().ForEach(block => grid.RemoveBlock(block));
                    });
                }
            });
        }