예제 #1
0
        public double SafeZoneIntersectionCheck(MySafeZone zone)
        {
            var zoneEntity = zone as IMyEntity;

            if (zone.Shape == MySafeZoneShape.Sphere)
            {
                var newSphere = new BoundingSphereD(zoneEntity.PositionComp.WorldVolume.Center, zone.Radius);
                var result    = Ray.Intersects(newSphere);

                if (result.HasValue == true)
                {
                    return((double)result);
                }
            }
            else
            {
                var result = Ray.Intersects(zoneEntity.PositionComp.WorldAABB);

                if (result.HasValue == true)
                {
                    return((double)result);
                }
            }

            return(-1);
        }
예제 #2
0
        public bool HitFriendlyShield(Vector3D weaponPos, Vector3D targetPos, Vector3D dir)
        {
            var testRay = new RayD(weaponPos, dir);

            Comp.Ai.TestShields.Clear();
            var checkDistanceSqr = Vector3.DistanceSquared(targetPos, weaponPos);

            for (int i = 0; i < Comp.Ai.NearByFriendlyShields.Count; i++)
            {
                var shield = Comp.Ai.NearByFriendlyShields[i];
                var dist   = testRay.Intersects(shield.PositionComp.WorldVolume);
                if (dist != null && dist.Value * dist.Value <= checkDistanceSqr)
                {
                    Comp.Ai.TestShields.Add(shield);
                }
            }

            if (Comp.Ai.TestShields.Count == 0)
            {
                return(false);
            }

            var result = Comp.Ai.Session.SApi.IntersectEntToShieldFast(Comp.Ai.TestShields, testRay, true, false, Comp.Ai.AiOwner, checkDistanceSqr);

            return(result.Item1 && result.Item2 > 0);
        }
예제 #3
0
        private bool RayCheckTargets(Vector3D origin, Vector3D dir, out MyEntity closestEnt, out Vector3D hitPos, out bool foundOther, bool checkOthers = false)
        {
            var ai          = _session.TrackingAi;
            var closestDist = double.MaxValue;

            closestEnt = null;
            foreach (var info in ai.Targets.Keys)
            {
                var hit = info as MyCubeGrid;
                if (hit == null)
                {
                    continue;
                }
                var ray  = new RayD(origin, dir);
                var dist = ray.Intersects(info.PositionComp.WorldVolume);
                if (dist.HasValue)
                {
                    if (dist.Value < closestDist)
                    {
                        closestDist = dist.Value;
                        closestEnt  = hit;
                    }
                }
            }

            foundOther = false;
            if (checkOthers)
            {
                for (int i = 0; i < ai.Obstructions.Count; i++)
                {
                    var otherEnt = ai.Obstructions[i];
                    if (otherEnt is MyCubeGrid)
                    {
                        var ray  = new RayD(origin, dir);
                        var dist = ray.Intersects(otherEnt.PositionComp.WorldVolume);
                        if (dist.HasValue)
                        {
                            if (dist.Value < closestDist)
                            {
                                closestDist = dist.Value;
                                closestEnt  = otherEnt;
                                foundOther  = true;
                            }
                        }
                    }
                }
            }

            if (closestDist < double.MaxValue)
            {
                hitPos = origin + (dir * closestDist);
            }
            else
            {
                hitPos = Vector3D.Zero;
            }

            return(closestEnt != null);
        }
예제 #4
0
        private bool HitDoor(HitEntity hitEnt, MyDoorBase door)
        {
            var ray    = new RayD(ref hitEnt.Intersection.From, ref hitEnt.Intersection.Direction);
            var rayHit = ray.Intersects(door.PositionComp.WorldVolume);

            if (rayHit != null)
            {
                var      hitPos = hitEnt.Intersection.From + (hitEnt.Intersection.Direction * (rayHit.Value + 0.25f));
                IHitInfo hitInfo;
                if (MyAPIGateway.Physics.CastRay(hitPos, hitEnt.Intersection.To, out hitInfo, 15))
                {
                    var rotMatrix = Quaternion.CreateFromRotationMatrix(door.WorldMatrix);
                    var obb       = new MyOrientedBoundingBoxD(door.PositionComp.WorldAABB.Center, door.PositionComp.LocalAABB.HalfExtents, rotMatrix);
                    var sphere    = new BoundingSphereD(hitInfo.Position + (hitEnt.Intersection.Direction * 0.15f), 0.01f);
                    if (obb.Intersects(ref sphere))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
예제 #5
0
        /// <summary>
        /// Approaching, going to intersect turretMissileBubble.
        /// Meteors are also checked, they are after all, essentially missiles.
        /// </summary>
        /// <returns></returns>
        private bool missileIsThreat(IMyEntity missile, out double toP0_lengthSquared, bool allowInside)
        {
            toP0_lengthSquared = -1;
            if (missile.Closed || missile.Physics == null)
            {
                return(false);
            }

            Vector3D P0 = missile.GetPosition();

            if (missile.Physics.LinearVelocity.LengthSquared() < 1)
            {
                return(false);
            }
            Vector3D missileDirection = Vector3D.Normalize(missile.Physics.LinearVelocity);

            if (!allowInside)
            {
                toP0_lengthSquared = (P0 - turretPosition).LengthSquared();
                if (toP0_lengthSquared < turretMissileBubble.Radius * turretMissileBubble.Radius + 25)                 // missile is inside bubble
                {
                    return(false);
                }
            }

            RayD missileRay = new RayD(P0, missileDirection);
            //myLogger.debugLog("missileRay = " + missileRay, "missileIsHostile()");

            double?intersects = missileRay.Intersects(turretMissileBubble);

            if (intersects != null)
            {
                //myLogger.debugLog("got a missile intersection of " + intersects, "getBestMissile()");
                return(true);
            }
            return(false);
        }
예제 #6
0
        public static void FindLookAtEntity(IMyControllableEntity controlledEntity, bool ignoreOccupiedGrid, bool ignoreProjection, out IMyEntity lookEntity, out double lookDistance, out Vector3D hitPoint, bool findShips, bool findCubes, bool findPlayers, bool findAsteroids, bool findPlanets, bool findReplicable)
        {
            const float range = 5000000;
            Matrix      worldMatrix;
            Vector3D    startPosition;
            Vector3D    endPosition;
            IMyCubeGrid occupiedGrid = null;

            if (controlledEntity.Entity.Parent == null)
            {
                worldMatrix   = controlledEntity.GetHeadMatrix(true, true, false); // dead center of player cross hairs, or the direction the player is looking with ALT.
                startPosition = worldMatrix.Translation + worldMatrix.Forward * 0.5f;
                endPosition   = worldMatrix.Translation + worldMatrix.Forward * (range + 0.5f);
            }
            else
            {
                occupiedGrid = controlledEntity.Entity.GetTopMostParent() as IMyCubeGrid;
                worldMatrix  = controlledEntity.Entity.WorldMatrix;
                // TODO: need to adjust for position of cockpit within ship.
                startPosition = worldMatrix.Translation + worldMatrix.Forward * 1.5f;
                endPosition   = worldMatrix.Translation + worldMatrix.Forward * (range + 1.5f);
            }

            var entites = new HashSet <IMyEntity>();

            MyAPIGateway.Entities.GetEntities(entites, e => e != null);

            var list = new Dictionary <IMyEntity, double>();
            var ray  = new RayD(startPosition, worldMatrix.Forward);

            foreach (var entity in entites)
            {
                if (findShips || findCubes)
                {
                    var cubeGrid = entity as IMyCubeGrid;

                    if (cubeGrid != null)
                    {
                        if (ignoreOccupiedGrid && occupiedGrid != null && occupiedGrid.EntityId == cubeGrid.EntityId)
                        {
                            continue;
                        }

                        // Will ignore Projected grids, new grid/cube placement, and grids in middle of copy/paste.
                        if (ignoreProjection && cubeGrid.Physics == null)
                        {
                            continue;
                        }

                        // check if the ray comes anywhere near the Grid before continuing.
                        if (ray.Intersects(entity.WorldAABB).HasValue)
                        {
                            var hit = cubeGrid.RayCastBlocks(startPosition, endPosition);
                            if (hit.HasValue)
                            {
                                var distance = (startPosition - cubeGrid.GridIntegerToWorld(hit.Value)).Length();
                                var block    = cubeGrid.GetCubeBlock(hit.Value);

                                if (block.FatBlock != null && findCubes)
                                {
                                    list.Add(block.FatBlock, distance);
                                }
                                else if (findShips)
                                {
                                    list.Add(entity, distance);
                                }
                            }
                        }
                    }
                }

                if (findPlayers)
                {
                    var controller = entity as IMyControllableEntity;
                    if (controlledEntity.Entity.EntityId != entity.EntityId && controller != null && ray.Intersects(entity.WorldAABB).HasValue)
                    {
                        var distance = (startPosition - entity.GetPosition()).Length();
                        list.Add(entity, distance);
                    }
                }

                if (findReplicable)
                {
                    var replicable = entity as Sandbox.Game.Entities.MyInventoryBagEntity;
                    if (replicable != null && ray.Intersects(entity.WorldAABB).HasValue)
                    {
                        var distance = (startPosition - entity.GetPosition()).Length();
                        list.Add(entity, distance);
                    }
                }

                if (findAsteroids)
                {
                    var voxelMap = entity as IMyVoxelMap;
                    if (voxelMap != null)
                    {
                        var aabb = new BoundingBoxD(voxelMap.PositionLeftBottomCorner, voxelMap.PositionLeftBottomCorner + voxelMap.Storage.Size);
                        var hit  = ray.Intersects(aabb);
                        if (hit.HasValue)
                        {
                            var center   = voxelMap.PositionLeftBottomCorner + (voxelMap.Storage.Size / 2);
                            var distance = (startPosition - center).Length();  // use distance to center of asteroid.
                            list.Add(entity, distance);
                        }
                    }
                }

                if (findPlanets)
                {
                    // Looks to be working against Git and public release.
                    var planet = entity as Sandbox.Game.Entities.MyPlanet;
                    if (planet != null)
                    {
                        var aabb = new BoundingBoxD(planet.PositionLeftBottomCorner, planet.PositionLeftBottomCorner + planet.Size);
                        var hit  = ray.Intersects(aabb);
                        if (hit.HasValue)
                        {
                            var center   = planet.WorldMatrix.Translation;
                            var distance = (startPosition - center).Length(); // use distance to center of planet.
                            list.Add(entity, distance);
                        }
                    }
                }
            }

            if (list.Count == 0)
            {
                lookEntity   = null;
                lookDistance = 0;
                hitPoint     = Vector3D.Zero;
                return;
            }

            // find the closest Entity.
            var item = list.OrderBy(f => f.Value).First();

            lookEntity   = item.Key;
            lookDistance = item.Value;
            hitPoint     = startPosition + (Vector3D.Normalize(ray.Direction) * lookDistance);
        }
        public override bool Invoke(ulong steamId, long playerId, string messageText)
        {
            #region test

            if (messageText.Equals("/test", StringComparison.InvariantCultureIgnoreCase))
            {
                // for testing things.
                //MyAPIGateway.Utilities.ShowMessage("path", MyAPIGateway.Session.CurrentPath);

                //MyAPIGateway.Utilities.ShowMessage("size1", MyAPIGateway.Utilities.ConfigDedicated.SessionSettings.WorldSizeKm.ToString());
                //MyAPIGateway.Utilities.ShowMessage("size2", MyAPIGateway.Session.GetWorld().Checkpoint.Settings.WorldSizeKm.ToString());


                //IMyConfigDedicated config = null;
                //List<string> admins = null;
                try
                {
                    //config = MyAPIGateway.Utilities.ConfigDedicated;
                    //config.Load();
                    //config.
                }
                catch (Exception)
                {
                    MyAPIGateway.Utilities.ShowMessage("Exception", "ConfigDedicated"); //ex.Message);
                }
                //if (config != null)
                {
                    try
                    {
                        StringBuilder str     = new StringBuilder();
                        var           players = new List <IMyPlayer>();
                        MyAPIGateway.Players.GetPlayers(players, p => p != null);
                        str.AppendLine("Player Count {0}", players.Count);

                        var identities = new List <IMyIdentity>();
                        MyAPIGateway.Players.GetAllIdentites(identities);
                        str.AppendLine("Identities Count {0}", identities.Count);

                        //str.AppendLine("Admin Count {0}", config.Administrators.Count);
                        ////str.AppendLine("WorldName {0}", config.WorldName);
                        ////str.AppendLine("WorldSize {0}", config.SessionSettings.WorldSizeKm);
                        //str.AppendLine("Mods Count {0}", config.Mods.Count);
                        ////str.AppendLine("IP {0}", config.IP));

                        //var clients = MyAPIGateway.Session.GetWorld().Checkpoint.Clients;
                        //str.AppendLine("Client Count", clients == null ? "null" : string.Format("{0}", clients.Count));

                        //if (clients != null)
                        //{
                        //    var client = clients.FirstOrDefault(c => c.SteamId == MyAPIGateway.Multiplayer.MyId);
                        //    if (client != null)
                        //    {
                        //        str.AppendLine("IsAdmin {0}", client.IsAdmin);
                        //    }
                        //}

                        int index = 1;
                        foreach (var identity in identities.OrderBy(i => i.DisplayName))
                        {
                            var steamPlayer = players.FirstOrDefault(p => p.IdentityId == identity.IdentityId);
                            if (steamPlayer != null)
                            {
                                str.AppendFormat("#{0} {1} {2} '{3}'\r\n", index++, steamPlayer?.PromoteLevel, steamPlayer?.SteamUserId, identity.DisplayName);
                            }
                        }

                        MyAPIGateway.Utilities.ShowMissionScreen("test", null, null, str.ToString());
                    }
                    catch (Exception ex)
                    {
                        MyAPIGateway.Utilities.ShowMissionScreen("Exception", "reading config", null, ex.ToString());
                    }
                }
                return(true);
            }

            #endregion

            #region test2

            if (messageText.Equals("/test2", StringComparison.InvariantCultureIgnoreCase))
            {
                // for testing things.
                var count = MyAPIGateway.Utilities.ConfigDedicated.Administrators.Count.ToString(CultureInfo.InvariantCulture);
                MyAPIGateway.Utilities.ShowMessage("Admins", string.Format("Count {0}", count));
                MyAPIGateway.Utilities.ShowMessage("Players", string.Format("Count {0}", MyAPIGateway.Players.Count));
                MyAPIGateway.Utilities.ShowMessage("MultiPlayers", string.Format("Count {0}", MyAPIGateway.Multiplayer.Players.Count));
                return(true);
            }

            #endregion

            #region test3

            if (messageText.Equals("/test3", StringComparison.InvariantCultureIgnoreCase))
            {
                // for testing things.

                StringBuilder msg = new StringBuilder();
                msg.AppendFormat("MyId {0}\r\n", MyAPIGateway.Multiplayer.MyId);
                msg.AppendFormat("SteamId {0}\r\n", MyAPIGateway.Session.Player.SteamUserId);
                msg.AppendFormat("PlayerID {0}\r\n", MyAPIGateway.Session.Player.IdentityId);
                msg.AppendFormat("IdentityId {0}\r\n", MyAPIGateway.Session.Player.IdentityId);
                msg.AppendFormat("MyName {0}\r\n", MyAPIGateway.Multiplayer.MyName);
                msg.AppendFormat("IsServer {0}\r\n", MyAPIGateway.Multiplayer.IsServer);
                msg.AppendFormat("ServerId {0}\r\n", MyAPIGateway.Multiplayer.ServerId);
                msg.AppendFormat("IsServerPlayer {0}\r\n", MyAPIGateway.Multiplayer.IsServerPlayer(MyAPIGateway.Session.Player.Client));
                msg.AppendFormat("MultiplayerActive {0}\r\n", MyAPIGateway.Multiplayer.MultiplayerActive);
                msg.AppendFormat("OnlineMode {0}\r\n", MyAPIGateway.Session.OnlineMode);
                msg.AppendFormat("IsDedicated {0}\r\n", MyAPIGateway.Utilities.IsDedicated);
                //msg.AppendFormat("Culture {0}\r\n", MyTexts.Culture.IetfLanguageTag);
                msg.AppendFormat("Culture {0}\r\n", MyAPIGateway.Session.Config.Language);
                msg.AppendFormat("Culture {0}-{1}\r\n", MyTexts.Languages[MyAPIGateway.Session.Config.Language].CultureName, MyTexts.Languages[MyAPIGateway.Session.Config.Language].SubcultureName);



                var languageRu = MyTexts.Languages[MyLanguagesEnum.Russian];

                MyTexts.Clear();
                MyTexts.LoadTexts(Path.Combine(MyAPIGateway.Utilities.GamePaths.ContentPath, "Data", "Localization"), languageRu.CultureName, languageRu.SubcultureName);
                var yesRu       = MyStringId.Get("DisplayName_Item_GoldIngot").GetString();
                var russianGold = MyTexts.GetString(MyStringId.Get("DisplayName_Item_GoldIngot"));



                var languageEn = MyTexts.Languages[MyLanguagesEnum.English];
                MyTexts.Clear();
                MyTexts.LoadTexts(Path.Combine(MyAPIGateway.Utilities.GamePaths.ContentPath, "Data", "Localization"), languageEn.CultureName, languageRu.SubcultureName);
                var yesEn = MyStringId.Get("DisplayName_Item_GoldIngot").GetString();


                msg.AppendFormat("Language Test Ru={0} En={1}\r\n", yesRu, yesEn);

                // CultureInfo has been set to InvariantCulture since 01.100.xxx
                // CurrentThread is overwritten in MyInitializer to assist in reading Exceptions (which is stupid as stack traces are all in code). So don't bother.
                //msg.AppendFormat("Culture '{0}' '{1}' '{2}'\r\n", CultureInfo.CurrentUICulture, CultureInfo.CurrentUICulture.IetfLanguageTag, CultureInfo.CurrentUICulture.Name);
                //msg.AppendFormat("Culture '{0}'\r\n", System.Threading.Thread.CurrentThread.CurrentUICulture.IetfLanguageTag); // not whitelisted anyhow.

                var ed = ((MyObjectBuilder_EnvironmentDefinition)MyDefinitionManager.Static.EnvironmentDefinition.GetObjectBuilder());
                msg.AppendFormat("LargeShipMaxSpeed {0}\r\n", ed.LargeShipMaxSpeed);
                msg.AppendFormat("LargeShipMaxSpeed {0}\r\n", MyDefinitionManager.Static.EnvironmentDefinition.LargeShipMaxSpeed);
                msg.AppendFormat("SmallShipMaxSpeed {0}\r\n", MyDefinitionManager.Static.EnvironmentDefinition.SmallShipMaxSpeed);

                msg.AppendFormat("ViewDistance {0:N}m\r\n", MyAPIGateway.Session.SessionSettings.ViewDistance);
                msg.AppendFormat("LastSaveTime {0:o}\r\n", MyAPIGateway.Session.GetWorld().Checkpoint.LastSaveTime);

                MyAPIGateway.Utilities.ShowMissionScreen("test3", null, null, msg.ToString());
                return(true);
            }

            #endregion

            #region test4

            if (messageText.Equals("/test4", StringComparison.InvariantCultureIgnoreCase))
            {
                var player = MyAPIGateway.Session.Player;
                if (player != null)
                {
                    var pos = player.GetPosition();
                    MyAPIGateway.Utilities.ShowMessage("Player", "pos={0:N},{1:N},{2:N}", pos.X, pos.Y, pos.Z);
                }

                var cockpit       = MyAPIGateway.Session.ControlledObject as IMyCockpit;
                var remoteControl = MyAPIGateway.Session.ControlledObject as IMyRemoteControl;
                var character     = MyAPIGateway.Session.ControlledObject as IMyCharacter;
                //var character2 = MyAPIGateway.Session.ControlledObject as Sandbox.Game.Entities.Character.MyCharacter;
                var camera           = MyAPIGateway.Session.ControlledObject as IMyCamera;
                var cameraBlock      = MyAPIGateway.Session.ControlledObject as IMyCameraBlock;
                var cameraController = MyAPIGateway.Session.ControlledObject as IMyCameraController;
                //var spectator = MyAPIGateway.Session.ControlledObject as VRage.MySpectator;
                var spectator = MyAPIGateway.Session.Camera;

                if (cockpit != null)
                {
                    MyAPIGateway.Utilities.ShowMessage("Control", "in cockpit.");
                }
                if (remoteControl != null)
                {
                    MyAPIGateway.Utilities.ShowMessage("Control", "remoting.");
                }
                if (character != null)
                {
                    MyAPIGateway.Utilities.ShowMessage("Control", "character.");
                }
                //if (character2 != null)
                //{
                //    //var pos = character2.PositionComp.GetPosition(); // Uses MyEntity which is not whitelisted.
                //    MyAPIGateway.Utilities.ShowMessage("Control", "character2.");
                //}
                if (camera != null)
                {
                    MyAPIGateway.Utilities.ShowMessage("Control", "camera.");
                }
                if (cameraBlock != null)
                {
                    MyAPIGateway.Utilities.ShowMessage("Control", "camera block.");
                }
                if (cameraController != null)
                {
                    //var pos = cameraController.GetViewMatrix().Translation;
                    //MyAPIGateway.Utilities.ShowMessage("Control", "camera controller 1. FPV={0} POS={1:N},{2:N},{3:N}", cameraController.IsInFirstPersonView, pos.X, pos.Y, pos.Z);
                }
                if (MyAPIGateway.Session.ControlledObject.Entity is IMyCameraController)
                {
                    MyAPIGateway.Utilities.ShowMessage("Control", "camera controller 2.");
                }

                //MyAPIGateway.Utilities.ShowMessage("Player", "Spectator1. {0}", VRage.Common.MySpectator.Static.IsInFirstPersonView);

                //System.Windows.Forms.Clipboard.SetText("hello");

                if (spectator != null)
                {
                    MyAPIGateway.Utilities.ShowMessage("Player", "Spectator1.");
                    MyAPIGateway.Utilities.ShowMessage("Control", "camera controller 1. POS={0:N},{1:N},{2:N}", spectator.Position.X, spectator.Position.Y, spectator.Position.Z);
                }
                if (MyAPIGateway.Session.ControlledObject.Entity is MySpectator)
                {
                    MyAPIGateway.Utilities.ShowMessage("Player", "Spectator2.");
                }
                //else
                //{
                //    MyAPIGateway.Utilities.ShowMessage("Player", "other.");
                //}

                MyAPIGateway.Utilities.ShowMessage("Controller", "ControlledEntity == ControlledObject : {0}", MyAPIGateway.Session.Player.Controller.ControlledEntity == MyAPIGateway.Session.ControlledObject);
                MyAPIGateway.Utilities.ShowMessage("Controller", "ControlledEntity == ControlledObject : {0}", MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity == MyAPIGateway.Session.ControlledObject.Entity);


                return(true);

                var playerMatrix   = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.WorldMatrix;
                var playerPosition = playerMatrix.Translation + playerMatrix.Forward * 0.5f + playerMatrix.Up * 1.0f;
                MyAPIGateway.Utilities.ShowMessage("Pos", string.Format("x={0:N},y={1:N},z={2:N}  x={3:N},y={4:N},z={5:N}", playerPosition.X, playerPosition.Y, playerPosition.Z, playerMatrix.Forward.X, playerMatrix.Forward.Y, playerMatrix.Forward.Z));
                //MyAPIGateway.Utilities.ShowMessage("Up", string.Format("x={0:N},y={1:N},z={2:N}", playerMatrix.Up.X, playerMatrix.Up.Y, playerMatrix.Up.Z));

                // TODO: need to properly establish control state and how to tell which state we are in.
                // Player - First person.
                // Player - thrid person.
                // Cockpit - First person.  ControlledObject.GetHeadMatrix(true, true, true);
                // Cockpit - thrid person.  ControlledObject.GetHeadMatrix(true, true, true);
                // Spectator freeview.      CameraController.GetViewMatrix()  but corrupted pos and vector.
                // Camera.                  CameraController.GetViewMatrix()

                //MyAPIGateway.Session.Player.PlayerCharacter.GetHeadMatrix(true, true, true);
                //MyAPIGateway.Session.CameraController.GetViewMatrix();
                //MyAPIGateway.Session.ControlledObject.GetHeadMatrix(true, true, true);
                //Sandbox.ModAPI.IMyControllerInfo //?
                //Sandbox.ModAPI.IMyEntityController
                //Sandbox.ModAPI.Interfaces.IMyCameraController
                //Sandbox.ModAPI.Interfaces.IMyControllableEntity



                // The CameraController.GetViewMatrix appears warped at the moment.
                //var position = ((IMyEntity)MyAPIGateway.Session.CameraController).GetPosition();
                //var camMatrix = MyAPIGateway.Session.CameraController.GetViewMatrix();
                //var camPosition = camMatrix.Translation;
                //MyAPIGateway.Utilities.ShowMessage("Cam", string.Format("x={0:N},y={1:N},z={2:N}  x={3:N},y={4:N},z={5:N}", camPosition.X, camPosition.Y, camPosition.Z, camMatrix.Forward.X, camMatrix.Forward.Y, camMatrix.Forward.Z));

                //var worldMatrix = MyAPIGateway.Session.ControlledObject.Entity.WorldMatrix;
                var worldMatrix = MyAPIGateway.Session.ControlledObject.GetHeadMatrix(true, true, true);
                var position    = worldMatrix.Translation;
                MyAPIGateway.Utilities.ShowMessage("Con", string.Format("x={0:N},y={1:N},z={2:N}  x={3:N},y={4:N},z={5:N}", position.X, position.Y, position.Z, worldMatrix.Forward.X, worldMatrix.Forward.Y, worldMatrix.Forward.Z));


                //MyAPIGateway.Session.Player.PlayerCharacter.MoveAndRotate(new Vector3(), new Vector2(0, 0), 90f);
                //MyAPIGateway.Session.Player.PlayerCharacter.MoveAndRotate(new Vector3(), new Vector2(3.14f, 0), 0f);
                //MyAPIGateway.Session.Player.PlayerCharacter.Up();
                // thrust, walk player forward?

                //MyAPIGateway.Session.Player.PlayerCharacter.Entity.worldmatrix

                //var character = (MyObjectBuilder_Character)obj;

                return(true);
            }

            #endregion

            #region test5

            if (messageText.Equals("/test5", StringComparison.InvariantCultureIgnoreCase))
            {
                var worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.GetHeadMatrix(true, true, true); // most accurate for player view.
                var position    = worldMatrix.Translation + worldMatrix.Forward * 0.5f;

                var entites = new HashSet <IMyEntity>();
                MyAPIGateway.Entities.GetEntities(entites, e => e != null);

                var list = new Dictionary <IMyEntity, double>();

                foreach (var entity in entites)
                {
                    var cubeGrid = entity as IMyCubeGrid;

                    // check if the ray comes anywhere near the Grid before continuing.
                    var ray = new RayD(position, worldMatrix.Forward);
                    if (cubeGrid != null && ray.Intersects(entity.WorldAABB).HasValue)
                    {
                        var hit = cubeGrid.RayCastBlocks(position, worldMatrix.Forward * 1000);
                        if (hit.HasValue)
                        {
                            var blocks = new List <IMySlimBlock>();
                            cubeGrid.GetBlocks(blocks, f => f.FatBlock != null);
                            MyAPIGateway.Utilities.ShowMessage("AABB", string.Format("{0}", entity.WorldAABB));


                            //    var block = blocks[0];
                            //    //block.wo
                            //    var hsv = block.FatBlock.GetDiffuseColor();
                            //    MyAPIGateway.Utilities.ShowMessage("Hsv", string.Format("{0},{1},{2}  {3}", hsv.X, hsv.Y, hsv.Z, 1.45f));
                            //    var c = VRageMath.ColorExtensions.HSVtoColor(hsv);
                            //    MyAPIGateway.Utilities.ShowMessage("Rgb", string.Format("{0},{1},{2}", c.R, c.G, c.B));
                        }
                    }
                }
                return(true);
            }

            #endregion

            #region test6

            if (messageText.Equals("/test6", StringComparison.InvariantCultureIgnoreCase))
            {
                var entity = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity;
                //MyAPIGateway.Utilities.ShowMessage("AABB", string.Format("{0}", entity.WorldAABB));
                //MyAPIGateway.Utilities.ShowMessage("Size", string.Format("{0}", entity.WorldAABB.Size()));

                //if (entity is IMyPlayer)
                //    MyAPIGateway.Utilities.ShowMessage("IMyPlayer", "true");
                //if (entity is IMyCubeBlock)
                //    MyAPIGateway.Utilities.ShowMessage("IMyCubeBlock", "true");  // Ship
                //if (entity is IMyCubeGrid)
                //    MyAPIGateway.Utilities.ShowMessage("IMyCubeGrid", "true");
                //if (entity is IMyIdentity)
                //    MyAPIGateway.Utilities.ShowMessage("IMyIdentity", "true");
                //if (entity is IMyNetworkClient)
                //    MyAPIGateway.Utilities.ShowMessage("IMyNetworkClient", "true");
                //if (entity is IMyEntityController)
                //    MyAPIGateway.Utilities.ShowMessage("IMyEntityController", "true");
                //if (entity is IMyControllableEntity)
                //    MyAPIGateway.Utilities.ShowMessage("IMyControllableEntity", "true");   // Ship and player
                //if (entity is IMyCameraController)
                //    MyAPIGateway.Utilities.ShowMessage("IMyCameraController", "true");  // Everything
                //if (entity is IMyMultiplayer)
                //    MyAPIGateway.Utilities.ShowMessage("IMyMultiplayer", "true");


                if (entity is IMyCubeGrid)
                {
                    entity = entity.Parent;
                }

                if (entity.Physics != null)
                {
                    var pos = entity.GetPosition();
                    //var pos = Vector3.Zero;
                    var m = Matrix.CreateWorld(pos, Vector3.Forward, Vector3.Up);
                    entity.SetWorldMatrix(m);

                    //MyAPIGateway.Multiplayer.SendEntitiesCreated();
                    //entity.LocalMatrix

                    //entity.SetPosition(pos);
                    //if (entity.SyncObject.UpdatesOnlyOnServer)
                    //    entity.SyncObject.UpdatePosition();

                    //MyAPIGateway.Utilities.ShowMessage("Physics=null", string.Format("{0}", phys == null));
                    MyAPIGateway.Utilities.ShowMessage("LinearVelocity", string.Format("{0}", entity.Physics.LinearVelocity));
                    //MyAPIGateway.Utilities.ShowMessage("Speed", string.Format("{0}", phys.Speed));
                    //MyAPIGateway.Utilities.ShowMessage("Mass", string.Format("{0}", phys.Mass));

                    //phys.AddForce(Sandbox.Engine.Physics.MyPhysicsForceType.ADD_BODY_FORCE_AND_BODY_TORQUE, Vector3.Forward, Vector3.Zero, Vector3.Zero);
                    //phys.LinearVelocity = Vector3.Forward;
                    //phys
                }


                //var vm = MyAPIGateway.Session.Player.Controller.ControlledEntity.GetHeadMatrix(true, true, true); // most accurate for player view.
                return(true);
            }

            #endregion

            #region test7

            if (messageText.Equals("/test7", StringComparison.InvariantCultureIgnoreCase))
            {
                var character = (MyObjectBuilder_Character)MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.GetObjectBuilder();

                //var obj = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.GetObjectBuilder();
                var obj = MyAPIGateway.Session.Player.Client as IMyEntity;


                MyAPIGateway.Utilities.ShowMessage("isNull", string.Format("{0}", obj == null));
                //MyAPIGateway.Utilities.ShowMessage("Name", string.Format("{0}", obj.GetType().Name));

                return(true);
            }

            #endregion

            #region test8

            if (messageText.Equals("/test8A", StringComparison.InvariantCultureIgnoreCase))
            {
                var gridBuilder = new MyObjectBuilder_CubeGrid()
                {
                    PersistentFlags        = MyPersistentEntityFlags2.CastShadows | MyPersistentEntityFlags2.InScene,
                    GridSizeEnum           = MyCubeSize.Large,
                    IsStatic               = true,
                    LinearVelocity         = new SerializableVector3(0, 0, 0),
                    AngularVelocity        = new SerializableVector3(0, 0, 0),
                    PositionAndOrientation = new MyPositionAndOrientation(Vector3.Zero, Vector3.Forward, Vector3.Up),
                    DisplayName            = "test grid"
                };

                MyObjectBuilder_CubeBlock cube = new MyObjectBuilder_CubeBlock();
                cube.Min              = new SerializableVector3I(0, 0, 0);
                cube.SubtypeName      = "LargeBlockArmorBlock";
                cube.ColorMaskHSV     = new SerializableVector3(0, -1, 0);
                cube.EntityId         = 0;
                cube.Owner            = 0;
                cube.BlockOrientation = new SerializableBlockOrientation(Base6Directions.Direction.Forward, Base6Directions.Direction.Up);
                cube.ShareMode        = MyOwnershipShareModeEnum.All;
                gridBuilder.CubeBlocks.Add(cube);


                // multiple grids...
                //var tempList = new List<MyObjectBuilder_EntityBase>();
                //tempList.Add(gridBuilder);
                //MyAPIGateway.Entities.RemapObjectBuilderCollection(tempList);
                //tempList.ForEach(grid => MyAPIGateway.Entities.CreateFromObjectBuilderAndAdd(grid));
                //MyAPIGateway.Multiplayer.SendEntitiesCreated(tempList);

                // Single grid.
                MyAPIGateway.Entities.RemapObjectBuilder(gridBuilder);
                MyAPIGateway.Entities.CreateFromObjectBuilderAndAdd(gridBuilder);
                MyAPIGateway.Multiplayer.SendEntitiesCreated(new List <MyObjectBuilder_EntityBase> {
                    gridBuilder
                });

                MyAPIGateway.Utilities.ShowMessage("OK", "fine");

                return(true);
            }

            if (messageText.Equals("/test8B", StringComparison.InvariantCultureIgnoreCase))
            {
                var entity = Support.FindLookAtEntity(MyAPIGateway.Session.ControlledObject, true, true, false, false, true, false) as IMyCubeGrid;

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

                var gridBuilder = new MyObjectBuilder_CubeGrid()
                {
                    PersistentFlags        = MyPersistentEntityFlags2.CastShadows | MyPersistentEntityFlags2.InScene,
                    GridSizeEnum           = MyCubeSize.Large,
                    IsStatic               = true,
                    LinearVelocity         = new SerializableVector3(0, 0, 0),
                    AngularVelocity        = new SerializableVector3(0, 0, 0),
                    PositionAndOrientation = new MyPositionAndOrientation(Vector3.Zero, Vector3.Forward, Vector3.Up),
                    DisplayName            = "test grid"
                };

                MyObjectBuilder_CubeBlock cube = new MyObjectBuilder_CubeBlock();
                cube.Min              = new SerializableVector3I(0, 0, 0);
                cube.SubtypeName      = "LargeBlockArmorBlock";
                cube.ColorMaskHSV     = new SerializableVector3(0, -1, 0);
                cube.ShareMode        = MyOwnershipShareModeEnum.None;
                cube.Owner            = 0;
                cube.BlockOrientation = new SerializableBlockOrientation(Base6Directions.Direction.Forward, Base6Directions.Direction.Up);
                cube.ShareMode        = MyOwnershipShareModeEnum.All;
                gridBuilder.CubeBlocks.Add(cube);

                //var tempList = new List<MyObjectBuilder_EntityBase>();
                //tempList.Add(gridBuilder);
                //MyAPIGateway.Entities.RemapObjectBuilderCollection(tempList); //no need for this on new object
                //var newEntity = (IMyCubeGrid)MyAPIGateway.Entities.CreateFromObjectBuilderAndAdd(tempList[0]);
                //MyAPIGateway.Multiplayer.SendEntitiesCreated(tempList);


                MyAPIGateway.Entities.RemapObjectBuilder(gridBuilder);
                var newEntity = (IMyCubeGrid)MyAPIGateway.Entities.CreateFromObjectBuilderAndAdd(gridBuilder);
                MyAPIGateway.Multiplayer.SendEntitiesCreated(new List <MyObjectBuilder_EntityBase> {
                    gridBuilder
                });
                entity.MergeGrid_MergeBlock(newEntity, new Vector3I(0, 1, 0));


                MyAPIGateway.Utilities.ShowMessage("OK", "fine");

                return(true);
            }

            #endregion

            #region test9

            if (messageText.Equals("/test9", StringComparison.InvariantCultureIgnoreCase))
            {
                var allEntites = new HashSet <IMyEntity>();
                MyAPIGateway.Entities.GetEntities(allEntites, e => e != null);

                var sphere            = new BoundingSphereD(Vector3D.Zero, 1000000f);
                var allSphereEntities = MyAPIGateway.Entities.GetEntitiesInSphere(ref sphere);

                MyAPIGateway.Utilities.ShowMessage("All Entities", String.Format("{0} == {1} ??", allEntites.Count, allSphereEntities.Count));

                return(true);
            }

            #endregion

            #region test10

            // attached grid count test.
            if (messageText.Equals("/test10", StringComparison.InvariantCultureIgnoreCase))
            {
                var entity = Support.FindLookAtEntity(MyAPIGateway.Session.ControlledObject, true, false, false, false, false, false) as IMyCubeGrid;

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

                var cubeGrid = (IMyCubeGrid)entity;
                var grids    = cubeGrid.GetAttachedGrids();

                MyAPIGateway.Utilities.ShowMessage("Attached Count", "{0}", grids.Count);
                foreach (var grid in grids)
                {
                    MyAPIGateway.Utilities.ShowMessage("Attached", "Id:{0}", grid.EntityId);
                }


                // Terminal Groups....
                var gridTerminalSystem = MyAPIGateway.TerminalActionsHelper.GetTerminalSystemForGrid(cubeGrid);
                var groups             = new List <IMyBlockGroup>();
                gridTerminalSystem.GetBlockGroups(groups); // may abide by the owner rules?


                //MyAPIGateway.Utilities.ShowMessage("BlockGroup Count", "{0}", groups.Count);
                //foreach (var group in groups)
                //    MyAPIGateway.Utilities.ShowMessage("BlockGroup", "name:{0} blocks:{1} Id:{2}", group.Name, group.Blocks.Count, group.Blocks.Count > 0 ? group.Blocks[0].CubeGrid.EntityId : 0);

                //MyAPIGateway.Utilities.ShowMessage("Grid count", string.Format("{0} {1} {2}", cubeGrid.DisplayName, terminalsys.Blocks.Count, terminalsys.BlockGroups.Count));

                return(true);
            }

            #endregion

            #region test11

            if (messageText.Equals("/test11", StringComparison.InvariantCultureIgnoreCase))
            {
                //var identities = new List<IMyIdentity>();
                //MyAPIGateway.Players.GetAllIdentites(identities);
                //var ident = identities.FirstOrDefault();
                //var bIdent = ((IMyEntity)ident).GetObjectBuilder();
                //MyAPIGateway.Utilities.ShowMessage("IMyIdentity", string.Format("{0}", bIdent.GetType()));


                var players = new List <IMyPlayer>();
                MyAPIGateway.Players.GetPlayers(players, p => p != null);
                var player = players.FirstOrDefault();

                var cpnt = MyAPIGateway.Session.GetCheckpoint("null");
                MyAPIGateway.Utilities.ShowMessage("cpnt", cpnt.Clients == null ? "null" : string.Format("{0}", cpnt.Clients.Count));

                var c = MyAPIGateway.Session.GetWorld().Checkpoint.Clients;
                MyAPIGateway.Utilities.ShowMessage("Count", c == null ? "null" : string.Format("{0}", c.Count));

                var nc = player.Client;
                MyAPIGateway.Utilities.ShowMessage("IMyNetworkClient", string.Format("{0}", nc.GetType()));
                //MyAPIGateway.Utilities.ShowMessage("IMyNetworkClient", string.Format("{0}", nc.GetType().BaseType));

                //var bPlayer = ((IMyEntity)nc).GetObjectBuilder();
                //MyAPIGateway.Utilities.ShowMessage("IMyPlayer", string.Format("{0}", bPlayer.GetType()));

                //var vm = MyAPIGateway.Session.Player.Controller.ControlledEntity.GetHeadMatrix(true, true, true); // most accurate for player view.
                return(true);
            }

            #endregion

            #region test12

            if (messageText.Equals("/test12", StringComparison.InvariantCultureIgnoreCase))
            {
                var entity     = Support.FindLookAtEntity(MyAPIGateway.Session.ControlledObject, true, true, true, true, true, true);
                var resultList = new List <ITerminalAction>();
                if (entity != null)
                {
                    var displayName = entity.DisplayName;
                    MyAPIGateway.Utilities.ShowMessage("ID", displayName);

                    MyAPIGateway.Utilities.ShowMessage("Components", string.Format("{0}", entity.Components == null));
                    MyAPIGateway.Utilities.ShowMessage("Hierarchy", string.Format("{0}", entity.Hierarchy == null));

                    var cockpits = entity.FindWorkingCockpits();
                    var terminal = (IMyTerminalBlock)cockpits[0];
                    //cockpits[0]
                    terminal.GetActions(resultList);
                    MyAPIGateway.Utilities.ShowMessage("count", string.Format("{0}", resultList.Count));
                }

                //Vector3D? FindFreePlace(Vector3D basePos, float radius, int maxTestCount = 20, int testsPerDistance = 5, float stepSize = 1f);
                //MyAPIGateway.Entities.FindFreePlace(

                //resultList.Clear();
                //var myObject = Sandbox.Common.ObjectBuilders.Serializer.MyObjectBuilderSerializer.CreateNewObject(typeof(MyObjectBuilder_Reactor), "SmallBlockLargeGenerator");
                //MyAPIGateway.TerminalActionsHelper.GetActions(typeof(MyObjectBuilder_Reactor), resultList);
                //MyAPIGateway.Utilities.ShowMessage("count", string.Format("{0}", resultList.Count));

                //MyAPIGateway.TerminalActionsHelper.GetActions(typeof(IMyMotorStator), resultList);
                //MyAPIGateway.Utilities.ShowMessage("count", string.Format("{0}", resultList.Count));

                //MyAPIGateway.TerminalActionsHelper.GetActions(typeof(IMyFunctionalBlock), resultList);
                //MyAPIGateway.Utilities.ShowMessage("count", string.Format("{0}", resultList.Count));

                //MyAPIGateway.TerminalActionsHelper.GetActions(typeof(IMyTerminalBlock), resultList);
                //MyAPIGateway.Utilities.ShowMessage("count", string.Format("{0}", resultList.Count));


                foreach (var a in resultList)
                {
                    MyAPIGateway.Utilities.ShowMessage("item", string.Format("{0}={1}", a.Name, a.Id));
                }


                return(true);
            }

            #endregion

            #region test13

            if (messageText.Equals("/test13", StringComparison.InvariantCultureIgnoreCase))
            {
                var entites = new HashSet <IMyEntity>();
                MyAPIGateway.Entities.GetEntities(entites, e => e != null);

                //var physicalItem = MyDefinitionManager.Static.GetCubeBlockDefinition(new MyDefinitionId(typeof(MyObjectBuilder_SpaceBall), "SpaceBallLarge"));
                //physicalItem.Public = true;

                //MyDefinitionManager.Static.EnvironmentDefinition.SmallShipMaxSpeed = 2000;
                //MyDefinitionManager.Static.EnvironmentDefinition.LargeShipMaxSpeed = 2000;
                MyAPIGateway.Session.GetCheckpoint("null").GameMode = MyGameModeEnum.Creative;
                //MyAPIGateway.Session.GetCheckpoint("null").CargoShipsEnabled
                //MyAPIGateway.Session.GetCheckpoint("null").EnableCopyPaste = true;

                //MyAPIGateway.Utilities.ShowMessage("Sun Distance", string.Format("{0}", MyDefinitionManager.Static.EnvironmentDefinition.DistanceToSun));
                //MyDefinitionManager.Static.EnvironmentDefinition.DirectionToSun = new Vector3(0, 1, 0);

                foreach (var entity in entites)
                {
                    var cubeGrid = entity as IMyCubeGrid;
                    if (cubeGrid != null)
                    {
                        var terminalsys = MyAPIGateway.TerminalActionsHelper.GetTerminalSystemForGrid(cubeGrid);
                        //MyAPIGateway.Utilities.ShowMessage("Grid count", string.Format("{0} {1} {2}", cubeGrid.DisplayName, terminalsys.Blocks.Count, terminalsys.BlockGroups.Count));

                        //var blocks = new List<Sandbox.ModAPI.IMySlimBlock>();
                        //cubeGrid.GetBlocks(blocks, f => f.FatBlock != null && f.FatBlock == MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity);
                        //MyAPIGateway.Utilities.ShowMessage("Pilot count", string.Format("{0}", blocks.Count));

                        //cubeGrid.GetBlocks(blocks);
                        //foreach (var block in blocks)
                        //{
                        //    cubeGrid.ColorBlocks(block.Position, block.Position, VRageMath.Color.Gold.ToHsvColor());
                        //}
                    }
                }

                return(true);
            }

            #endregion

            #region test14

            if (messageText.Equals("/test14", StringComparison.InvariantCultureIgnoreCase))
            {
                // Tag every floating object in player GPS.
                //var entites = new HashSet<IMyEntity>();
                //MyAPIGateway.Entities.GetEntities(entites, e => (e is Sandbox.ModAPI.IMyFloatingObject));

                //foreach (var entity in entites)
                //{
                //    var pos = entity.GetPosition();
                //    var gps = MyAPIGateway.Session.GPS.Create("Floating " + entity.DisplayName, "Some drifting junk", pos, true, false);
                //    MyAPIGateway.Session.GPS.AddLocalGps(gps);
                //}


                //// Tag the Head position, and current position of the player.
                //var worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.GetHeadMatrix(true, true, false, false); // dead center of player cross hairs.

                //var gps = MyAPIGateway.Session.GPS.Create("GetHeadMatrix", "", worldMatrix.Translation, true, false);
                ////MyAPIGateway.Session.GPS.AddLocalGps(gps);

                //gps = MyAPIGateway.Session.GPS.Create("GetPosition", "", MyAPIGateway.Session.Player.GetPosition(), true, false);
                ////MyAPIGateway.Session.GPS.AddLocalGps(gps);

                //var pos1 = worldMatrix.Translation;
                //var pos2 = MyAPIGateway.Session.Player.GetPosition();
                //var pos = pos2 - pos1;

                //MyAPIGateway.Utilities.ShowMessage("Distance", "{0}", pos.Length());


                var clients = MyAPIGateway.Session.GetCheckpoint("null").Clients;
                if (clients != null)
                {
                    IMyPlayer player = MyAPIGateway.Session.Player;

                    MyObjectBuilder_Client client = clients.FirstOrDefault(c => c.SteamId == player.SteamUserId && c.IsAdmin);
                    if (client == null)
                    {
                        client = new MyObjectBuilder_Client()
                        {
                            IsAdmin = true,
                            SteamId = player.SteamUserId,
                            Name    = player.DisplayName
                        };
                        clients.Add(client);
                        MyAPIGateway.Utilities.ShowMessage("Check", "added admin");
                    }
                    else
                    {
                        MyAPIGateway.Utilities.ShowMessage("Check", "already admin");
                    }
                }
                return(true);
            }

            #endregion


            return(false);
        }
예제 #8
0
        internal void InitialHitCheck()
        {
            var vhCount  = ValidateHits.Count;
            var minCount = Session.Settings.Enforcement.ServerOptimizations ? 96 : 99999;
            var stride   = vhCount < minCount ? 100000 : 48;

            MyAPIGateway.Parallel.For(0, ValidateHits.Count, x => {
                var p = ValidateHits[x];

                var shieldByPass       = p.Info.ConsumableDef.DamageScales.Shields.Type == ShieldDef.ShieldType.Bypass;
                var shieldFullBypass   = shieldByPass && p.Info.ConsumableDef.Const.ShieldBypassMod >= 1;
                var genericFields      = p.Info.EwarActive && (p.Info.ConsumableDef.Const.AreaEffect == DotField || p.Info.ConsumableDef.Const.AreaEffect == PushField || p.Info.ConsumableDef.Const.AreaEffect == PullField);
                p.FinalizeIntersection = false;
                var lineCheck          = p.Info.ConsumableDef.Const.CollisionIsLine && !p.Info.EwarAreaPulse;
                var ewarProjectile     = (p.Info.EwarActive || p.Info.ConsumableDef.Const.EwarEffect);

                bool projetileInShield = false;
                var tick = p.Info.System.Session.Tick;

                var useEntityCollection = p.CheckType != Projectile.CheckTypes.Ray;
                var entityCollection    = p.UseEntityCache ? p.Info.Ai.NearByEntityCache : p.MyEntityList;
                var collectionCount     = !useEntityCollection ? p.MySegmentList.Count : entityCollection.Count;
                var ray    = new RayD(ref p.Beam.From, ref p.Beam.Direction);
                var myGrid = p.Info.Target.FiringCube.CubeGrid;

                Water water = null;
                if (Session.WaterApiLoaded && p.Info.MyPlanet != null)
                {
                    Session.WaterMap.TryGetValue(p.Info.MyPlanet, out water);
                }

                for (int i = 0; i < collectionCount; i++)
                {
                    var ent = !useEntityCollection ? p.MySegmentList[i].Element : entityCollection[i];

                    var grid      = ent as MyCubeGrid;
                    var entIsSelf = grid != null && (grid == myGrid || myGrid.IsSameConstructAs(grid));

                    if (entIsSelf && p.SmartsOn || ent.MarkedForClose || !ent.InScene || ent == p.Info.MyShield)
                    {
                        continue;
                    }

                    var character = ent as IMyCharacter;
                    if (p.Info.EwarActive && character != null && !genericFields)
                    {
                        continue;
                    }

                    var entSphere = ent.PositionComp.WorldVolume;
                    if (useEntityCollection)
                    {
                        if (p.CheckType == Projectile.CheckTypes.CachedRay)
                        {
                            var dist = ray.Intersects(entSphere);
                            if (!dist.HasValue || dist > p.Beam.Length)
                            {
                                continue;
                            }
                        }
                        else if (p.CheckType == Projectile.CheckTypes.CachedSphere && p.PruneSphere.Contains(entSphere) == ContainmentType.Disjoint)
                        {
                            continue;
                        }
                    }

                    if (grid != null || character != null)
                    {
                        var extBeam   = new LineD(p.Beam.From - p.Beam.Direction * (entSphere.Radius * 2), p.Beam.To);
                        var transform = ent.PositionComp.WorldMatrixRef;
                        var box       = ent.PositionComp.LocalAABB;
                        var obb       = new MyOrientedBoundingBoxD(box, transform);
                        if (lineCheck && obb.Intersects(ref extBeam) == null || !lineCheck && !obb.Intersects(ref p.PruneSphere))
                        {
                            continue;
                        }
                    }
                    var safeZone = ent as MySafeZone;
                    if (safeZone != null && safeZone.Enabled)
                    {
                        var action = (Session.SafeZoneAction)safeZone.AllowedActions;
                        if ((action & Session.SafeZoneAction.Damage) == 0)
                        {
                            bool intersects;
                            if (safeZone.Shape == MySafeZoneShape.Sphere)
                            {
                                var sphere = new BoundingSphereD(safeZone.PositionComp.WorldVolume.Center, safeZone.Radius);
                                var dist   = ray.Intersects(sphere);
                                intersects = dist != null && dist <= p.Beam.Length;
                            }
                            else
                            {
                                intersects = new MyOrientedBoundingBoxD(safeZone.PositionComp.LocalAABB, safeZone.PositionComp.WorldMatrixRef).Intersects(ref p.Beam) != null;
                            }

                            if (intersects)
                            {
                                p.State    = Projectile.ProjectileState.Depleted;
                                p.EarlyEnd = true;

                                if (p.EnableAv)
                                {
                                    p.Info.AvShot.ForceHitParticle = true;
                                }
                                break;
                            }
                        }
                    }

                    HitEntity hitEntity = null;
                    var checkShield     = Session.ShieldApiLoaded && Session.ShieldHash == ent.DefinitionId?.SubtypeId && ent.Render.Visible;
                    MyTuple <IMyTerminalBlock, MyTuple <bool, bool, float, float, float, int>, MyTuple <MatrixD, MatrixD> >?shieldInfo = null;
                    if (checkShield && (!shieldFullBypass && !p.ShieldBypassed || p.Info.EwarActive && (p.Info.ConsumableDef.Const.AreaEffect == DotField || p.Info.ConsumableDef.Const.AreaEffect == EmpField)))
                    {
                        shieldInfo = p.Info.System.Session.SApi.MatchEntToShieldFastExt(ent, true);
                        if (shieldInfo != null && !myGrid.IsSameConstructAs(shieldInfo.Value.Item1.CubeGrid))
                        {
                            if (p.Info.IsShrapnel || Vector3D.Transform(p.Info.Origin, shieldInfo.Value.Item3.Item1).LengthSquared() > 1)
                            {
                                p.EntitiesNear = true;
                                var dist       = MathFuncs.IntersectEllipsoid(shieldInfo.Value.Item3.Item1, shieldInfo.Value.Item3.Item2, new RayD(p.Beam.From, p.Beam.Direction));
                                if (p.Info.Target.IsProjectile && Vector3D.Transform(p.Info.Target.Projectile.Position, shieldInfo.Value.Item3.Item1).LengthSquared() <= 1)
                                {
                                    projetileInShield = true;
                                }

                                if (dist != null && (dist.Value < p.Beam.Length || p.Info.EwarActive))
                                {
                                    if (shieldByPass)
                                    {
                                        p.ShieldBypassed = true;
                                    }
                                    hitEntity           = HitEntityPool.Get();
                                    hitEntity.EventType = Shield;
                                    hitEntity.HitPos    = p.Beam.From + (p.Beam.Direction * dist.Value);
                                    hitEntity.HitDist   = dist;
                                }
                                else
                                {
                                    continue;
                                }
                            }
                        }
                    }

                    var destroyable = ent as IMyDestroyableObject;
                    var voxel       = ent as MyVoxelBase;
                    if (voxel != null && voxel == voxel?.RootVoxel)
                    {
                        if (ent == p.Info.MyPlanet && !(p.LinePlanetCheck || p.DynamicGuidance || p.CachedPlanetHit))
                        {
                            continue;
                        }
                        VoxelIntersectBranch voxelState = VoxelIntersectBranch.None;
                        Vector3D?voxelHit = null;
                        if (tick - p.Info.VoxelCache.HitRefreshed < 60)
                        {
                            var cacheDist = ray.Intersects(p.Info.VoxelCache.HitSphere);
                            if (cacheDist.HasValue && cacheDist.Value <= p.Beam.Length)
                            {
                                voxelHit   = p.Beam.From + (p.Beam.Direction * cacheDist.Value);
                                voxelState = VoxelIntersectBranch.PseudoHit1;
                            }
                            else if (cacheDist.HasValue)
                            {
                                p.Info.VoxelCache.MissSphere.Center = p.Beam.To;
                            }
                        }

                        if (voxelState != VoxelIntersectBranch.PseudoHit1)
                        {
                            if (voxel == p.Info.MyPlanet && p.Info.VoxelCache.MissSphere.Contains(p.Beam.To) == ContainmentType.Disjoint)
                            {
                                if (p.LinePlanetCheck)
                                {
                                    if (water != null && !p.Info.ConsumableDef.IgnoreWater)
                                    {
                                        var waterSphere = new BoundingSphereD(p.Info.MyPlanet.PositionComp.WorldAABB.Center, water.radius);
                                        var estiamtedSurfaceDistance = ray.Intersects(waterSphere);

                                        if (estiamtedSurfaceDistance.HasValue && estiamtedSurfaceDistance.Value <= p.Beam.Length)
                                        {
                                            var estimatedHit = ray.Position + (ray.Direction * estiamtedSurfaceDistance.Value);
                                            voxelHit         = estimatedHit;
                                            voxelState       = VoxelIntersectBranch.PseudoHit2;
                                        }
                                    }

                                    if (voxelState != VoxelIntersectBranch.PseudoHit2)
                                    {
                                        var surfacePos   = p.Info.MyPlanet.GetClosestSurfacePointGlobal(ref p.Position);
                                        var planetCenter = p.Info.MyPlanet.PositionComp.WorldAABB.Center;
                                        double surfaceToCenter;
                                        Vector3D.DistanceSquared(ref surfacePos, ref planetCenter, out surfaceToCenter);
                                        double endPointToCenter;
                                        Vector3D.DistanceSquared(ref p.Position, ref planetCenter, out endPointToCenter);
                                        double startPointToCenter;
                                        Vector3D.DistanceSquared(ref p.Info.Origin, ref planetCenter, out startPointToCenter);

                                        var prevEndPointToCenter = p.PrevEndPointToCenterSqr;
                                        Vector3D.DistanceSquared(ref surfacePos, ref p.Position, out p.PrevEndPointToCenterSqr);
                                        if (surfaceToCenter > endPointToCenter || p.PrevEndPointToCenterSqr <= (p.Beam.Length * p.Beam.Length) || endPointToCenter > startPointToCenter && prevEndPointToCenter > p.DistanceToTravelSqr || surfaceToCenter > Vector3D.DistanceSquared(planetCenter, p.LastPosition))
                                        {
                                            var estiamtedSurfaceDistance = ray.Intersects(p.Info.VoxelCache.PlanetSphere);
                                            var fullCheck = p.Info.VoxelCache.PlanetSphere.Contains(p.Info.Origin) != ContainmentType.Disjoint || !estiamtedSurfaceDistance.HasValue;

                                            if (!fullCheck && estiamtedSurfaceDistance.HasValue && (estiamtedSurfaceDistance.Value <= p.Beam.Length || p.Info.VoxelCache.PlanetSphere.Radius < 1))
                                            {
                                                double distSqr;
                                                var estimatedHit = ray.Position + (ray.Direction * estiamtedSurfaceDistance.Value);
                                                Vector3D.DistanceSquared(ref p.Info.VoxelCache.FirstPlanetHit, ref estimatedHit, out distSqr);

                                                if (distSqr > 625)
                                                {
                                                    fullCheck = true;
                                                }
                                                else
                                                {
                                                    voxelHit   = estimatedHit;
                                                    voxelState = VoxelIntersectBranch.PseudoHit2;
                                                }
                                            }

                                            if (fullCheck)
                                            {
                                                voxelState = VoxelIntersectBranch.DeferFullCheck;
                                            }

                                            if (voxelHit.HasValue && Vector3D.DistanceSquared(voxelHit.Value, p.Info.VoxelCache.PlanetSphere.Center) > p.Info.VoxelCache.PlanetSphere.Radius * p.Info.VoxelCache.PlanetSphere.Radius)
                                            {
                                                p.Info.VoxelCache.GrowPlanetCache(voxelHit.Value);
                                            }
                                        }
                                    }
                                }
                            }
                            else if (voxelHit == null && p.Info.VoxelCache.MissSphere.Contains(p.Beam.To) == ContainmentType.Disjoint)
                            {
                                voxelState = VoxelIntersectBranch.DeferedMissUpdate;
                            }
                        }

                        if (voxelState == VoxelIntersectBranch.PseudoHit1 || voxelState == VoxelIntersectBranch.PseudoHit2)
                        {
                            if (!voxelHit.HasValue)
                            {
                                if (p.Info.VoxelCache.MissSphere.Contains(p.Beam.To) == ContainmentType.Disjoint)
                                {
                                    p.Info.VoxelCache.MissSphere.Center = p.Beam.To;
                                }
                                continue;
                            }

                            hitEntity = HitEntityPool.Get();

                            var hitPos       = voxelHit.Value;
                            hitEntity.HitPos = hitPos;

                            double dist;
                            Vector3D.Distance(ref p.Beam.From, ref hitPos, out dist);
                            hitEntity.HitDist = dist;

                            hitEntity.EventType = Voxel;
                        }
                        else if (voxelState == VoxelIntersectBranch.DeferedMissUpdate || voxelState == VoxelIntersectBranch.DeferFullCheck)
                        {
                            DeferedVoxels.Add(new DeferedVoxels {
                                Projectile = p, Branch = voxelState, Voxel = voxel
                            });
                        }
                    }
                    else if (ent.Physics != null && !ent.Physics.IsPhantom && !ent.IsPreview && grid != null)
                    {
                        if (grid != null)
                        {
                            hitEntity = HitEntityPool.Get();
                            if (entIsSelf)
                            {
                                if (!p.Info.ConsumableDef.Const.IsBeamWeapon && p.Beam.Length <= grid.GridSize * 2)
                                {
                                    MyCube cube;
                                    if (!(grid.TryGetCube(grid.WorldToGridInteger(p.Position), out cube) && cube.CubeBlock != p.Info.Target.FiringCube.SlimBlock || grid.TryGetCube(grid.WorldToGridInteger(p.LastPosition), out cube) && cube.CubeBlock != p.Info.Target.FiringCube.SlimBlock))
                                    {
                                        HitEntityPool.Return(hitEntity);
                                        continue;
                                    }
                                }

                                if (!p.Info.EwarAreaPulse)
                                {
                                    var forwardPos = p.Info.Age != 1 ? p.Beam.From : p.Beam.From + (p.Beam.Direction * Math.Min(grid.GridSizeHalf, p.Info.DistanceTraveled - p.Info.PrevDistanceTraveled));
                                    grid.RayCastCells(forwardPos, p.Beam.To, hitEntity.Vector3ICache, null, true, true);

                                    if (hitEntity.Vector3ICache.Count > 0)
                                    {
                                        IHitInfo hitInfo;
                                        p.Info.System.Session.Physics.CastRay(forwardPos, p.Beam.To, out hitInfo, CollisionLayers.DefaultCollisionLayer);
                                        var hitGrid = hitInfo?.HitEntity?.GetTopMostParent() as MyCubeGrid;
                                        if (hitGrid == null || !myGrid.IsSameConstructAs(hitGrid))
                                        {
                                            HitEntityPool.Return(hitEntity);
                                            continue;
                                        }

                                        hitEntity.HitPos = hitInfo.Position;
                                        hitEntity.Blocks.Add(grid.GetCubeBlock(hitEntity.Vector3ICache[0]));
                                    }
                                }
                            }
                            else
                            {
                                grid.RayCastCells(p.Beam.From, p.Beam.To, hitEntity.Vector3ICache, null, true, true);
                            }

                            if (!ewarProjectile)
                            {
                                hitEntity.EventType = Grid;
                            }
                            else if (!p.Info.EwarAreaPulse)
                            {
                                hitEntity.EventType = Effect;
                            }
                            else
                            {
                                hitEntity.EventType = Field;
                            }

                            p.EntitiesNear = true;
                        }
                    }
                    else if (destroyable != null)
                    {
                        hitEntity           = HitEntityPool.Get();
                        hitEntity.EventType = Destroyable;
                    }

                    if (hitEntity != null)
                    {
                        p.FinalizeIntersection   = true;
                        hitEntity.Info           = p.Info;
                        hitEntity.Entity         = hitEntity.EventType != Shield ? ent : (MyEntity)shieldInfo.Value.Item1;
                        hitEntity.Intersection   = p.Beam;
                        hitEntity.SphereCheck    = !lineCheck;
                        hitEntity.PruneSphere    = p.PruneSphere;
                        hitEntity.SelfHit        = entIsSelf;
                        hitEntity.DamageOverTime = p.Info.ConsumableDef.Const.AreaEffect == DotField;

                        p.Info.HitList.Add(hitEntity);
                    }
                }

                if (p.Info.Target.IsProjectile && !p.Info.ConsumableDef.Const.EwarEffect && !projetileInShield)
                {
                    var detonate     = p.State == Projectile.ProjectileState.Detonate;
                    var hitTolerance = detonate ? p.Info.ConsumableDef.Const.DetonationRadius : p.Info.ConsumableDef.Const.AreaEffectSize > p.Info.ConsumableDef.Const.CollisionSize ? p.Info.ConsumableDef.Const.AreaEffectSize : p.Info.ConsumableDef.Const.CollisionSize;
                    var useLine      = p.Info.ConsumableDef.Const.CollisionIsLine && !detonate && p.Info.ConsumableDef.Const.AreaEffectSize <= 0;

                    var sphere = new BoundingSphereD(p.Info.Target.Projectile.Position, p.Info.Target.Projectile.Info.ConsumableDef.Const.CollisionSize);
                    sphere.Include(new BoundingSphereD(p.Info.Target.Projectile.LastPosition, 1));

                    bool rayCheck = false;
                    if (useLine)
                    {
                        var dist = sphere.Intersects(new RayD(p.LastPosition, p.Info.Direction));
                        if (dist <= hitTolerance || p.Info.ConsumableDef.Const.IsBeamWeapon && dist <= p.Beam.Length)
                        {
                            rayCheck = true;
                        }
                    }

                    var testSphere    = p.PruneSphere;
                    testSphere.Radius = hitTolerance;

                    if (rayCheck || sphere.Intersects(testSphere))
                    {
                        ProjectileHit(p, p.Info.Target.Projectile, lineCheck, ref p.Beam);
                    }
                }

                if (!useEntityCollection)
                {
                    p.MySegmentList.Clear();
                }
                else if (p.CheckType == Projectile.CheckTypes.Sphere)
                {
                    entityCollection.Clear();
                }

                if (p.FinalizeIntersection)
                {
                    FinalHitCheck.Add(p);
                }
            }, stride);
            ValidateHits.ClearImmediate();
        }
        public override bool Invoke(string messageText)
        {
            #region test

            if (messageText.Equals("/test", StringComparison.InvariantCultureIgnoreCase))
            {
                // for testing things.
                //MyAPIGateway.Utilities.ShowMessage("path", MyAPIGateway.Session.CurrentPath);

                //MyAPIGateway.Utilities.ShowMessage("size1", MyAPIGateway.Utilities.ConfigDedicated.SessionSettings.WorldSizeKm.ToString());
                //MyAPIGateway.Utilities.ShowMessage("size2", MyAPIGateway.Session.GetWorld().Checkpoint.Settings.WorldSizeKm.ToString());

                IMyConfigDedicated config = null;
                //List<string> admins = null;
                try
                {
                    config = MyAPIGateway.Utilities.ConfigDedicated;
                    config.Load();
                    //config.
                }
                catch (Exception)
                {
                    MyAPIGateway.Utilities.ShowMessage("Exception", "ConfigDedicated"); //ex.Message);
                }
                if (config != null)
                {
                    try
                    {
                        var players = new List<IMyPlayer>();
                        MyAPIGateway.Players.GetPlayers(players, p => p != null);
                        MyAPIGateway.Utilities.ShowMessage("Player Count", string.Format("{0}", players.Count));

                        var identities = new List<IMyIdentity>();
                        MyAPIGateway.Players.GetAllIdentites(identities);
                        MyAPIGateway.Utilities.ShowMessage("Identities Count", string.Format("{0}", identities.Count));

                        MyAPIGateway.Utilities.ShowMessage("Admin Count", string.Format("{0}", config.Administrators.Count));
                        //MyAPIGateway.Utilities.ShowMessage("WorldName", string.Format("{0}", config.WorldName));
                        //MyAPIGateway.Utilities.ShowMessage("WorldSize", string.Format("{0}", config.SessionSettings.WorldSizeKm));
                        MyAPIGateway.Utilities.ShowMessage("Mods Count", string.Format("{0}", config.Mods.Count));
                        //MyAPIGateway.Utilities.ShowMessage("IP", string.Format("{0}", config.IP));

                        var clients = MyAPIGateway.Session.GetWorld().Checkpoint.Clients;
                        MyAPIGateway.Utilities.ShowMessage("Client Count", clients == null ? "null" : string.Format("{0}", clients.Count));

                        if (clients != null)
                        {
                            var client = clients.FirstOrDefault(c => c.SteamId == MyAPIGateway.Multiplayer.MyId);
                            if (client != null)
                            {
                                MyAPIGateway.Utilities.ShowMessage("IsAdmin", string.Format("{0}", client.IsAdmin));
                            }
                        }
                    }
                    catch (Exception)
                    {
                        MyAPIGateway.Utilities.ShowMessage("Exception", "reading config"); //ex.Message);
                    }
                }
                return true;
            }

            #endregion

            #region test2

            if (messageText.Equals("/test2", StringComparison.InvariantCultureIgnoreCase))
            {
                // for testing things.
                var count = MyAPIGateway.Utilities.ConfigDedicated.Administrators.Count.ToString(CultureInfo.InvariantCulture);
                MyAPIGateway.Utilities.ShowMessage("Admins", string.Format("Count {0}", count));
                MyAPIGateway.Utilities.ShowMessage("Players", string.Format("Count {0}", MyAPIGateway.Players.Count));
                MyAPIGateway.Utilities.ShowMessage("MultiPlayers", string.Format("Count {0}", MyAPIGateway.Multiplayer.Players.Count));
                return true;
            }

            #endregion

            #region test3

            if (messageText.Equals("/test3", StringComparison.InvariantCultureIgnoreCase))
            {
                // for testing things.
                MyAPIGateway.Utilities.ShowMessage("MyId", "{0}", MyAPIGateway.Multiplayer.MyId);
                MyAPIGateway.Utilities.ShowMessage("SteamId", "{0}", MyAPIGateway.Session.Player.SteamUserId);
                MyAPIGateway.Utilities.ShowMessage("MyName", "{0}", MyAPIGateway.Multiplayer.MyName);
                MyAPIGateway.Utilities.ShowMessage("IsServer", "{0}", MyAPIGateway.Multiplayer.IsServer);
                MyAPIGateway.Utilities.ShowMessage("IsServerPlayer", "{0}", MyAPIGateway.Multiplayer.IsServerPlayer(MyAPIGateway.Session.Player.Client));
                MyAPIGateway.Utilities.ShowMessage("MultiplayerActive", "{0}", MyAPIGateway.Multiplayer.MultiplayerActive);
                MyAPIGateway.Utilities.ShowMessage("OnlineMode", "{0}", MyAPIGateway.Session.OnlineMode);
                MyAPIGateway.Utilities.ShowMessage("IsDedicated", "{0}", MyAPIGateway.Utilities.IsDedicated);
                //MyAPIGateway.Utilities.ShowMessage("Culture", "{0}", MyTexts.Culture.IetfLanguageTag);
                MyAPIGateway.Utilities.ShowMessage("Culture", "{0} {1}", CultureInfo.CurrentUICulture, CultureInfo.CurrentUICulture.IetfLanguageTag);

                var ed = ((MyObjectBuilder_EnvironmentDefinition)MyDefinitionManager.Static.EnvironmentDefinition.GetObjectBuilder());
                MyAPIGateway.Utilities.ShowMessage("LargeShipMaxSpeed", "{0}", ed.LargeShipMaxSpeed);
                MyAPIGateway.Utilities.ShowMessage("SunDirection", "{0} {1} {2}", ed.SunDirection.X, ed.SunDirection.Y, ed.SunDirection.Z);
                return true;
            }

            #endregion

            #region test4

            if (messageText.Equals("/test4", StringComparison.InvariantCultureIgnoreCase))
            {
                var player = MyAPIGateway.Session.Player;
                if (player != null)
                {
                    var pos = player.GetPosition();
                    MyAPIGateway.Utilities.ShowMessage("Player", "pos={0:N},{1:N},{2:N}", pos.X, pos.Y, pos.Z);
                }

                var cockpit = MyAPIGateway.Session.ControlledObject as Sandbox.ModAPI.Ingame.IMyCockpit;
                var remoteControl = MyAPIGateway.Session.ControlledObject as Sandbox.ModAPI.Ingame.IMyRemoteControl;
                var character = MyAPIGateway.Session.ControlledObject as Sandbox.ModAPI.IMyCharacter;
                var character2 = MyAPIGateway.Session.ControlledObject as Sandbox.Game.Entities.Character.MyCharacter;
                var camera = MyAPIGateway.Session.ControlledObject as Sandbox.ModAPI.IMyCamera;
                var cameraBlock = MyAPIGateway.Session.ControlledObject as Sandbox.ModAPI.Ingame.IMyCameraBlock;
                var cameraController = MyAPIGateway.Session.ControlledObject as Sandbox.ModAPI.Interfaces.IMyCameraController;
                var spectator = MyAPIGateway.Session.ControlledObject as VRage.MySpectator;

                if (cockpit != null)
                {
                    MyAPIGateway.Utilities.ShowMessage("Control", "in cockpit.");
                }
                if (remoteControl != null)
                {
                    MyAPIGateway.Utilities.ShowMessage("Control", "remoting.");
                }
                if (character != null)
                {
                    MyAPIGateway.Utilities.ShowMessage("Control", "character.");
                }
                if (character2 != null)
                {
                    //var pos = character2.PositionComp.GetPosition(); // Uses MyEntity which is not whitelisted.
                    MyAPIGateway.Utilities.ShowMessage("Control", "character2.");
                }
                if (camera != null)
                {
                    MyAPIGateway.Utilities.ShowMessage("Control", "camera.");
                }
                if (cameraBlock != null)
                {
                    MyAPIGateway.Utilities.ShowMessage("Control", "camera block.");
                }
                if (cameraController != null)
                {
                    var pos = cameraController.GetViewMatrix().Translation;
                    MyAPIGateway.Utilities.ShowMessage("Control", "camera controller 1. FPV={0} POS={1:N},{2:N},{3:N}", cameraController.IsInFirstPersonView, pos.X, pos.Y, pos.Z);
                }
                if (MyAPIGateway.Session.ControlledObject.Entity is Sandbox.ModAPI.Interfaces.IMyCameraController)
                {
                    MyAPIGateway.Utilities.ShowMessage("Control", "camera controller 2.");
                }

                //MyAPIGateway.Utilities.ShowMessage("Player", "Spectator1. {0}", VRage.Common.MySpectator.Static.IsInFirstPersonView);

                //System.Windows.Forms.Clipboard.SetText("hello");

                if (spectator != null)
                {
                    MyAPIGateway.Utilities.ShowMessage("Player", "Spectator1.");
                }
                if (MyAPIGateway.Session.ControlledObject.Entity is MySpectator)
                {
                    MyAPIGateway.Utilities.ShowMessage("Player", "Spectator2.");
                }
                //else
                //{
                //    MyAPIGateway.Utilities.ShowMessage("Player", "other.");
                //}

                return true;

                var playerMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.WorldMatrix;
                var playerPosition = playerMatrix.Translation + playerMatrix.Forward * 0.5f + playerMatrix.Up * 1.0f;
                MyAPIGateway.Utilities.ShowMessage("Pos", string.Format("x={0:N},y={1:N},z={2:N}  x={3:N},y={4:N},z={5:N}", playerPosition.X, playerPosition.Y, playerPosition.Z, playerMatrix.Forward.X, playerMatrix.Forward.Y, playerMatrix.Forward.Z));
                //MyAPIGateway.Utilities.ShowMessage("Up", string.Format("x={0:N},y={1:N},z={2:N}", playerMatrix.Up.X, playerMatrix.Up.Y, playerMatrix.Up.Z));

                // TODO: need to properly establish control state and how to tell which state we are in.
                // Player - First person.
                // Player - thrid person.
                // Cockpit - First person.  ControlledObject.GetHeadMatrix(true, true, true);
                // Cockpit - thrid person.  ControlledObject.GetHeadMatrix(true, true, true);
                // Spectator freeview.      CameraController.GetViewMatrix()  but corrupted pos and vector.
                // Camera.                  CameraController.GetViewMatrix()

                //MyAPIGateway.Session.Player.PlayerCharacter.GetHeadMatrix(true, true, true);
                //MyAPIGateway.Session.CameraController.GetViewMatrix();
                //MyAPIGateway.Session.ControlledObject.GetHeadMatrix(true, true, true);
                //Sandbox.ModAPI.IMyControllerInfo //?
                //Sandbox.ModAPI.IMyEntityController
                //Sandbox.ModAPI.Interfaces.IMyCameraController
                //Sandbox.ModAPI.Interfaces.IMyControllableEntity

                // The CameraController.GetViewMatrix appears warped at the moment.
                //var position = ((IMyEntity)MyAPIGateway.Session.CameraController).GetPosition();
                var camMatrix = MyAPIGateway.Session.CameraController.GetViewMatrix();
                var camPosition = camMatrix.Translation;
                MyAPIGateway.Utilities.ShowMessage("Cam", string.Format("x={0:N},y={1:N},z={2:N}  x={3:N},y={4:N},z={5:N}", camPosition.X, camPosition.Y, camPosition.Z, camMatrix.Forward.X, camMatrix.Forward.Y, camMatrix.Forward.Z));

                //var worldMatrix = MyAPIGateway.Session.ControlledObject.Entity.WorldMatrix;
                var worldMatrix = MyAPIGateway.Session.ControlledObject.GetHeadMatrix(true, true, true);
                var position = worldMatrix.Translation;
                MyAPIGateway.Utilities.ShowMessage("Con", string.Format("x={0:N},y={1:N},z={2:N}  x={3:N},y={4:N},z={5:N}", position.X, position.Y, position.Z, worldMatrix.Forward.X, worldMatrix.Forward.Y, worldMatrix.Forward.Z));

                //MyAPIGateway.Session.Player.PlayerCharacter.MoveAndRotate(new Vector3(), new Vector2(0, 0), 90f);
                //MyAPIGateway.Session.Player.PlayerCharacter.MoveAndRotate(new Vector3(), new Vector2(3.14f, 0), 0f);
                //MyAPIGateway.Session.Player.PlayerCharacter.Up();
                // thrust, walk player forward?

                //MyAPIGateway.Session.Player.PlayerCharacter.Entity.worldmatrix

                //var character = (MyObjectBuilder_Character)obj;

                return true;
            }

            #endregion

            #region test5

            if (messageText.Equals("/test5", StringComparison.InvariantCultureIgnoreCase))
            {
                var worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.GetHeadMatrix(true, true, true); // most accurate for player view.
                var position = worldMatrix.Translation + worldMatrix.Forward * 0.5f;

                var entites = new HashSet<IMyEntity>();
                MyAPIGateway.Entities.GetEntities(entites, e => e != null);

                var list = new Dictionary<IMyEntity, double>();

                foreach (var entity in entites)
                {
                    var cubeGrid = entity as Sandbox.ModAPI.IMyCubeGrid;

                    // check if the ray comes anywhere near the Grid before continuing.
                    var ray = new RayD(position, worldMatrix.Forward);
                    if (cubeGrid != null && ray.Intersects(entity.WorldAABB).HasValue)
                    {
                        var hit = cubeGrid.RayCastBlocks(position, worldMatrix.Forward * 1000);
                        if (hit.HasValue)
                        {
                            var blocks = new List<Sandbox.ModAPI.IMySlimBlock>();
                            cubeGrid.GetBlocks(blocks, f => f.FatBlock != null);
                            MyAPIGateway.Utilities.ShowMessage("AABB", string.Format("{0}", entity.WorldAABB));

                            //    var block = blocks[0];
                            //    //block.wo
                            //    var hsv = block.FatBlock.GetDiffuseColor();
                            //    MyAPIGateway.Utilities.ShowMessage("Hsv", string.Format("{0},{1},{2}  {3}", hsv.X, hsv.Y, hsv.Z, 1.45f));
                            //    var c = VRageMath.ColorExtensions.HSVtoColor(hsv);
                            //    MyAPIGateway.Utilities.ShowMessage("Rgb", string.Format("{0},{1},{2}", c.R, c.G, c.B));
                        }
                    }
                }
                return true;
            }

            #endregion

            #region test6

            if (messageText.Equals("/test6", StringComparison.InvariantCultureIgnoreCase))
            {
                var entity = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity;
                //MyAPIGateway.Utilities.ShowMessage("AABB", string.Format("{0}", entity.WorldAABB));
                //MyAPIGateway.Utilities.ShowMessage("Size", string.Format("{0}", entity.WorldAABB.Size()));

                //if (entity is IMyPlayer)
                //    MyAPIGateway.Utilities.ShowMessage("IMyPlayer", "true");
                //if (entity is IMyCubeBlock)
                //    MyAPIGateway.Utilities.ShowMessage("IMyCubeBlock", "true");  // Ship
                //if (entity is IMyCubeGrid)
                //    MyAPIGateway.Utilities.ShowMessage("IMyCubeGrid", "true");
                //if (entity is IMyIdentity)
                //    MyAPIGateway.Utilities.ShowMessage("IMyIdentity", "true");
                //if (entity is IMyNetworkClient)
                //    MyAPIGateway.Utilities.ShowMessage("IMyNetworkClient", "true");
                //if (entity is IMyEntityController)
                //    MyAPIGateway.Utilities.ShowMessage("IMyEntityController", "true");
                //if (entity is IMyControllableEntity)
                //    MyAPIGateway.Utilities.ShowMessage("IMyControllableEntity", "true");   // Ship and player
                //if (entity is IMyCameraController)
                //    MyAPIGateway.Utilities.ShowMessage("IMyCameraController", "true");  // Everything
                //if (entity is IMyMultiplayer)
                //    MyAPIGateway.Utilities.ShowMessage("IMyMultiplayer", "true");

                if (entity is Sandbox.ModAPI.IMyCubeGrid) entity = entity.Parent;

                if (entity.Physics != null)
                {
                    var pos = entity.GetPosition();
                    //var pos = Vector3.Zero;
                    var m = Matrix.CreateWorld(pos, Vector3.Forward, Vector3.Up);
                    entity.SetWorldMatrix(m);

                    //MyAPIGateway.Multiplayer.SendEntitiesCreated();
                    //entity.LocalMatrix

                    //entity.SetPosition(pos);
                    //if (entity.SyncObject.UpdatesOnlyOnServer)
                    //    entity.SyncObject.UpdatePosition();

                    //MyAPIGateway.Utilities.ShowMessage("Physics=null", string.Format("{0}", phys == null));
                    MyAPIGateway.Utilities.ShowMessage("LinearVelocity", string.Format("{0}", entity.Physics.LinearVelocity));
                    //MyAPIGateway.Utilities.ShowMessage("Speed", string.Format("{0}", phys.Speed));
                    //MyAPIGateway.Utilities.ShowMessage("Mass", string.Format("{0}", phys.Mass));

                    //phys.AddForce(Sandbox.Engine.Physics.MyPhysicsForceType.ADD_BODY_FORCE_AND_BODY_TORQUE, Vector3.Forward, Vector3.Zero, Vector3.Zero);
                    //phys.LinearVelocity = Vector3.Forward;
                    //phys
                }

                //var vm = MyAPIGateway.Session.Player.Controller.ControlledEntity.GetHeadMatrix(true, true, true); // most accurate for player view.
                return true;
            }

            #endregion

            #region test7

            if (messageText.Equals("/test7", StringComparison.InvariantCultureIgnoreCase))
            {
                var character = (MyObjectBuilder_Character)MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.GetObjectBuilder();

                //var obj = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.GetObjectBuilder();
                var obj = MyAPIGateway.Session.Player.Client as IMyEntity;

                MyAPIGateway.Utilities.ShowMessage("isNull", string.Format("{0}", obj == null));
                //MyAPIGateway.Utilities.ShowMessage("Name", string.Format("{0}", obj.GetType().Name));

                return true;
            }

            #endregion

            #region test8

            if (messageText.Equals("/test8A", StringComparison.InvariantCultureIgnoreCase))
            {
                var gridBuilder = new MyObjectBuilder_CubeGrid()
                {
                    PersistentFlags = MyPersistentEntityFlags2.CastShadows | MyPersistentEntityFlags2.InScene,
                    GridSizeEnum = MyCubeSize.Large,
                    IsStatic = true,
                    LinearVelocity = new SerializableVector3(0, 0, 0),
                    AngularVelocity = new SerializableVector3(0, 0, 0),
                    PositionAndOrientation = new MyPositionAndOrientation(Vector3.Zero, Vector3.Forward, Vector3.Up),
                    DisplayName = "test grid"
                };

                Sandbox.Common.ObjectBuilders.MyObjectBuilder_CubeBlock cube = new Sandbox.Common.ObjectBuilders.MyObjectBuilder_CubeBlock();
                cube.Min = new SerializableVector3I(0, 0, 0);
                cube.SubtypeName = "LargeBlockArmorBlock";
                cube.ColorMaskHSV = new SerializableVector3(0, -1, 0);
                cube.ShareMode = MyOwnershipShareModeEnum.None;
                cube.EntityId = 0;
                cube.Owner = 0;
                cube.BlockOrientation = new SerializableBlockOrientation(Base6Directions.Direction.Forward, Base6Directions.Direction.Up);
                cube.ShareMode = Sandbox.Common.ObjectBuilders.MyOwnershipShareModeEnum.All;
                gridBuilder.CubeBlocks.Add(cube);

                // multiple grids...
                //var tempList = new List<MyObjectBuilder_EntityBase>();
                //tempList.Add(gridBuilder);
                //MyAPIGateway.Entities.RemapObjectBuilderCollection(tempList);
                //tempList.ForEach(grid => MyAPIGateway.Entities.CreateFromObjectBuilderAndAdd(grid));
                //MyAPIGateway.Multiplayer.SendEntitiesCreated(tempList);

                // Single grid.
                MyAPIGateway.Entities.RemapObjectBuilder(gridBuilder);
                MyAPIGateway.Entities.CreateFromObjectBuilderAndAdd(gridBuilder);
                MyAPIGateway.Multiplayer.SendEntitiesCreated(new List<MyObjectBuilder_EntityBase> { gridBuilder });

                MyAPIGateway.Utilities.ShowMessage("OK", "fine");

                return true;
            }

            if (messageText.Equals("/test8B", StringComparison.InvariantCultureIgnoreCase))
            {
                var entity = Support.FindLookAtEntity(MyAPIGateway.Session.ControlledObject, true, false, false) as Sandbox.ModAPI.IMyCubeGrid;

                if (entity == null)
                    return false;

                var gridBuilder = new MyObjectBuilder_CubeGrid()
                {
                    PersistentFlags = MyPersistentEntityFlags2.CastShadows | MyPersistentEntityFlags2.InScene,
                    GridSizeEnum = MyCubeSize.Large,
                    IsStatic = true,
                    LinearVelocity = new SerializableVector3(0, 0, 0),
                    AngularVelocity = new SerializableVector3(0, 0, 0),
                    PositionAndOrientation = new MyPositionAndOrientation(Vector3.Zero, Vector3.Forward, Vector3.Up),
                    DisplayName = "test grid"
                };

                Sandbox.Common.ObjectBuilders.MyObjectBuilder_CubeBlock cube = new Sandbox.Common.ObjectBuilders.MyObjectBuilder_CubeBlock();
                cube.Min = new SerializableVector3I(0, 0, 0);
                cube.SubtypeName = "LargeBlockArmorBlock";
                cube.ColorMaskHSV = new SerializableVector3(0, -1, 0);
                cube.ShareMode = MyOwnershipShareModeEnum.None;
                cube.Owner = 0;
                cube.BlockOrientation = new SerializableBlockOrientation(Base6Directions.Direction.Forward, Base6Directions.Direction.Up);
                cube.ShareMode = Sandbox.Common.ObjectBuilders.MyOwnershipShareModeEnum.All;
                gridBuilder.CubeBlocks.Add(cube);

                //var tempList = new List<MyObjectBuilder_EntityBase>();
                //tempList.Add(gridBuilder);
                //MyAPIGateway.Entities.RemapObjectBuilderCollection(tempList); //no need for this on new object
                //var newEntity = (IMyCubeGrid)MyAPIGateway.Entities.CreateFromObjectBuilderAndAdd(tempList[0]);
                //MyAPIGateway.Multiplayer.SendEntitiesCreated(tempList);

                MyAPIGateway.Entities.RemapObjectBuilder(gridBuilder);
                var newEntity = (Sandbox.ModAPI.IMyCubeGrid)MyAPIGateway.Entities.CreateFromObjectBuilderAndAdd(gridBuilder);
                MyAPIGateway.Multiplayer.SendEntitiesCreated(new List<MyObjectBuilder_EntityBase> { gridBuilder });
                entity.MergeGrid_MergeBlock(newEntity, new Vector3I(0, 1, 0));

                MyAPIGateway.Utilities.ShowMessage("OK", "fine");

                return true;
            }

            #endregion

            #region test9

            if (messageText.Equals("/test9", StringComparison.InvariantCultureIgnoreCase))
            {
                var allEntites = new HashSet<IMyEntity>();
                MyAPIGateway.Entities.GetEntities(allEntites, e => e != null);

                var sphere = new BoundingSphereD(Vector3D.Zero, 1000000f);
                var allSphereEntities = MyAPIGateway.Entities.GetEntitiesInSphere(ref sphere);

                MyAPIGateway.Utilities.ShowMessage("All Entities", String.Format("{0} == {1} ??", allEntites.Count, allSphereEntities.Count));

                return true;
            }

            #endregion

            #region test10

            if (messageText.StartsWith("/test10 ", StringComparison.InvariantCultureIgnoreCase))
            {
                var match = Regex.Match(messageText, @"/test10\s{1,}(?<Key>.+)", RegexOptions.IgnoreCase);
                if (match.Success)
                {
                    var prefabName = match.Groups["Key"].Value;

                    var entities = new HashSet<IMyEntity>();
                    MyAPIGateway.Entities.GetEntities(entities, e => e is Sandbox.ModAPI.IMyCubeGrid);

                    var idx = Int32.Parse(prefabName);
                    var cubeGrid = (Sandbox.ModAPI.IMyCubeGrid)entities.ToArray()[idx];

                    var grids = cubeGrid.GetAttachedGrids();

                    MyAPIGateway.Utilities.ShowMessage("Attached Count", string.Format("{0}", grids.Count));

                    //foreach (var grid in grids)
                    //    MyAPIGateway.Utilities.ShowMessage("Attached", string.Format("{0}", grid.EntityId));

                    return true;
                }
                //var vm = MyAPIGateway.Session.Player.Controller.ControlledEntity.GetHeadMatrix(true, true, true); // most accurate for player view.
            }

            #endregion

            #region test11

            if (messageText.Equals("/test11", StringComparison.InvariantCultureIgnoreCase))
            {

                //var identities = new List<IMyIdentity>();
                //MyAPIGateway.Players.GetAllIdentites(identities);
                //var ident = identities.FirstOrDefault();
                //var bIdent = ((IMyEntity)ident).GetObjectBuilder();
                //MyAPIGateway.Utilities.ShowMessage("IMyIdentity", string.Format("{0}", bIdent.GetType()));

                var players = new List<IMyPlayer>();
                MyAPIGateway.Players.GetPlayers(players, p => p != null);
                var player = players.FirstOrDefault();

                var cpnt = MyAPIGateway.Session.GetCheckpoint("null");
                MyAPIGateway.Utilities.ShowMessage("cpnt", cpnt.Clients == null ? "null" : string.Format("{0}", cpnt.Clients.Count));

                var c = MyAPIGateway.Session.GetWorld().Checkpoint.Clients;
                MyAPIGateway.Utilities.ShowMessage("Count", c == null ? "null" : string.Format("{0}", c.Count));

                var nc = player.Client;
                MyAPIGateway.Utilities.ShowMessage("IMyNetworkClient", string.Format("{0}", nc.GetType()));
                //MyAPIGateway.Utilities.ShowMessage("IMyNetworkClient", string.Format("{0}", nc.GetType().BaseType));

                //var bPlayer = ((IMyEntity)nc).GetObjectBuilder();
                //MyAPIGateway.Utilities.ShowMessage("IMyPlayer", string.Format("{0}", bPlayer.GetType()));

                //var vm = MyAPIGateway.Session.Player.Controller.ControlledEntity.GetHeadMatrix(true, true, true); // most accurate for player view.
                return true;
            }

            #endregion

            #region test12

            if (messageText.Equals("/test12", StringComparison.InvariantCultureIgnoreCase))
            {
                var entity = Support.FindLookAtEntity(MyAPIGateway.Session.ControlledObject);
                var resultList = new List<ITerminalAction>();
                if (entity != null)
                {
                    var displayName = entity.DisplayName;
                    MyAPIGateway.Utilities.ShowMessage("ID", displayName);

                    MyAPIGateway.Utilities.ShowMessage("Components", string.Format("{0}", entity.Components == null));
                    MyAPIGateway.Utilities.ShowMessage("Hierarchy", string.Format("{0}", entity.Hierarchy == null));

                    var cockpits = entity.FindWorkingCockpits();
                    var terminal = (IMyTerminalBlock)cockpits[0];
                    //cockpits[0]
                    terminal.GetActions(resultList);
                    MyAPIGateway.Utilities.ShowMessage("count", string.Format("{0}", resultList.Count));
                }

                //Vector3D? FindFreePlace(Vector3D basePos, float radius, int maxTestCount = 20, int testsPerDistance = 5, float stepSize = 1f);
                //MyAPIGateway.Entities.FindFreePlace(

                //resultList.Clear();
                //var myObject = Sandbox.Common.ObjectBuilders.Serializer.MyObjectBuilderSerializer.CreateNewObject(typeof(MyObjectBuilder_Reactor), "SmallBlockLargeGenerator");
                //MyAPIGateway.TerminalActionsHelper.GetActions(typeof(MyObjectBuilder_Reactor), resultList);
                //MyAPIGateway.Utilities.ShowMessage("count", string.Format("{0}", resultList.Count));

                //MyAPIGateway.TerminalActionsHelper.GetActions(typeof(IMyMotorStator), resultList);
                //MyAPIGateway.Utilities.ShowMessage("count", string.Format("{0}", resultList.Count));

                //MyAPIGateway.TerminalActionsHelper.GetActions(typeof(IMyFunctionalBlock), resultList);
                //MyAPIGateway.Utilities.ShowMessage("count", string.Format("{0}", resultList.Count));

                //MyAPIGateway.TerminalActionsHelper.GetActions(typeof(IMyTerminalBlock), resultList);
                //MyAPIGateway.Utilities.ShowMessage("count", string.Format("{0}", resultList.Count));

                foreach (var a in resultList)
                {
                    MyAPIGateway.Utilities.ShowMessage("item", string.Format("{0}={1}", a.Name, a.Id));
                }

                return true;
            }

            #endregion

            #region test13

            if (messageText.Equals("/test13", StringComparison.InvariantCultureIgnoreCase))
            {
                var entites = new HashSet<IMyEntity>();
                MyAPIGateway.Entities.GetEntities(entites, e => e != null);

                //var physicalItem = MyDefinitionManager.Static.GetCubeBlockDefinition(new MyDefinitionId(typeof(MyObjectBuilder_SpaceBall), "SpaceBallLarge"));
                //physicalItem.Public = true;

                //MyDefinitionManager.Static.EnvironmentDefinition.SmallShipMaxSpeed = 2000;
                //MyDefinitionManager.Static.EnvironmentDefinition.LargeShipMaxSpeed = 2000;
                MyAPIGateway.Session.GetCheckpoint("null").GameMode = MyGameModeEnum.Creative;
                //MyAPIGateway.Session.GetCheckpoint("null").CargoShipsEnabled
                //MyAPIGateway.Session.GetCheckpoint("null").EnableCopyPaste = true;

                //MyAPIGateway.Utilities.ShowMessage("Sun Distance", string.Format("{0}", MyDefinitionManager.Static.EnvironmentDefinition.DistanceToSun));
                //MyDefinitionManager.Static.EnvironmentDefinition.DirectionToSun = new Vector3(0, 1, 0);

                foreach (var entity in entites)
                {
                    var cubeGrid = entity as Sandbox.ModAPI.IMyCubeGrid;
                    if (cubeGrid != null)
                    {
                        var terminalsys = MyAPIGateway.TerminalActionsHelper.GetTerminalSystemForGrid(cubeGrid);
                        //MyAPIGateway.Utilities.ShowMessage("Grid count", string.Format("{0} {1} {2}", cubeGrid.DisplayName, terminalsys.Blocks.Count, terminalsys.BlockGroups.Count));

                        //var blocks = new List<Sandbox.ModAPI.IMySlimBlock>();
                        //cubeGrid.GetBlocks(blocks, f => f.FatBlock != null && f.FatBlock == MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity);
                        //MyAPIGateway.Utilities.ShowMessage("Pilot count", string.Format("{0}", blocks.Count));

                        //cubeGrid.GetBlocks(blocks);
                        //foreach (var block in blocks)
                        //{
                        //    cubeGrid.ColorBlocks(block.Position, block.Position, VRageMath.Color.Gold.ToHsvColor());
                        //}

                    }
                }

                return true;
            }

            #endregion

            #region test14

            // Tag every floating object in player GPS.
            if (messageText.Equals("/test14", StringComparison.InvariantCultureIgnoreCase))
            {
                var entites = new HashSet<IMyEntity>();
                MyAPIGateway.Entities.GetEntities(entites, e => (e is Sandbox.ModAPI.IMyFloatingObject));

                foreach (var entity in entites)
                {
                    var pos = entity.GetPosition();
                    var gps = MyAPIGateway.Session.GPS.Create("Floating " + entity.DisplayName, "Some drifting junk", pos, true, false);
                    MyAPIGateway.Session.GPS.AddLocalGps(gps);
                }

                return true;
            }

            #endregion

            return false;
        }
예제 #10
0
        public bool TryNamingAnBlockOrFloatingObject()
        {
            var worldMatrix = MyAPIGateway.Session.Camera.WorldMatrix; // most accurate for player view.
            var position    = worldMatrix.Translation + worldMatrix.Forward * 0.5f;
            var ray         = new RayD(position, worldMatrix.Forward * 1000);

            var boundingSphere = new BoundingSphereD(worldMatrix.Translation, 30);
            var entites        = MyEntities.GetEntitiesInSphere(ref boundingSphere);

            List <MyPhysics.HitInfo> hits = new List <MyPhysics.HitInfo>();

            MyPhysics.CastRay(worldMatrix.Translation, worldMatrix.Translation + worldMatrix.Forward * 5, hits, 15);

            foreach (var hitInfo in hits)
            {
                var body = (MyPhysicsBody)hitInfo.HkHitInfo.Body.UserObject;
                if (body.Entity is MyFloatingObject)
                {
                    var rayEntity = (MyEntity)body.Entity;
                    NameDialog(rayEntity);
                    return(true);
                }
            }

            foreach (var entity in entites)
            {
                var cubeGrid = entity as MyCubeGrid;

                if (cubeGrid != null && ray.Intersects(entity.PositionComp.WorldAABB).HasValue)
                {
                    var hit = cubeGrid.RayCastBlocks(worldMatrix.Translation, worldMatrix.Translation + worldMatrix.Forward * 100);
                    if (hit.HasValue)
                    {
                        var block = cubeGrid.GetCubeBlock(hit.Value);

                        if (block.FatBlock != null)
                        {
                            var dialog = new ValueGetScreenWithCaption("Name block dialog: " + block.FatBlock.DefinitionDisplayNameText, block.FatBlock.Name ?? block.FatBlock.DefinitionDisplayNameText + " has no name.", delegate(string text)
                            {
                                MyEntity foundEntity;
                                if (MyEntities.TryGetEntityByName(text, out foundEntity))
                                {
                                    MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox(
                                                               buttonType: MyMessageBoxButtonsType.OK,
                                                               messageText: new StringBuilder("Entity with same name already exits, please enter different name."),
                                                               messageCaption: new StringBuilder("Naming error")));
                                }
                                else
                                {
                                    block.FatBlock.Name = text;
                                    MyEntities.SetEntityName(block.FatBlock, true);

                                    return(true);
                                }

                                return(false);
                            });
                            MyGuiSandbox.AddScreen(dialog);
                            entites.Clear();
                            return(true);
                        }
                    }
                }
            }

            entites.Clear();
            return(false);
        }
        public static void FindLookAtEntity(IMyControllableEntity controlledEntity, out IMyEntity lookEntity, out double lookDistance, bool findShips = true, bool findPlayers = true, bool findAsteroids = true, bool findPlanets = true)
        {
            const float range = 5000000;
            Matrix worldMatrix;
            Vector3D startPosition;
            Vector3D endPosition;
            if (MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.Parent == null)
            {
                worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.GetHeadMatrix(true, true, false); // dead center of player cross hairs.
                startPosition = worldMatrix.Translation + worldMatrix.Forward * 0.5f;
                endPosition = worldMatrix.Translation + worldMatrix.Forward * (range + 0.5f);
            }
            else
            {
                worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.WorldMatrix;
                // TODO: need to adjust for position of cockpit within ship.
                startPosition = worldMatrix.Translation + worldMatrix.Forward * 1.5f;
                endPosition = worldMatrix.Translation + worldMatrix.Forward * (range + 1.5f);
            }

            //var worldMatrix = MyAPIGateway.Session.Player.PlayerCharacter.Entity.WorldMatrix;
            //var position = MyAPIGateway.Session.Player.PlayerCharacter.Entity.GetPosition();
            //var position = worldMatrix.Translation + worldMatrix.Forward * 0.5f + worldMatrix.Up * 1.0f;
            //MyAPIGateway.Utilities.ShowMessage("Pos", string.Format("x={0:N},y={1:N},z={2:N}  x={3:N},y={4:N},z={5:N}", playerPos.X, playerPos.Y, playerPos.Z, playerMatrix.Forward.X, playerMatrix.Forward.Y, playerMatrix.Forward.Z));

            // The CameraController.GetViewMatrix appears warped at the moment.
            //var position = ((IMyEntity)MyAPIGateway.Session.CameraController).GetPosition();
            //var worldMatrix = MyAPIGateway.Session.CameraController.GetViewMatrix();
            //var position = worldMatrix.Translation;
            //MyAPIGateway.Utilities.ShowMessage("Cam", string.Format("x={0:N},y={1:N},z={2:N}  x={3:N},y={4:N},z={5:N}", position.X, position.Y, position.Z, worldMatrix.Forward.X, worldMatrix.Forward.Y, worldMatrix.Forward.Z));

            var entites = new HashSet<IMyEntity>();
            MyAPIGateway.Entities.GetEntities(entites, e => e != null);

            var list = new Dictionary<IMyEntity, double>();
            var ray = new RayD(startPosition, worldMatrix.Forward);

            foreach (var entity in entites)
            {
                if (findShips)
                {
                    var cubeGrid = entity as Sandbox.ModAPI.IMyCubeGrid;

                    // check if the ray comes anywhere near the Grid before continuing.
                    if (cubeGrid != null && ray.Intersects(entity.WorldAABB).HasValue)
                    {
                        var hit = cubeGrid.RayCastBlocks(startPosition, endPosition);
                        if (hit.HasValue)
                        {
                            var distance = (startPosition - cubeGrid.GridIntegerToWorld(hit.Value)).Length();
                            list.Add(entity, distance);
                        }
                    }
                }

                if (findPlayers)
                {
                    var controller = entity as IMyControllableEntity;
                    if (MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.EntityId != entity.EntityId && controller != null && ray.Intersects(entity.WorldAABB).HasValue)
                    {
                        var distance = (startPosition - entity.GetPosition()).Length();
                        list.Add(entity, distance);
                    }
                }

                if (findAsteroids)
                {
                    var voxelMap = entity as IMyVoxelMap;
                    if (voxelMap != null)
                    {
                        var aabb = new BoundingBoxD(voxelMap.PositionLeftBottomCorner, voxelMap.PositionLeftBottomCorner + voxelMap.Storage.Size);
                        var hit = ray.Intersects(aabb);
                        if (hit.HasValue)
                        {
                            var center = voxelMap.PositionLeftBottomCorner + (voxelMap.Storage.Size / 2);
                            var distance = (startPosition - center).Length();  // use distance to center of asteroid.
                            list.Add(entity, distance);
                        }
                    }
                }

                if (findPlanets)
                {
                    // Looks to be working against Git and public release.
                    var planet = entity as Sandbox.Game.Entities.MyPlanet;
                    if (planet != null)
                    {
                        var aabb = new BoundingBoxD(planet.PositionLeftBottomCorner, planet.PositionLeftBottomCorner + planet.Size);
                        var hit = ray.Intersects(aabb);
                        if (hit.HasValue)
                        {
                            var center = planet.PositionLeftBottomCorner + (planet.Size / 2);
                            var distance = (startPosition - center).Length(); // use distance to center of planet.
                            list.Add(entity, distance);
                        }
                    }
                }
            }

            if (list.Count == 0)
            {
                lookEntity = null;
                lookDistance = 0;
                return;
            }

            // find the closest Entity.
            var item = list.OrderBy(f => f.Value).First();
            lookEntity = item.Key;
            lookDistance = item.Value;
        }
예제 #12
0
        public void Update(List <IMyEntity> missileCollection)
        {
            if (SafetyTimerIsOver())
            {
                ModDebugger.Launch();
                //      if (Missile.Physics.Flags != RigidBodyFlag.RBF_BULLET) Missile.Physics.Flags = RigidBodyFlag.RBF_BULLET;
                //     float TURNING_SPEED = 0.1f;
                //   float FACTOR = 2f;
                //    Log.Info("Missile.Physics.Flags");
                //BLEH
                Vector3 targetPoint = Vector3.Zero;
                try
                {
                    Vector3 boundingBoxCenter = (Target.WorldAABB.Max + Target.WorldAABB.Min) * 0.5;
                    if (boundingBoxCenter == Vector3.Zero)
                    {
                        boundingBoxCenter = Target.GetPosition();
                    }
                    if (_hasPhysicsSteering)
                    {
                        Ray   positiveVelocityRay = new Ray(Missile.GetPosition(), Missile.Physics.LinearVelocity);
                        Ray   negativeVelocityRay = new Ray(Missile.GetPosition(), -1f * Missile.Physics.LinearVelocity);
                        Plane targetPlane         = new Plane(boundingBoxCenter, Vector3.Normalize(Missile.Physics.LinearVelocity));
                        float?intersectionDist    = positiveVelocityRay.Intersects(targetPlane);
                        //  Vector3 reverseVector;
                        if (intersectionDist != null)
                        {
                            targetPoint = positiveVelocityRay.Position + (float)intersectionDist * positiveVelocityRay.Direction;
                            //  reverseVector = Target.GetPosition() - targetPoint;
                            targetPoint = 2 * boundingBoxCenter - targetPoint;
                            //  targetPoint = targetPoint +  reverseVector;
                        }
                        else
                        {
                            intersectionDist = negativeVelocityRay.Intersects(targetPlane);
                            if (intersectionDist != null)
                            {
                                if ((_isOvershooting == false) && (_finishedOvershooting == false))
                                {
                                    _overshootDistance = Missile.Physics.LinearVelocity.Length() * (360 / _turningSpeed) / 10000 + 0;
                                    _isOvershooting    = true;
                                }
                                //  targetPoint = negativeVelocityRay.Position + (float)intersectionDist * negativeVelocityRay.Direction;

                                if (_isOvershooting && !_finishedOvershooting)
                                {
                                    if (intersectionDist > _overshootDistance)
                                    {
                                        targetPoint           = boundingBoxCenter;
                                        _finishedOvershooting = true;
                                        // Log.Info("we finished overshooting, returning to target.");
                                    }
                                    else
                                    {
                                        targetPoint = Missile.GetPosition() + Missile.WorldMatrix.Forward;
                                        //   Log.Info("we overshot, we keep heading forward.");
                                        //   Log.Info("         current Distance: " + intersectionDist + " and overshootCorr " + _overshootDistance);
                                    }
                                }
                                else if (_isOvershooting && _finishedOvershooting)
                                {
                                    targetPoint = boundingBoxCenter;
                                }
                            }
                        }


                        Vector3 diffVelocity = Target.GetTopMostParent().Physics.LinearVelocity - Missile.Physics.LinearVelocity;

                        if (targetPoint == Vector3.Zero)
                        {
                            targetPoint = boundingBoxCenter - diffVelocity;
                        }
                    }
                    else
                    {
                        targetPoint = boundingBoxCenter;
                    }
                }
                catch (Exception e)
                {
                    Log.Info("Caught exception during MissileData Update! " + e);
                    if (Target != null)
                    {
                        targetPoint = Target.GetPosition();
                    }
                }

                Vector3 targetDirection = Vector3.Normalize(targetPoint - Missile.GetPosition());



                float maxRadVelocity = MathHelper.ToRadians(_turningSpeed);
                float angle          = MyUtils.GetAngleBetweenVectorsAndNormalise(Missile.WorldMatrix.Forward,
                                                                                  targetDirection);



                // Log.Info("angle = " + MathHelper.ToDegrees(angle));
                float turnPercent;

                if (Math.Abs(angle) < Double.Epsilon)
                {
                    turnPercent = 0f;
                }
                else if (Math.Abs(angle) > maxRadVelocity)
                {
                    turnPercent = maxRadVelocity / Math.Abs(angle);
                }
                else
                {
                    turnPercent = 1f;
                }


                Matrix targetMatrix = Matrix.CreateWorld(Missile.GetPosition(), targetDirection,
                                                         Vector3D.CalculatePerpendicularVector(targetDirection));
                //Matrix.CreateFromYawPitchRoll(0f, (float)Math.PI*0.5f, 0f)));

                var slerpMatrix = Matrix.Slerp(Missile.WorldMatrix, targetMatrix, turnPercent);

                RayD nextTargetLineD = new RayD(Missile.GetPosition(), slerpMatrix.Forward);

                bool iswait = false;
                foreach (var othermissile in missileCollection)
                {
                    if (othermissile.EntityId == Missile.EntityId)
                    {
                        continue;
                    }
                    if (nextTargetLineD.Intersects(othermissile.WorldVolume) != null)
                    {
                        iswait = true;
                    }
                }

                if (iswait == false)
                {
                    Missile.SetWorldMatrix(slerpMatrix);

                    if (_hasPhysicsSteering)
                    {
                        var linVel   = Missile.Physics.LinearVelocity;
                        var linSpeed = linVel.Length();
                        Missile.Physics.LinearVelocity = 0.98f * linVel + 0.02f * Missile.WorldMatrix.Forward * linSpeed;
                    }
                    else
                    {
                        Vector3 linVel = Missile.Physics.LinearVelocity;
                        Missile.Physics.LinearVelocity = Vector3.Normalize(Missile.WorldMatrix.Forward) * linVel.Length();
                    }
                }
            }
            else
            {
                //     if (Missile.Physics.Flags == RigidBodyFlag.RBF_BULLET) Missile.Physics.Flags = RigidBodyFlag.RBF_BULLET & RigidBodyFlag.RBF_DISABLE_COLLISION_RESPONSE;
            }
            Tick();
        }
예제 #13
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( );
                }
            });
        }
예제 #14
0
        public static void OnGlobalSpawnEvent(object senderEvent)
        {
            // Select a spawn group to spawn
            MySpawnGroupDefinition spawnGroup = PickRandomSpawnGroup();

            if (spawnGroup == null)
            {
                return;
            }

            spawnGroup.ReloadPrefabs();

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

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

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

            double       forbiddenRadius = NEUTRAL_SHIP_FORBIDDEN_RADIUS;
            BoundingBoxD spawnBox;

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

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

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

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

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

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

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

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

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

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

            ProfilerShort.End();

            ProfilerShort.Begin("Check free space");

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

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

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

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

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

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

            ProfilerShort.End();

            ProfilerShort.Begin("Spawn ships");

            long spawnGroupId = MyPirateAntennas.GetPiratesId();

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

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

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

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

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

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

            ProfilerShort.End();
        }
예제 #15
0
        public static ConcurrentBag <MyGroups <MyCubeGrid, MyGridPhysicalGroupData> .Group> FindLookAtGridGroup(IMyCharacter controlledEntity)
        {
            const float range = 5000;
            Matrix      worldMatrix;
            Vector3D    startPosition;
            Vector3D    endPosition;

            worldMatrix   = controlledEntity.GetHeadMatrix(true, true, false); // dead center of player cross hairs, or the direction the player is looking with ALT.
            startPosition = worldMatrix.Translation + worldMatrix.Forward * 0.5f;
            endPosition   = worldMatrix.Translation + worldMatrix.Forward * (range + 0.5f);

            var list = new Dictionary <MyGroups <MyCubeGrid, MyGridPhysicalGroupData> .Group, double>();
            var ray  = new RayD(startPosition, worldMatrix.Forward);

            foreach (var group in MyCubeGridGroups.Static.Physical.Groups)
            {
                foreach (MyGroups <MyCubeGrid, MyGridPhysicalGroupData> .Node groupNodes in group.Nodes)
                {
                    IMyCubeGrid cubeGrid = groupNodes.NodeData;

                    if (cubeGrid == null)
                    {
                        continue;
                    }

                    if (cubeGrid.Physics == null)
                    {
                        continue;
                    }

                    // check if the ray comes anywhere near the Grid before continuing.
                    if (!ray.Intersects(cubeGrid.WorldAABB).HasValue)
                    {
                        continue;
                    }

                    Vector3I?hit = cubeGrid.RayCastBlocks(startPosition, endPosition);

                    if (!hit.HasValue)
                    {
                        continue;
                    }

                    double distance = (startPosition - cubeGrid.GridIntegerToWorld(hit.Value)).Length();


                    if (list.TryGetValue(group, out double oldDistance))
                    {
                        if (distance < oldDistance)
                        {
                            list.Remove(group);
                            list.Add(group, distance);
                        }
                    }
                    else
                    {
                        list.Add(group, distance);
                    }
                }
            }

            var bag = new ConcurrentBag <MyGroups <MyCubeGrid, MyGridPhysicalGroupData> .Group>();

            if (list.Count == 0)
            {
                return(bag);
            }

            // find the closest Entity.
            var item = list.OrderBy(f => f.Value).First();

            bag.Add(item.Key);

            return(bag);
        }
        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.CollisionLayers.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.CollisionLayers.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");

            long spawnGroupId = MyPirateAntennas.GetPiratesId();

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

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

                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
                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,
                                     ownerId: shipPrefab.ResetOwnership ? spawnGroupId : 0,
                    updateSync: true);
                ProfilerShort.End();

                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();

                ProfilerShort.End();
            }

            ProfilerShort.End();
        }
예제 #17
0
        internal static void AcquireProjectile(Weapon w, out TargetType targetType)
        {
            var ai        = w.Comp.Ai;
            var s         = w.System;
            var physics   = s.Session.Physics;
            var target    = w.NewTarget;
            var weaponPos = w.MyPivotPos;

            var collection   = ai.GetProCache();
            var numOfTargets = collection.Count;
            var lockedOnly   = w.System.Values.Targeting.LockedSmartOnly;
            var smartOnly    = w.System.Values.Targeting.IgnoreDumbProjectiles;

            if (s.ClosestFirst)
            {
                int length = collection.Count;
                for (int h = length / 2; h > 0; h /= 2)
                {
                    for (int i = h; i < length; i += 1)
                    {
                        var    tempValue = collection[i];
                        double temp;
                        Vector3D.DistanceSquared(ref collection[i].Position, ref weaponPos, out temp);

                        int j;
                        for (j = i; j >= h && Vector3D.DistanceSquared(collection[j - h].Position, weaponPos) > temp; j -= h)
                        {
                            collection[j] = collection[j - h];
                        }

                        collection[j] = tempValue;
                    }
                }
            }

            var numToRandomize = s.ClosestFirst ? w.System.Values.Targeting.TopTargets : numOfTargets;
            var deck           = GetDeck(ref target.TargetDeck, ref target.TargetPrevDeckLen, 0, numOfTargets, numToRandomize, w.TargetData.WeaponRandom, Acquire);

            for (int x = 0; x < numOfTargets; x++)
            {
                var card = deck[x];
                var lp   = collection[card];
                var cube = lp.Info.Target.Entity as MyCubeBlock;
                if (smartOnly && !lp.SmartsOn || lockedOnly && (!lp.SmartsOn || cube != null && cube.CubeGrid.IsSameConstructAs(w.Comp.Ai.MyGrid)) || lp.MaxSpeed > s.MaxTargetSpeed || lp.MaxSpeed <= 0 || lp.State != Projectile.ProjectileState.Alive || Vector3D.DistanceSquared(lp.Position, w.MyPivotPos) > w.MaxTargetDistanceSqr || Vector3D.DistanceSquared(lp.Position, w.MyPivotPos) < w.MinTargetDistanceSqr)
                {
                    continue;
                }

                Vector3D predictedPos;
                if (Weapon.CanShootTarget(w, ref lp.Position, lp.Velocity, lp.AccelVelocity, out predictedPos))
                {
                    var needsCast = false;
                    for (int i = 0; i < ai.Obstructions.Count; i++)
                    {
                        var ent       = ai.Obstructions[i];
                        var obsSphere = ent.PositionComp.WorldVolume;

                        var dir  = lp.Position - weaponPos;
                        var beam = new RayD(ref weaponPos, ref dir);

                        if (beam.Intersects(obsSphere) != null)
                        {
                            var transform = ent.PositionComp.WorldMatrixRef;
                            var box       = ent.PositionComp.LocalAABB;
                            var obb       = new MyOrientedBoundingBoxD(box, transform);
                            if (obb.Intersects(ref beam) != null)
                            {
                                needsCast = true;
                                break;
                            }
                        }
                    }

                    if (needsCast)
                    {
                        IHitInfo hitInfo;
                        physics.CastRay(weaponPos, lp.Position, out hitInfo, 15);
                        if (hitInfo?.HitEntity == null && (!w.System.Values.HardPoint.Other.MuzzleCheck || !w.MuzzleHitSelf()))
                        {
                            double hitDist;
                            Vector3D.Distance(ref weaponPos, ref lp.Position, out hitDist);
                            var        shortDist = hitDist;
                            var        origDist  = hitDist;
                            const long topEntId  = long.MaxValue;
                            target.Set(null, lp.Position, shortDist, origDist, topEntId, lp);
                            targetType = TargetType.Projectile;
                            target.TransferTo(w.Target, w.Comp.Session.Tick);
                            return;
                        }
                    }
                    else
                    {
                        Vector3D?hitInfo;
                        if (GridIntersection.BresenhamGridIntersection(ai.MyGrid, ref weaponPos, ref lp.Position, out hitInfo, w.Comp.MyCube, w.Comp.Ai))
                        {
                            continue;
                        }

                        double hitDist;
                        Vector3D.Distance(ref weaponPos, ref lp.Position, out hitDist);
                        var        shortDist = hitDist;
                        var        origDist  = hitDist;
                        const long topEntId  = long.MaxValue;
                        target.Set(null, lp.Position, shortDist, origDist, topEntId, lp);
                        targetType = TargetType.Projectile;
                        target.TransferTo(w.Target, w.Comp.Session.Tick);
                        return;
                    }
                }
            }
            targetType = TargetType.None;
        }
예제 #18
0
        public static List <MyCubeGrid> FindLookAtGridGroup(IMyCharacter controlledEntity, long playerId, out CheckResult result)
        {
            const float range = 5000;
            Matrix      worldMatrix;
            Vector3D    startPosition;
            Vector3D    endPosition;

            var GridsGroup   = new List <MyCubeGrid>();
            var charlocation = controlledEntity.PositionComp.GetPosition();
            var sphere       = new BoundingSphereD(charlocation, range);
            var entList      = MyAPIGateway.Entities.GetTopMostEntitiesInSphere(ref sphere);

            if (entList == null || entList.Count == 0)
            {
                result = CheckResult.GRID_NOT_FOUND;
                return(GridsGroup);
            }

            worldMatrix   = controlledEntity.GetHeadMatrix(true, true, false); // dead center of player cross hairs, or the direction the player is looking with ALT.
            startPosition = worldMatrix.Translation + worldMatrix.Forward * 0.5f;
            endPosition   = worldMatrix.Translation + worldMatrix.Forward * (range + 0.5f);

            var list            = new Dictionary <MyCubeGrid, double>();
            var ray             = new RayD(startPosition, worldMatrix.Forward);
            var FoundWrongOwner = false;

            foreach (var ent in entList)
            {
                if (ent is MyCubeGrid cubeGrid)
                {
                    if (cubeGrid.Physics != null)
                    {
                        // check if the ray comes anywhere near the Grid before continuing.
                        if (ray.Intersects(cubeGrid.PositionComp.WorldAABB).HasValue)
                        {
                            Vector3I?hit = cubeGrid.RayCastBlocks(startPosition, endPosition);

                            if (hit.HasValue)
                            {
                                /* We are not the server and playerId is not owner */
                                if (playerId != 0 && !OwnershipCorrect(cubeGrid, playerId))
                                {
                                    FoundWrongOwner = true;
                                    continue;
                                }

                                double distance = (startPosition - cubeGrid.GridIntegerToWorld(hit.Value)).Length();

                                if (list.TryGetValue(cubeGrid, out double oldDistance))
                                {
                                    if (distance < oldDistance)
                                    {
                                        list.Remove(cubeGrid);
                                        list.Add(cubeGrid, distance);
                                    }
                                }
                                else
                                {
                                    list.Add(cubeGrid, distance);
                                }
                            }
                        }
                    }
                }
            }

            // find the closest Entity.
            if (list != null && list.Any())
            {
                var grid = list.OrderBy(f => f.Value).First().Key;

                // only here we can see attached by landing gear grids to main grid!
                var IMygrids = new List <IMyCubeGrid>();
                MyAPIGateway.GridGroups.GetGroup(grid, GridLinkTypeEnum.Physical, IMygrids);

                // convert back to MyCubeGrid
                foreach (var Mygrid in IMygrids)
                {
                    GridsGroup.Add((MyCubeGrid)Mygrid);
                }

                // sort the list. largest to smallest
                GridsGroup.SortNoAlloc((x, y) => x.BlocksCount.CompareTo(y.BlocksCount));
                GridsGroup.Reverse();
                GridsGroup.SortNoAlloc((x, y) => x.GridSizeEnum.CompareTo(y.GridSizeEnum));

                result = CheckResult.OK;
                return(GridsGroup);
            }

            if (FoundWrongOwner)
            {
                result = CheckResult.OWNED_BY_DIFFERENT_PLAYER;
            }
            else
            {
                result = CheckResult.GRID_NOT_FOUND;
            }

            return(GridsGroup);
        }
예제 #19
0
        /// <summary>
        /// Gets a destination and tries to fix it so that it does not collide with anything
        /// </summary>
        /// <param name="originalDestination">The final destination that the remote wants to get to.</param>
        /// <param name="checkRadius">The maximum radius until which this method should search.</param>
        /// <param name="shipRadius">The radius of our ship. Make sure that this is large enough to avoid collision.</param>
        Vector3D ModAPI.Ingame.IMyRemoteControl.GetFreeDestination(Vector3D originalDestination, float checkRadius, float shipRadius)
        {
            MyCestmirDebugInputComponent.ClearDebugSpheres();
            MyCestmirDebugInputComponent.ClearDebugPoints();

            MyCestmirDebugInputComponent.AddDebugPoint(this.WorldMatrix.Translation, Color.Green);

            Vector3D retval = originalDestination;
            BoundingSphereD sphere = new BoundingSphereD(this.WorldMatrix.Translation, shipRadius + checkRadius);

            Vector3D rayDirection = originalDestination - this.WorldMatrix.Translation;
            double originalDistance = rayDirection.Length();
            rayDirection = rayDirection / originalDistance;
            RayD ray = new RayD(this.WorldMatrix.Translation, rayDirection);

            double closestIntersection = double.MaxValue;
            BoundingSphereD closestSphere = default(BoundingSphereD);

            var entities = MyEntities.GetEntitiesInSphere(ref sphere);
            for (int i = 0; i < entities.Count; ++i)
            {
                var entity = entities[i];

                if (!(entity is MyCubeGrid) && !(entity is MyVoxelMap)) continue;
                if (entity.Parent != null) continue;
                if (entity == this.Parent) continue;

                BoundingSphereD entitySphere = entity.PositionComp.WorldVolume;
                entitySphere.Radius += shipRadius;

                MyCestmirDebugInputComponent.AddDebugSphere(entitySphere.Center, (float)entity.PositionComp.WorldVolume.Radius, Color.Plum);
                MyCestmirDebugInputComponent.AddDebugSphere(entitySphere.Center, (float)entity.PositionComp.WorldVolume.Radius + shipRadius, Color.Purple);

                double? intersection = ray.Intersects(entitySphere);
                if (intersection.HasValue && intersection.Value < closestIntersection)
                {
                    closestIntersection = intersection.Value;
                    closestSphere = entitySphere;
                }
            }

            if (closestIntersection != double.MaxValue)
            {
                Vector3D correctedDestination = ray.Position + closestIntersection * ray.Direction;
                MyCestmirDebugInputComponent.AddDebugSphere(correctedDestination, 1.0f, Color.Blue);
                Vector3D normal = correctedDestination - closestSphere.Center;
                if (Vector3D.IsZero(normal))
                {
                    normal = Vector3D.Up;
                }
                normal.Normalize();
                MyCestmirDebugInputComponent.AddDebugSphere(correctedDestination + normal, 1.0f, Color.Red);
                Vector3D newDirection = Vector3D.Reject(ray.Direction, normal);
                newDirection.Normalize();
                newDirection *= Math.Max(20.0, closestSphere.Radius * 0.5);
                MyCestmirDebugInputComponent.AddDebugSphere(correctedDestination + newDirection, 1.0f, Color.LightBlue);
                retval = correctedDestination + newDirection;
            }
            else
            {
                retval = ray.Position + ray.Direction * Math.Min(checkRadius, originalDistance);
            }

            entities.Clear();

            return retval;
        }
        public bool TryNamingAnBlockOrFloatingObject()
        {
            var worldMatrix = MyAPIGateway.Session.Camera.WorldMatrix; // most accurate for player view.
            var position = worldMatrix.Translation + worldMatrix.Forward * 0.5f;
            var ray = new RayD(position, worldMatrix.Forward * 1000);

            var boundingSphere = new BoundingSphereD(worldMatrix.Translation, 30);
            var entites = MyEntities.GetEntitiesInSphere(ref boundingSphere);

            List<MyPhysics.HitInfo> hits = new List<MyPhysics.HitInfo>();
            MyPhysics.CastRay(worldMatrix.Translation, worldMatrix.Translation + worldMatrix.Forward * 5, hits, 15);

            foreach (var hitInfo in hits)
            {
                var body = (MyPhysicsBody)hitInfo.HkHitInfo.Body.UserObject;
                if (body.Entity is MyFloatingObject)
                {
                    var rayEntity = (MyEntity) body.Entity;
                    NameDialog(rayEntity);
                    return true;
                }
            }

            foreach (var entity in entites)
            {
                var cubeGrid = entity as MyCubeGrid;

                if (cubeGrid != null && ray.Intersects(entity.PositionComp.WorldAABB).HasValue)
                {
                    var hit = cubeGrid.RayCastBlocks(worldMatrix.Translation, worldMatrix.Translation + worldMatrix.Forward * 100);
                    if (hit.HasValue)
                    {
                        var block = cubeGrid.GetCubeBlock(hit.Value);
                        
                        if(block.FatBlock != null)
                        {
                            var dialog = new ValueGetScreenWithCaption("Name block dialog: " + block.FatBlock.DefinitionDisplayNameText, block.FatBlock.Name ?? block.FatBlock.DefinitionDisplayNameText + " has no name.", delegate(string text)
                            {
                                MyEntity foundEntity;
                                if (MyEntities.TryGetEntityByName(text, out foundEntity))
                                {
                                    MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox(
                                        buttonType: MyMessageBoxButtonsType.OK,
                                        messageText: new StringBuilder("Entity with same name already exits, please enter different name."),
                                        messageCaption: new StringBuilder("Naming error")));
                                }
                                else
                                {
                                    block.FatBlock.Name = text;
                                    MyEntities.SetEntityName(block.FatBlock, true);

                                    return true;
                                }

                                return false;
                            }); 
                            MyGuiSandbox.AddScreen(dialog);
                            entites.Clear();
                            return true;
                        }
                    }
                }
            }

            entites.Clear();
            return false;
        }
        internal static Vector3D?ProcessVoxel(LineD trajectile, MyVoxelBase voxel, WeaponSystem system, List <Vector3I> testPoints)
        {
            var planet       = voxel as MyPlanet;
            var voxelMap     = voxel as MyVoxelMap;
            var ray          = new RayD(trajectile.From, trajectile.Direction);
            var voxelAABB    = voxel.PositionComp.WorldAABB;
            var rayVoxelDist = ray.Intersects(voxelAABB);

            if (rayVoxelDist.HasValue)
            {
                var voxelMaxLen = voxel.PositionComp.WorldVolume.Radius * 2;
                var start       = trajectile.From + (ray.Direction * rayVoxelDist.Value);
                var lenRemain   = trajectile.Length - rayVoxelDist.Value;
                var end         = voxelMaxLen > lenRemain ? start + (ray.Direction * lenRemain) : start + (ray.Direction * voxelMaxLen);
                var testLine    = new LineD(trajectile.From + (ray.Direction * rayVoxelDist.Value), end);
                var rotMatrix   = Quaternion.CreateFromRotationMatrix(voxel.WorldMatrix);
                var obb         = new MyOrientedBoundingBoxD(voxel.PositionComp.WorldAABB.Center, voxel.PositionComp.LocalAABB.HalfExtents, rotMatrix);
                if (obb.Intersects(ref testLine) != null)
                {
                    Log.Line("obb");
                    if (planet != null)
                    {
                        var startPos = trajectile.From - planet.PositionLeftBottomCorner;
                        var startInt = Vector3I.Round(startPos);
                        var endPos   = trajectile.To - planet.PositionLeftBottomCorner;
                        var endInt   = Vector3I.Round(endPos);

                        BresenhamLineDraw(startInt, endInt, testPoints);

                        for (int i = 0; i < testPoints.Count; ++i)
                        {
                            var voxelCoord = testPoints[i];
                            var voxelHit   = new VoxelHit();
                            planet.Storage.ExecuteOperationFast(ref voxelHit, MyStorageDataTypeFlags.Content, ref voxelCoord, ref voxelCoord, notifyRangeChanged: false);
                            if (voxelHit.HasHit)
                            {
                                return((Vector3D)voxelCoord + planet.PositionLeftBottomCorner);
                            }
                        }
                    }
                    else if (voxelMap != null)
                    {
                        var startPos = trajectile.From - voxelMap.PositionLeftBottomCorner;
                        var startInt = Vector3I.Round(startPos);
                        var endPos   = trajectile.To - voxelMap.PositionLeftBottomCorner;
                        var endInt   = Vector3I.Round(endPos);

                        BresenhamLineDraw(startInt, endInt, testPoints);

                        for (int i = 0; i < testPoints.Count; ++i)
                        {
                            var voxelCoord = testPoints[i];
                            var voxelHit   = new VoxelHit();
                            voxelMap.Storage.ExecuteOperationFast(ref voxelHit, MyStorageDataTypeFlags.Content, ref voxelCoord, ref voxelCoord, notifyRangeChanged: false);
                            if (voxelHit.HasHit)
                            {
                                return((Vector3D)voxelCoord + voxelMap.PositionLeftBottomCorner);
                            }
                        }
                    }
                }
            }

            return(null);
        }
        public static void FindLookAtEntity(IMyControllableEntity controlledEntity, bool ignoreOccupiedGrid, bool ignoreProjection, out IMyEntity lookEntity, out double lookDistance, out Vector3D hitPoint, bool findShips, bool findCubes, bool findPlayers, bool findAsteroids, bool findPlanets, bool findReplicable)
        {
            const float range = 5000000;
            Matrix worldMatrix;
            Vector3D startPosition;
            Vector3D endPosition;
            IMyCubeGrid occupiedGrid = null;

            if (controlledEntity.Entity.Parent == null)
            {
                worldMatrix = controlledEntity.GetHeadMatrix(true, true, false); // dead center of player cross hairs, or the direction the player is looking with ALT.
                startPosition = worldMatrix.Translation + worldMatrix.Forward * 0.5f;
                endPosition = worldMatrix.Translation + worldMatrix.Forward * (range + 0.5f);
            }
            else
            {
                occupiedGrid = controlledEntity.Entity.GetTopMostParent() as IMyCubeGrid;
                worldMatrix = controlledEntity.Entity.WorldMatrix;
                // TODO: need to adjust for position of cockpit within ship.
                startPosition = worldMatrix.Translation + worldMatrix.Forward * 1.5f;
                endPosition = worldMatrix.Translation + worldMatrix.Forward * (range + 1.5f);
            }

            //var worldMatrix = MyAPIGateway.Session.Player.PlayerCharacter.Entity.WorldMatrix;
            //var position = MyAPIGateway.Session.Player.PlayerCharacter.Entity.GetPosition();
            //var position = worldMatrix.Translation + worldMatrix.Forward * 0.5f + worldMatrix.Up * 1.0f;
            //MyAPIGateway.Utilities.ShowMessage("Pos", string.Format("x={0:N},y={1:N},z={2:N}  x={3:N},y={4:N},z={5:N}", playerPos.X, playerPos.Y, playerPos.Z, playerMatrix.Forward.X, playerMatrix.Forward.Y, playerMatrix.Forward.Z));

            // The CameraController.GetViewMatrix appears warped at the moment.
            //var position = ((IMyEntity)MyAPIGateway.Session.CameraController).GetPosition();
            //var worldMatrix = MyAPIGateway.Session.CameraController.GetViewMatrix();
            //var position = worldMatrix.Translation;
            //MyAPIGateway.Utilities.ShowMessage("Cam", string.Format("x={0:N},y={1:N},z={2:N}  x={3:N},y={4:N},z={5:N}", position.X, position.Y, position.Z, worldMatrix.Forward.X, worldMatrix.Forward.Y, worldMatrix.Forward.Z));

            var entites = new HashSet<IMyEntity>();
            MyAPIGateway.Entities.GetEntities(entites, e => e != null);

            var list = new Dictionary<IMyEntity, double>();
            var ray = new RayD(startPosition, worldMatrix.Forward);

            foreach (var entity in entites)
            {
                if (findShips || findCubes)
                {
                    var cubeGrid = entity as Sandbox.ModAPI.IMyCubeGrid;

                    if (cubeGrid != null)
                    {
                        if (ignoreOccupiedGrid && occupiedGrid != null && occupiedGrid.EntityId == cubeGrid.EntityId)
                            continue;

                        // TODO: ignore construction. New cube, new ship, new station, new paste.
                        //if (ignoreConstruction && (MyAPIGateway.CubeBuilder.BlockCreationIsActivated || MyAPIGateway.CubeBuilder.ShipCreationIsActivated || MyAPIGateway.CubeBuilder.CopyPasteIsActivated))
                        //    continue;

                        // Will ignore Projected grids, new grid/cube placement, and grids in middle of copy/paste.
                        // TODO: need a better way of determining projection other than Physics, as constructions have no physics either..
                        if (ignoreProjection && cubeGrid.Physics == null)
                            continue;

                        // check if the ray comes anywhere near the Grid before continuing.    
                        if (ray.Intersects(entity.WorldAABB).HasValue)
                        {
                            var hit = cubeGrid.RayCastBlocks(startPosition, endPosition);
                            if (hit.HasValue)
                            {
                                var distance = (startPosition - cubeGrid.GridIntegerToWorld(hit.Value)).Length();
                                var block = cubeGrid.GetCubeBlock(hit.Value);

                                if (block.FatBlock != null && findCubes)
                                    list.Add(block.FatBlock, distance);
                                else if (findShips)
                                    list.Add(entity, distance);
                            }
                        }
                    }
                }

                if (findPlayers)
                {
                    var controller = entity as IMyControllableEntity;
                    if (controlledEntity.Entity.EntityId != entity.EntityId && controller != null && ray.Intersects(entity.WorldAABB).HasValue)
                    {
                        var distance = (startPosition - entity.GetPosition()).Length();
                        list.Add(entity, distance);
                    }
                }

                if (findReplicable)
                {
                    var replicable = entity as Sandbox.Game.Entities.MyInventoryBagEntity;
                    if (replicable != null && ray.Intersects(entity.WorldAABB).HasValue)
                    {
                        var distance = (startPosition - entity.GetPosition()).Length();
                        list.Add(entity, distance);
                    }
                }

                if (findAsteroids)
                {
                    var voxelMap = entity as IMyVoxelMap;
                    if (voxelMap != null)
                    {
                        var aabb = new BoundingBoxD(voxelMap.PositionLeftBottomCorner, voxelMap.PositionLeftBottomCorner + voxelMap.Storage.Size);
                        var hit = ray.Intersects(aabb);
                        if (hit.HasValue)
                        {
                            Vector3D? hitIngoing;
                            Vector3D? hitOutgoing;

                            // May not be asteroid that is blocking ray, so am doing additional checks. It's still not reliable.
                            if (voxelMap.WorldAABB.IntersectPoints(startPosition, endPosition, out hitIngoing, out hitOutgoing)
                                && Sandbox.Game.Entities.MyEntities.IsRaycastBlocked(hitIngoing.Value, hitOutgoing.Value))
                            {
                                Vector3 lastOutsidePos;
                                // TODO: IsInsideVoxel doesn't appear to be reliable. Need to find an improved method.

                                //List<Sandbox.Engine.Physics.MyPhysics.HitInfo> m_hits = new List<Sandbox.Engine.Physics.MyPhysics.HitInfo>();
                                //Sandbox.Engine.Physics.MyPhysics.CastRay(startPosition, endPosition, m_hits, 0);   // MyPhysics is not whitelisted.

                                if (Sandbox.Game.Entities.MyEntities.IsInsideVoxel(startPosition, endPosition, out lastOutsidePos))
                                {
                                    list.Add(entity, Vector3D.Distance(startPosition, lastOutsidePos));
                                    //MyAPIGateway.Utilities.ShowMessage("Range", "CheckA");
                                }
                                else
                                {
                                    var center = voxelMap.PositionLeftBottomCorner + (voxelMap.Storage.Size / 2);
                                    // use distance to center of asteroid as an approximation.
                                    //MyAPIGateway.Utilities.ShowMessage("Range", "CheckB");
                                    list.Add(entity, Vector3D.Distance(startPosition, center));
                                }
                            }
                        }
                    }
                }

                if (findPlanets)
                {
                    // Looks to be working against Git and public release.
                    var planet = entity as Sandbox.Game.Entities.MyPlanet;
                    if (planet != null)
                    {
                        var aabb = new BoundingBoxD(planet.PositionLeftBottomCorner, planet.PositionLeftBottomCorner + planet.Size);
                        var hit = ray.Intersects(aabb);
                        if (hit.HasValue)
                        {
                            var center = planet.WorldMatrix.Translation;
                            var distance = (startPosition - center).Length(); // use distance to center of planet.
                            list.Add(entity, distance);
                        }
                    }
                }
            }

            if (list.Count == 0)
            {
                lookEntity = null;
                lookDistance = 0;
                hitPoint = Vector3D.Zero;
                return;
            }

            // find the closest Entity.
            var item = list.OrderBy(f => f.Value).First();
            lookEntity = item.Key;
            lookDistance = item.Value;
            hitPoint = startPosition + (Vector3D.Normalize(ray.Direction) * lookDistance);
        }
        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();
        }
예제 #24
0
        public static void FindLookAtEntity(IMyControllableEntity controlledEntity, bool ignoreOccupiedGrid, bool ignoreProjection, out IMyEntity lookEntity, out double lookDistance, out Vector3D hitPoint, bool findShips, bool findCubes, bool findPlayers, bool findAsteroids, bool findPlanets, bool findReplicable)
        {
            const float range = 5000000;
            Matrix worldMatrix;
            Vector3D startPosition;
            Vector3D endPosition;
            IMyCubeGrid occupiedGrid = null;

            if (controlledEntity.Entity.Parent == null)
            {
                worldMatrix = controlledEntity.GetHeadMatrix(true, true, false); // dead center of player cross hairs, or the direction the player is looking with ALT.
                startPosition = worldMatrix.Translation + worldMatrix.Forward * 0.5f;
                endPosition = worldMatrix.Translation + worldMatrix.Forward * (range + 0.5f);
            }
            else
            {
                occupiedGrid = controlledEntity.Entity.GetTopMostParent() as IMyCubeGrid;
                worldMatrix = controlledEntity.Entity.WorldMatrix;
                // TODO: need to adjust for position of cockpit within ship.
                startPosition = worldMatrix.Translation + worldMatrix.Forward * 1.5f;
                endPosition = worldMatrix.Translation + worldMatrix.Forward * (range + 1.5f);
            }

            var entites = new HashSet<IMyEntity>();
            MyAPIGateway.Entities.GetEntities(entites, e => e != null);

            var list = new Dictionary<IMyEntity, double>();
            var ray = new RayD(startPosition, worldMatrix.Forward);

            foreach (var entity in entites)
            {
                if (findShips || findCubes)
                {
                    var cubeGrid = entity as IMyCubeGrid;

                    if (cubeGrid != null)
                    {
                        if (ignoreOccupiedGrid && occupiedGrid != null && occupiedGrid.EntityId == cubeGrid.EntityId)
                            continue;

                        // Will ignore Projected grids, new grid/cube placement, and grids in middle of copy/paste.
                        if (ignoreProjection && cubeGrid.Physics == null)
                            continue;

                        // check if the ray comes anywhere near the Grid before continuing.
                        if (ray.Intersects(entity.WorldAABB).HasValue)
                        {
                            var hit = cubeGrid.RayCastBlocks(startPosition, endPosition);
                            if (hit.HasValue)
                            {
                                var distance = (startPosition - cubeGrid.GridIntegerToWorld(hit.Value)).Length();
                                var block = cubeGrid.GetCubeBlock(hit.Value);

                                if (block.FatBlock != null && findCubes)
                                    list.Add(block.FatBlock, distance);
                                else if (findShips)
                                    list.Add(entity, distance);
                            }
                        }
                    }
                }

                if (findPlayers)
                {
                    var controller = entity as IMyControllableEntity;
                    if (controlledEntity.Entity.EntityId != entity.EntityId && controller != null && ray.Intersects(entity.WorldAABB).HasValue)
                    {
                        var distance = (startPosition - entity.GetPosition()).Length();
                        list.Add(entity, distance);
                    }
                }

                if (findReplicable)
                {
                    var replicable = entity as Sandbox.Game.Entities.MyInventoryBagEntity;
                    if (replicable != null && ray.Intersects(entity.WorldAABB).HasValue)
                    {
                        var distance = (startPosition - entity.GetPosition()).Length();
                        list.Add(entity, distance);
                    }
                }

                if (findAsteroids)
                {
                    var voxelMap = entity as IMyVoxelMap;
                    if (voxelMap != null)
                    {
                        var aabb = new BoundingBoxD(voxelMap.PositionLeftBottomCorner, voxelMap.PositionLeftBottomCorner + voxelMap.Storage.Size);
                        var hit = ray.Intersects(aabb);
                        if (hit.HasValue)
                        {
                            var center = voxelMap.PositionLeftBottomCorner + (voxelMap.Storage.Size / 2);
                            var distance = (startPosition - center).Length();  // use distance to center of asteroid.
                            list.Add(entity, distance);
                        }
                    }
                }

                if (findPlanets)
                {
                    // Looks to be working against Git and public release.
                    var planet = entity as Sandbox.Game.Entities.MyPlanet;
                    if (planet != null)
                    {
                        var aabb = new BoundingBoxD(planet.PositionLeftBottomCorner, planet.PositionLeftBottomCorner + planet.Size);
                        var hit = ray.Intersects(aabb);
                        if (hit.HasValue)
                        {
                            var center = planet.WorldMatrix.Translation;
                            var distance = (startPosition - center).Length(); // use distance to center of planet.
                            list.Add(entity, distance);
                        }
                    }
                }
            }

            if (list.Count == 0)
            {
                lookEntity = null;
                lookDistance = 0;
                hitPoint = Vector3D.Zero;
                return;
            }

            // find the closest Entity.
            var item = list.OrderBy(f => f.Value).First();
            lookEntity = item.Key;
            lookDistance = item.Value;
            hitPoint = startPosition + (Vector3D.Normalize(ray.Direction) * lookDistance);
        }