private bool CheckIfEntityRelevant(HaE_Entity entity, Vector3D currentHeading)
            {
                if (entity.entityInfo.EntityId == rc.CubeGrid.EntityId)
                {
                    return(false);
                }

                if (entity.BoundingSphere.Radius <= 0)
                {
                    return(false);
                }

                Vector3D movementDir = rc.GetShipVelocities().LinearVelocity;

                movementDir.Normalize();

                RayD movementRay = new RayD(rc.CubeGrid.WorldVolume.Center, movementDir);
                RayD headingRay  = new RayD(rc.CubeGrid.WorldVolume.Center, currentHeading);

                BoundingSphereD sphere = entity.BoundingSphere;

                sphere.Radius += rc.CubeGrid.WorldVolume.Radius;

                double?intersectVel     = sphere.Intersects(movementRay);
                double?intersectHeading = sphere.Intersects(headingRay);

                return(intersectVel.HasValue || intersectHeading.HasValue);
            }
示例#2
0
        /// <summary>
        /// <para>Uses IMyEntities.GetEntities to get entities in Sphere</para>
        /// <para>Always use over GetEntitiesInSphere_Safe() when blocks are not needed, much faster.</para>
        /// </summary>
        /// <param name="preCollect">applied before intersection test</param>
        public static void GetEntitiesInSphere_Safe_NoBlock(this IMyEntities entitiesObject, BoundingSphereD boundingSphere, HashSet <IMyEntity> entities, Func <IMyEntity, bool> preCollect = null)
        {
            Func <IMyEntity, bool> collector;

            if (preCollect == null)
            {
                collector = (entity) => boundingSphere.Intersects(entity.WorldAABB);
            }
            else
            {
                collector = (entity) => { return(preCollect(entity) && boundingSphere.Intersects(entity.WorldAABB)); }
            };
            entitiesObject.GetEntities_Safe(entities, collector);
        }
示例#3
0
        /// <summary>
        /// Check intersection between line and bounding sphere
        /// We don't use BoundingSphere.Contains(Ray ...) because ray doesn't have an end, but line does, so we need
        /// to check if line really intersects the sphere.
        /// </summary>
        public static bool IsLineIntersectingBoundingSphere(ref LineD line, ref BoundingSphereD boundingSphere)
        {
            //  Create temporary ray and do intersection. But we can't rely only on it, because ray doesn't have end, yet our line does, so we
            //  need to check if ray-bounding_sphere intersection lies in the range of our line
            VRageMath.RayD ray = new VRageMath.RayD(line.From, line.Direction);
            double?        intersectionDistance = boundingSphere.Intersects(ray);

            if (intersectionDistance.HasValue == false)
            {
                //  No intersection between ray/line and bounding sphere
                return(false);
            }
            else
            {
                if (intersectionDistance.Value <= line.Length)
                {
                    //  Intersection between ray/line and bounding sphere IS withing the range of the line
                    return(true);
                }
                else
                {
                    //  Intersection between ray/line and bounding sphere IS NOT withing the range of the line
                    return(false);
                }
            }
        }
            public void NextPosition(ref Vector3D nextDirection, Vector3D headingDir, double safetyMargin = 1.25)
            {
                CreateSphereFromEntities(headingDir);

                Vector3D position    = rc.CubeGrid.WorldVolume.Center;
                Vector3D movementDir = rc.GetShipVelocities().LinearVelocity;

                movementDir.Normalize();

                RayD movementRay = new RayD(position, movementDir);
                RayD headingRay  = new RayD(rc.CubeGrid.WorldVolume.Center, headingDir);

                BoundingSphereD sphere = boundingSphere;

                sphere.Radius += rc.CubeGrid.WorldVolume.Radius;

                if (sphere.Contains(position) != ContainmentType.Disjoint)
                {
                    Vector3D dodgeDirection = Vector3D.Normalize(position - sphere.Center);

                    nextDirection = sphere.Center + dodgeDirection * sphere.Radius * safetyMargin;
                    return;
                }

                double?movementDist = sphere.Intersects(movementRay);
                double?headingDist  = sphere.Intersects(headingRay);

                if (movementDist.HasValue || headingDist.HasValue)
                {
                    Vector3D pointOnSphere;
                    Vector3D dodgeDirection;
                    if (movementDist.HasValue)
                    {
                        pointOnSphere  = position + movementDir * movementDist.Value;
                        dodgeDirection = GetAvoidanceVector(pointOnSphere, sphere, movementDir);
                    }
                    else
                    {
                        pointOnSphere  = position + headingDir * headingDist.Value;
                        dodgeDirection = GetAvoidanceVector(pointOnSphere, sphere, headingDir);
                    }

                    nextDirection = dodgeDirection;
                }
            }
            private double?CollisionDistance(ref MyDetectedEntityInfo e, ref BoundingSphereD volume, ref Vector3D myVel)
            {
                BoundingSphereD sphere = new BoundingSphereD(e.Position, e.BoundingBox.Size.Length() / 2 + volume.Radius + Clearance);
                Vector3D        vel    = myVel + e.Velocity;

                vel.Normalize();
                RayD ray = new RayD(ref volume.Center, ref vel);

                return(sphere.Intersects(ray));
            }
        //Method From DarkStar for Detecting Sphere Intersections in Defense Shield
        public static Vector3D?DsRayCast(IMyEntity shield, LineD line, long attackerId, float damage, MyStringId effect)
        {
            var worldSphere = new BoundingSphereD(shield.PositionComp.WorldVolume.Center, shield.PositionComp.LocalAABB.HalfExtents.AbsMax());
            var myObb       = MyOrientedBoundingBoxD.Create(shield.PositionComp.LocalAABB, shield.PositionComp.WorldMatrix.GetOrientation());

            myObb.Center = shield.PositionComp.WorldVolume.Center;
            var obbCheck = myObb.Intersects(ref line);

            var testDir = line.From - line.To;

            testDir.Normalize();
            var ray         = new RayD(line.From, -testDir);
            var sphereCheck = worldSphere.Intersects(ray);

            var    obb    = obbCheck ?? 0;
            var    sphere = sphereCheck ?? 0;
            double furthestHit;

            if (obb <= 0 && sphere <= 0)
            {
                furthestHit = 0;
            }
            else if (obb > sphere)
            {
                furthestHit = obb;
            }
            else
            {
                furthestHit = sphere;
            }
            var hitPos = line.From + testDir * -furthestHit;

            /*
             * var parent = MyAPIGateway.Entities.GetEntityById(long.Parse(shield.Name));
             * var cubeBlock = (MyCubeBlock)parent;
             * var block = (IMySlimBlock)cubeBlock.SlimBlock;
             *
             * if(block == null){
             *
             *      return null;
             *
             * }
             *
             * block.DoDamage(damage, MyStringHash.GetOrCompute(effect.ToString()), true, null, attackerId);
             * shield.Render.ColorMaskHsv = hitPos;
             *
             * if(effect.ToString() == "bypass"){
             *
             *      return null;
             *
             * }
             */
            return(hitPos);
        }
        public static void AddKnownPlayerLocation(Vector3D coords, string faction, double radius, int duration = -1, int maxEncounters = -1, int minThreatToAvoidAbandonment = -1)
        {
            bool foundExistingLocation = false;
            var  sphere = new BoundingSphereD(coords, radius);
            List <KnownPlayerLocation> intersectingLocations = new List <KnownPlayerLocation>();

            foreach (var location in Locations)
            {
                if (location.NpcFaction != faction)
                {
                    continue;
                }

                if (!sphere.Intersects(location.Sphere) && location.Sphere.Contains(coords) == ContainmentType.Disjoint)
                {
                    continue;
                }

                intersectingLocations.Add(location);
                foundExistingLocation = true;
            }

            if (foundExistingLocation == false)
            {
                Logger.AddMsg("Creating KnownPlayerLocation at " + coords.ToString() + " / Radius: " + radius.ToString(), true);
                Locations.Add(new KnownPlayerLocation(faction, coords, radius, duration, maxEncounters, minThreatToAvoidAbandonment));
                AlertPlayersOfNewKPL(coords, radius, faction);
            }
            else
            {
                var currentLocation = new KnownPlayerLocation(faction, coords, radius, duration, maxEncounters, minThreatToAvoidAbandonment);

                foreach (var location in intersectingLocations)
                {
                    var dirFromCurrentToIntersection = Vector3D.Normalize(location.Coords - currentLocation.Coords);
                    var coordsBetweenCenters         = dirFromCurrentToIntersection * (Vector3D.Distance(location.Coords, currentLocation.Coords) / 2) + currentLocation.Coords;
                    var radiusToUse    = location.Radius == currentLocation.Radius ? currentLocation.Radius : currentLocation.Radius > location.Radius ? currentLocation.Radius : location.Radius;
                    var outerRimCoords = -dirFromCurrentToIntersection * radiusToUse + currentLocation.Coords;
                    var finalRadius    = Vector3D.Distance(outerRimCoords, coordsBetweenCenters);
                    currentLocation = new KnownPlayerLocation(faction, coordsBetweenCenters, finalRadius, duration, maxEncounters, minThreatToAvoidAbandonment);
                    Locations.Remove(location);
                }

                Locations.Add(currentLocation);
                AlertPlayersOfNewKPL(coords, radius, faction);
                Logger.AddMsg("Known Player Location(s) Already Exist, Merging Locations.", true);
            }

            SaveLocations();
        }
        public bool Contains(IMyEntity entity)
        {
            switch (Shape)
            {
                case ProtectionAreaShape.Cube:
                    var boundingBox = new BoundingBoxD(new Vector3D(Center.X - Size, Center.Y - Size, Center.Z - Size), new Vector3D(Center.X + Size, Center.Y + Size, Center.Z + Size));
                    return boundingBox.Intersects(entity.WorldAABB);
                case ProtectionAreaShape.Sphere:
                    var boundingSphere = new BoundingSphereD(Center, Size);
                    return boundingSphere.Intersects(entity.WorldAABB);
            }

            return false;
        }
        public bool Contains(BoundingBoxD boundingbox)
        {
            switch (Shape)
            {
            case ProtectionAreaShape.Cube:
                var boundingBox = new BoundingBoxD(Center - Size, Center + Size);
                return(boundingBox.Intersects(boundingbox));

            case ProtectionAreaShape.Sphere:
                var boundingSphere = new BoundingSphereD(Center, Size);
                return(boundingSphere.Intersects(boundingbox));
            }

            return(false);
        }
示例#10
0
        public bool Contains(IMyEntity entity)
        {
            switch (Shape)
            {
            case ProtectionAreaShape.Cube:
                var boundingBox = new BoundingBoxD(new Vector3D(Center.X - Size, Center.Y - Size, Center.Z - Size), new Vector3D(Center.X + Size, Center.Y + Size, Center.Z + Size));
                return(boundingBox.Intersects(entity.WorldAABB));

            case ProtectionAreaShape.Sphere:
                var boundingSphere = new BoundingSphereD(Center, Size);
                return(boundingSphere.Intersects(entity.WorldAABB));
            }

            return(false);
        }
        private void BroadcastDamageMessage(IMyTerminalBlock _b)
        {
            if (_b == null)
            {
                return;
            }
            List <IMyPlayer> players = new List <IMyPlayer>();

            MyAPIGateway.Players.GetPlayers(players);
            if (players != null)
            {
                var sphere      = new BoundingSphereD(_b.PositionComp.WorldAABB.Center, 250);
                var sendMessage = false;
                foreach (var player in players)
                {
                    if (player != null && player.IdentityId != MyAPIGateway.Session.Player.IdentityId)
                    {
                        continue;
                    }
                    if (player != null && !sphere.Intersects(player.Character.WorldVolume))
                    {
                        continue;
                    }
                    sendMessage = true;
                    break;
                }

                if (sendMessage)
                {
                    if (!MessageSent)
                    {
                        MyAPIGateway.Utilities.ShowNotification("Beacon Tampering Detected: Power System Damaged.", 9600, "Red");
                        MessageSent = true;
                    }
                }
                else
                {
                    //MyAPIGateway.Utilities.ShowNotification("Player NO.", 9600, "Red");
                }
            }
        }
        private void BroadcastSpamMessage(IMyTerminalBlock _b)
        {
            if (_b == null)
            {
                return;
            }
            List <IMyPlayer> players = new List <IMyPlayer>();

            MyAPIGateway.Players.GetPlayers(players);
            if (players != null)
            {
                var sphere      = new BoundingSphereD(_b.PositionComp.WorldAABB.Center, 500);
                var sendMessage = false;
                foreach (var player in players)
                {
                    if (player != null && player.IdentityId != MyAPIGateway.Session.Player.IdentityId)
                    {
                        continue;
                    }
                    if (player != null && !sphere.Intersects(player.Character.WorldVolume))
                    {
                        continue;
                    }
                    sendMessage = true;
                    break;
                }

                if (sendMessage)
                {
                    if (!SpamMessageSent)
                    {
                        MyAPIGateway.Utilities.ShowNotification("Coolant System Overloaded: Too many Heat Sinks on " + _b.CubeGrid.DisplayName.ToString(), 9600, "Red");
                        SpamMessageSent = true;
                    }
                }
                else
                {
                    //MyAPIGateway.Utilities.ShowNotification("Player NO.", 9600, "Red");
                }
            }
        }
示例#13
0
        private void BroadCastLosMessage(int blocked, int needed, DefenseShields controller)
        {
            var sphere      = new BoundingSphereD(Emitter.PositionComp.WorldAABB.Center, 1500);
            var sendMessage = false;

            foreach (var player in Session.Instance.Players.Values)
            {
                if (player.IdentityId != MyAPIGateway.Session.Player.IdentityId)
                {
                    continue;
                }
                if (!sphere.Intersects(player.Character.WorldVolume))
                {
                    continue;
                }
                sendMessage = true;
                break;
            }

            if (sendMessage)
            {
                var sighted = _vertsSighted.Count;
                if (needed > 0)
                {
                    needed = 0;
                }

                MyAPIGateway.Utilities.ShowNotification("The shield emitter DOES NOT have a CLEAR ENOUGH LINE OF SIGHT to the shield, SHUTTING DOWN.", 960, "Red");
                MyAPIGateway.Utilities.ShowNotification($"Green means clear line of sight, Flashing Orange means blocked | Blocked: {blocked} | Clear: {sighted} | Needed (Approximate): {needed}", 960, "Red");
                if (needed == 0 && controller.LosCheckTick != uint.MaxValue)
                {
                    MyAPIGateway.Utilities.ShowNotification($"Needed is only an approximation, if shield does not start in 30 seconds or is unstable, then it is not clear.", 960, "White");
                }
                else if (needed == 0 && _lCount % 2 == 1)
                {
                    MyAPIGateway.Utilities.ShowNotification($"Shield is still not clear!", 960, "White");
                }
            }
        }
示例#14
0
        public static float?IntersectEllipsoid(MatrixD ellipsoidMatrixInv, MatrixD ellipsoidMatrix, RayD ray)
        {
            var _normSphere = new BoundingSphereD(Vector3.Zero, 1f);
            var _kRay       = new RayD(Vector3D.Zero, Vector3D.Forward);

            var krayPos = Vector3D.Transform(ray.Position, ellipsoidMatrixInv);
            var krayDir = Vector3D.Normalize(Vector3D.TransformNormal(ray.Direction, ellipsoidMatrixInv));

            _kRay.Direction = krayDir;
            _kRay.Position  = krayPos;
            var nullDist = _normSphere.Intersects(_kRay);

            if (!nullDist.HasValue)
            {
                return(null);
            }

            var hitPos      = krayPos + (krayDir * -nullDist.Value);
            var worldHitPos = Vector3D.Transform(hitPos, ellipsoidMatrix);

            return(Vector3.Distance(worldHitPos, ray.Position));
        }
示例#15
0
        bool GetTargetCharacter(Vector3D rayFrom, Vector3D rayDir, double rayLength, IMyCharacter character, ref IMyPlayer targetPlayer)
        {
            List <IMyPlayer> players = Main.Caches.Players.Get();

            MyAPIGateway.Players.GetPlayers(players);

            RayD ray = new RayD(rayFrom, rayDir);

            foreach (IMyPlayer p in players)
            {
                IMyCharacter c = p.Character;
                if (c == null || c == character)
                {
                    continue;
                }

                BoundingSphereD sphere = Utils.GetCharacterSelectionSphere(c);
                if (Vector3D.DistanceSquared(rayFrom, sphere.Center) > (rayLength * rayLength))
                {
                    continue;
                }

                double?dist = sphere.Intersects(ray);
                if (!dist.HasValue || dist.Value > rayLength)
                {
                    continue;
                }

                targetPlayer = p;
                break;
            }

            Main.Caches.Players.Return(players);

            return(targetPlayer != null);
        }
示例#16
0
        internal static double?IntersectEllipsoid(MatrixD ellipsoidMatrixInv, MatrixD ellipsoidMatrix, RayD ray)
        {
            var normSphere = new BoundingSphereD(Vector3.Zero, 1f);
            var kRay       = new RayD(Vector3D.Zero, Vector3D.Forward);

            Vector3D krayPos;

            Vector3D.Transform(ref ray.Position, ref ellipsoidMatrixInv, out krayPos);

            Vector3D nDir;

            Vector3D.TransformNormal(ref ray.Direction, ref ellipsoidMatrixInv, out nDir);

            Vector3D krayDir;

            Vector3D.Normalize(ref nDir, out krayDir);

            kRay.Direction = krayDir;
            kRay.Position  = krayPos;
            var nullDist = normSphere.Intersects(kRay);

            if (!nullDist.HasValue)
            {
                return(null);
            }

            var      hitPos = krayPos + (krayDir * -nullDist.Value);
            Vector3D worldHitPos;

            Vector3D.Transform(ref hitPos, ref ellipsoidMatrix, out worldHitPos);

            double dist;

            Vector3D.Distance(ref worldHitPos, ref ray.Position, out dist);
            return(double.IsNaN(dist) ? (double?)null : dist);
        }
示例#17
0
        public override IEnumerable <ProceduralObject> Generate(BoundingSphereD include, BoundingSphereD?exclude)
        {
            var aabb = new BoundingBoxD(include.Center - include.Radius, include.Center + include.Radius);

            foreach (var cell in StationNoise.TryGetSpawnIn(aabb, (x) => include.Intersects(x) && (!exclude.HasValue || exclude.Value.Contains(x) != ContainmentType.Contains)))
            {
                LoadingConstruction instance;
                if (!m_instances.TryGetValue(cell.Item1, out instance))
                {
                    var numSeed = cell.Item1.GetHashCode();
                    Ob_ProceduralConstructionSeed dbSeed;
                    Ob_ProceduralConstruction     dbBlueprint;
                    Ob_ProceduralFaction          dbFaction;

                    ProceduralConstructionSeed seed;
                    if (m_database.TryGetBuildingBlueprint(numSeed, out dbSeed, out dbBlueprint) && dbSeed != null &&
                        m_database.TryGetFaction(dbSeed.FactionSeed, out dbFaction) && dbFaction != null)
                    {
                        seed = new ProceduralConstructionSeed(new ProceduralFactionSeed(dbFaction), cell.Item2.XYZ(), dbSeed);
                    }
                    else
                    {
                        seed = new ProceduralConstructionSeed(Factions.SeedAt(cell.Item2.XYZ()), cell.Item2, null,
                                                              numSeed);
                    }
                    instance = m_instances[cell.Item1] = new LoadingConstruction(this, cell.Item1,
                                                                                 seed);
                }
                else if (!instance.IsMarkedForRemoval)
                {
                    continue; // Already loaded + not marked for removal -- already in the tree.
                }
                instance.EnsureGenerationStarted();
                yield return(instance);
            }
        }
示例#18
0
        public bool Drill(bool collectOre = true, bool performCutout = true)
        {
            ProfilerShort.Begin("MyDrillBase::Drill()");

            bool drillingSuccess = false;

            MySoundPair sound = null;

            if ((m_drillEntity.Parent != null) && (m_drillEntity.Parent.Physics != null) && !m_drillEntity.Parent.Physics.Enabled)
            {
                return(false);
            }

            if (performCutout)
            {
                var entitiesInRange = m_sensor.EntitiesInRange;
                foreach (var entry in entitiesInRange)
                {
                    drillingSuccess = false;
                    var entity = entry.Value.Entity;
                    if (entity.MarkedForClose)
                    {
                        continue;
                    }
                    if (entity is MyCubeGrid)
                    {
                        var grid = entity as MyCubeGrid;
                        if (grid.Physics != null && grid.Physics.Enabled)
                        {
                            drillingSuccess = TryDrillBlocks(grid, entry.Value.DetectionPoint, !Sync.IsServer);
                        }
                        if (drillingSuccess)
                        {
                            m_initialHeatup = false;
                            sound           = m_sounds.MetalLoop;
                            CreateParticles(entry.Value.DetectionPoint, false, true, false);
                        }
                    }
                    else if (entity is MyVoxelBase)
                    {
                        ProfilerShort.Begin("Drill voxel map");
                        var voxels = entity as MyVoxelBase;
                        drillingSuccess = TryDrillVoxels(voxels, entry.Value.DetectionPoint, collectOre, !Sync.IsServer);
                        ProfilerShort.BeginNextBlock("Create particles");
                        if (drillingSuccess)
                        {
                            sound = m_sounds.RockLoop;
                            CreateParticles(entry.Value.DetectionPoint, true, false, true);
                        }
                        ProfilerShort.End();
                    }
                    else if (entity is MyFloatingObject)
                    {
                        var sphere = (BoundingSphereD)m_cutOut.Sphere;
                        sphere.Radius *= 1.33f;
                        if (entity.GetIntersectionWithSphere(ref sphere))
                        {
                            MyFloatingObject flObj = entity as MyFloatingObject;
                            if (Sync.IsServer)
                            {
                                if (flObj.Item.Content.TypeId == typeof(MyObjectBuilder_Ore))
                                {
                                    IMyInventoryOwner invOwn = m_drillEntity as IMyInventoryOwner;
                                    if (invOwn == null)
                                    {
                                        invOwn = (m_drillEntity as MyHandDrill).Owner as IMyInventoryOwner;
                                    }
                                    invOwn.GetInventory(0).TakeFloatingObject(flObj);
                                }
                                else
                                {
                                    (entity as MyFloatingObject).DoDamage(70, MyDamageType.Drill, true, attackerId: m_drillEntity != null ? m_drillEntity.EntityId : 0);
                                }
                            }
                            drillingSuccess = true;
                        }
                    }
                    else if (entity is MyCharacter)
                    {
                        var sphere = (BoundingSphereD)m_cutOut.Sphere;
                        sphere.Radius *= (4 / 5f);
                        var character = entity as MyCharacter;
                        if (entity.GetIntersectionWithSphere(ref sphere))
                        {
                            //MyRenderProxy.DebugDrawSphere(sphere.Center, sphere.Radius, Color.Green.ToVector3(), 1, true);
                            if (Sync.IsServer)
                            {
                                character.DoDamage(20, MyDamageType.Drill, true, attackerId: m_drillEntity != null ? m_drillEntity.EntityId : 0);
                            }
                            drillingSuccess = true;
                        }
                        else
                        {
                            BoundingSphereD headSphere = new BoundingSphereD(character.PositionComp.WorldMatrix.Translation + character.WorldMatrix.Up * 1.25f, 0.6f);
                            //MyRenderProxy.DebugDrawSphere(headSphere.Center, headSphere.Radius, Color.Red.ToVector3(), 1, false);
                            if (headSphere.Intersects(sphere))
                            {
                                //MyRenderProxy.DebugDrawSphere(sphere.Center, sphere.Radius, Color.Green.ToVector3(), 1, true);
                                if (Sync.IsServer)
                                {
                                    character.DoDamage(20, MyDamageType.Drill, true, attackerId: m_drillEntity != null ? m_drillEntity.EntityId : 0);
                                }
                                drillingSuccess = true;
                            }
                        }
                    }
                    if (drillingSuccess)
                    {
                        m_lastContactTime = MySandboxGame.TotalGamePlayTimeInMilliseconds;
                    }
                }
            }

            if (sound != null)
            {
                StartLoopSound(sound);
            }
            else
            {
                StartIdleSound(m_sounds.IdleLoop);
            }

            IsDrilling = true;

            m_animationLastUpdateTime = MySandboxGame.TotalGamePlayTimeInMilliseconds;
            ProfilerShort.End();
            return(drillingSuccess);
        }
示例#19
0
        private void PlayerMessages(PlayerNotice notice)
        {
            double radius;

            if (notice == PlayerNotice.EmpOverLoad || notice == PlayerNotice.OverLoad)
            {
                radius = 500;
            }
            else
            {
                radius = ShieldSphere.Radius * 2;
            }

            var       center       = GridIsMobile ? MyGrid.PositionComp.WorldVolume.Center : OffsetEmitterWMatrix.Translation;
            var       sphere       = new BoundingSphereD(center, radius);
            var       sendMessage  = false;
            IMyPlayer targetPlayer = null;

            foreach (var player in Session.Instance.Players.Values)
            {
                if (player.IdentityId != MyAPIGateway.Session.Player.IdentityId)
                {
                    continue;
                }
                if (!sphere.Intersects(player.Character.WorldVolume))
                {
                    continue;
                }
                var relation = MyAPIGateway.Session.Player.GetRelationTo(MyCube.OwnerId);
                if (relation == MyRelationsBetweenPlayerAndBlock.Neutral || relation == MyRelationsBetweenPlayerAndBlock.Enemies)
                {
                    continue;
                }
                sendMessage  = true;
                targetPlayer = player;
                break;
            }
            if (sendMessage && !DsSet.Settings.NoWarningSounds)
            {
                BroadcastSound(targetPlayer.Character, notice);
            }

            switch (notice)
            {
            case PlayerNotice.EmitterInit:
                if (sendMessage)
                {
                    MyAPIGateway.Utilities.ShowNotification("[ " + MyGrid.DisplayName + " ]" + " -- shield is reinitializing and checking LOS, attempting startup in 30 seconds!", 4816);
                }
                break;

            case PlayerNotice.FieldBlocked:
                if (sendMessage)
                {
                    MyAPIGateway.Utilities.ShowNotification("[ " + MyGrid.DisplayName + " ]" + "-- the shield's field cannot form when in contact with a solid body", 6720, "Blue");
                }
                break;

            case PlayerNotice.OverLoad:
                if (sendMessage)
                {
                    MyAPIGateway.Utilities.ShowNotification("[ " + MyGrid.DisplayName + " ]" + " -- shield has overloaded, restarting in 20 seconds!!", 8000, "Red");
                }
                break;

            case PlayerNotice.EmpOverLoad:
                if (sendMessage)
                {
                    MyAPIGateway.Utilities.ShowNotification("[ " + MyGrid.DisplayName + " ]" + " -- shield was EMPed, restarting in 60 seconds!!", 8000, "Red");
                }
                break;

            case PlayerNotice.Remodulate:
                if (sendMessage)
                {
                    MyAPIGateway.Utilities.ShowNotification("[ " + MyGrid.DisplayName + " ]" + " -- shield remodulating, restarting in 5 seconds.", 4800);
                }
                break;

            case PlayerNotice.NoLos:
                if (sendMessage)
                {
                    MyAPIGateway.Utilities.ShowNotification("[ " + MyGrid.DisplayName + " ]" + " -- Emitter does not have line of sight, shield offline", 8000, "Red");
                }
                break;

            case PlayerNotice.NoPower:
                if (sendMessage)
                {
                    MyAPIGateway.Utilities.ShowNotification("[ " + MyGrid.DisplayName + " ]" + " -- Insufficient Power, shield is failing!", 5000, "Red");
                }
                break;
            }
            if (Session.Enforced.Debug == 3)
            {
                Log.Line($"[PlayerMessages] Sending:{sendMessage} - rangeToClinetPlayer:{Vector3D.Distance(sphere.Center, MyAPIGateway.Session.Player.Character.WorldVolume.Center)}");
            }
        }
        /// <summary>
        /// Override this function to set custom update behaviour.
        /// Call base at first because it queries objects if DoQuery is set.
        /// </summary>
        protected virtual void UpdateInternal()
        {
            if (DoQuery)
            {
                m_queryResult.Clear();

                switch (m_triggerType)
                {
                case TriggerType.AABB:
                    MyGamePruningStructure.GetTopMostEntitiesInBox(ref m_AABB, m_queryResult);
                    break;

                case TriggerType.Sphere:
                    MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref m_boundingSphere, m_queryResult);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }


                for (int index = 0; index < m_queryResult.Count;)
                {
                    var result = m_queryResult[index];
                    if (!QueryEvaluator(result))
                    {
                        m_queryResult.RemoveAtFast(index);
                    }
                    else
                    {
                        switch (m_triggerType)
                        {
                        case TriggerType.AABB:
                            if (!m_AABB.Intersects(m_queryResult[index].PositionComp.WorldAABB))
                            {
                                m_queryResult.RemoveAtFast(index);
                            }
                            else
                            {
                                index++;
                            }
                            break;

                        case TriggerType.Sphere:
                            if (!m_boundingSphere.Intersects(m_queryResult[index].PositionComp.WorldAABB))
                            {
                                m_queryResult.RemoveAtFast(index);
                            }
                            else
                            {
                                index++;
                            }
                            break;

                        default:
                            index++;
                            break;
                        }
                    }
                }
            }
        }
示例#21
0
        public bool Drill(bool collectOre = true, bool performCutout = true)
        {
            ProfilerShort.Begin("MyDrillBase::Drill()");

            bool drillingSuccess = false;

            MySoundPair sound = null;

            if ((m_drillEntity.Parent != null) && (m_drillEntity.Parent.Physics != null) && !m_drillEntity.Parent.Physics.Enabled)
                return false;

            if (performCutout)
            {
                var entitiesInRange = m_sensor.EntitiesInRange;
                foreach (var entry in entitiesInRange)
                {
                    drillingSuccess = false;
                    var entity = entry.Value.Entity;
                    if (entity.MarkedForClose)
                        continue;
                    if (entity is MyCubeGrid)
                    {
                        var grid = entity as MyCubeGrid;
                        if (grid.Physics != null && grid.Physics.Enabled)
                        {
                            drillingSuccess = TryDrillBlocks(grid, entry.Value.DetectionPoint, !Sync.IsServer);
                        }
                        if (drillingSuccess)
                        {
                            m_initialHeatup = false;
                            sound = m_sounds.MetalLoop;
                            CreateParticles(entry.Value.DetectionPoint, false, true, false);
                        }
                    }
                    else if (entity is MyVoxelBase)
                    {
                        ProfilerShort.Begin("Drill voxel map");
                        var voxels = entity as MyVoxelBase;
                        drillingSuccess = TryDrillVoxels(voxels, entry.Value.DetectionPoint, collectOre, !Sync.IsServer);
                        ProfilerShort.BeginNextBlock("Create particles");
                        if (drillingSuccess)
                        {
                            sound = m_sounds.RockLoop;
                            CreateParticles(entry.Value.DetectionPoint, true, false, true);
                        }
                        ProfilerShort.End();
                    }
                    else if (entity is MyFloatingObject)
                    {
                        var sphere = (BoundingSphereD)m_cutOut.Sphere;
                        sphere.Radius *= 1.33f;
                        if (entity.GetIntersectionWithSphere(ref sphere))
                        {
                            MyFloatingObject flObj = entity as MyFloatingObject;
                            if (Sync.IsServer)
                            {
                                if (flObj.Item.Content.TypeId == typeof(MyObjectBuilder_Ore))
                                {
                                    IMyInventoryOwner invOwn = m_drillEntity as IMyInventoryOwner;
                                    if (invOwn == null)
                                        invOwn = (m_drillEntity as MyHandDrill).Owner as IMyInventoryOwner;
                                    invOwn.GetInventory(0).TakeFloatingObject(flObj);
                                }
                                else
                                    (entity as MyFloatingObject).DoDamage(70, MyDamageType.Drill, true);
                            }
                            drillingSuccess = true;
                        }
                    }
                    else if (entity is MyCharacter)
                    {
                        var sphere = (BoundingSphereD)m_cutOut.Sphere;
                        sphere.Radius *= (4 / 5f);
                        var character = entity as MyCharacter;
                        if (entity.GetIntersectionWithSphere(ref sphere))
                        {
                            //MyRenderProxy.DebugDrawSphere(sphere.Center, sphere.Radius, Color.Green.ToVector3(), 1, true);
                            if (Sync.IsServer)
                                character.DoDamage(20, MyDamageType.Drill, true);
                            drillingSuccess = true;
                        }
                        else
                        {
                            BoundingSphereD headSphere = new BoundingSphereD(character.PositionComp.WorldMatrix.Translation + character.WorldMatrix.Up * 1.25f, 0.6f);
                            //MyRenderProxy.DebugDrawSphere(headSphere.Center, headSphere.Radius, Color.Red.ToVector3(), 1, false);
                            if (headSphere.Intersects(sphere))
                            {
                                //MyRenderProxy.DebugDrawSphere(sphere.Center, sphere.Radius, Color.Green.ToVector3(), 1, true);
                                if (Sync.IsServer)
                                    character.DoDamage(20, MyDamageType.Drill, true);
                                drillingSuccess = true;
                            }
                        }
                    }
                    if (drillingSuccess)
                    {
                        m_lastContactTime = MySandboxGame.TotalGamePlayTimeInMilliseconds;
                    }
                }
            }

            if (sound != null)
                StartLoopSound(sound);
            else
                StartIdleSound(m_sounds.IdleLoop);

            IsDrilling = true;

            m_animationLastUpdateTime = MySandboxGame.TotalGamePlayTimeInMilliseconds;
            ProfilerShort.End();
            return drillingSuccess;
        }
示例#22
0
        internal bool GetAllEntitiesInLine(Projectile p, LineD beam)
        {
            var shieldByPass     = p.Info.AmmoDef.DamageScales.Shields.Type == ShieldDef.ShieldType.Bypass;
            var shieldFullBypass = shieldByPass && p.Info.AmmoDef.Const.ShieldBypassMod >= 1;
            var genericFields    = p.Info.EwarActive && (p.Info.AmmoDef.Const.AreaEffect == DotField || p.Info.AmmoDef.Const.AreaEffect == PushField || p.Info.AmmoDef.Const.AreaEffect == PullField);
            var ai         = p.Info.Ai;
            var found      = false;
            var lineCheck  = p.Info.AmmoDef.Const.CollisionIsLine && !p.Info.EwarActive && !p.Info.TriggeredPulse;
            var planetBeam = beam;

            planetBeam.To = p.Info.AmmoDef.Const.IsBeamWeapon && p.MaxTrajectory > 1500 ? beam.From + (beam.Direction * 1500) : beam.To;
            bool projetileInShield = false;

            for (int i = 0; i < p.SegmentList.Count; i++)
            {
                var ent         = p.SegmentList[i].Element;
                var grid        = ent as MyCubeGrid;
                var destroyable = ent as IMyDestroyableObject;
                var voxel       = ent as MyVoxelBase;
                if (ent is IMyCharacter && p.Info.EwarActive && !genericFields)
                {
                    continue;
                }
                if (grid != null && p.SmartsOn && p.Info.Ai.MyGrid.IsSameConstructAs(grid) || ent.MarkedForClose || !ent.InScene || ent == p.Info.Ai.MyShield)
                {
                    continue;
                }

                if (!shieldFullBypass && !p.ShieldBypassed || p.Info.EwarActive && (p.Info.AmmoDef.Const.AreaEffect == DotField && p.Info.AmmoDef.Const.AreaEffect == EmpField))
                {
                    var shieldInfo = p.Info.Ai.Session.SApi?.MatchEntToShieldFastExt(ent, true);
                    if (shieldInfo != null)
                    {
                        double?dist = null;
                        if (ent.Physics != null && ent.Physics.IsPhantom)
                        {
                            dist = MathFuncs.IntersectEllipsoid(shieldInfo.Value.Item3.Item1, shieldInfo.Value.Item3.Item2, new RayD(beam.From, 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 < beam.Length || p.Info.EwarActive) && !p.Info.Ai.MyGrid.IsSameConstructAs(shieldInfo.Value.Item1.CubeGrid))
                        {
                            var hitEntity = HitEntityPool.Get();
                            hitEntity.Clean();
                            hitEntity.Info = p.Info;
                            found          = true;
                            if (shieldByPass)
                            {
                                p.ShieldBypassed = true;
                            }
                            hitEntity.Entity       = (MyEntity)shieldInfo.Value.Item1;
                            hitEntity.Intersection = beam;
                            hitEntity.EventType    = Shield;
                            hitEntity.SphereCheck  = !lineCheck;
                            hitEntity.PruneSphere  = p.PruneSphere;
                            hitEntity.HitPos       = beam.From + (beam.Direction * dist.Value);
                            hitEntity.HitDist      = dist;

                            p.Info.HitList.Add(hitEntity);
                        }
                        else
                        {
                            continue;
                        }
                    }
                }

                if ((ent == ai.MyPlanet && (p.LinePlanetCheck || p.DynamicGuidance || p.CachedPlanetHit)) || ent.Physics != null && !ent.Physics.IsPhantom && !ent.IsPreview && (grid != null || voxel != null || destroyable != null))
                {
                    var extFrom = beam.From - (beam.Direction * (ent.PositionComp.WorldVolume.Radius * 2));
                    var extBeam = new LineD(extFrom, beam.To);

                    var rotMatrix = Quaternion.CreateFromRotationMatrix(ent.WorldMatrix);
                    var obb       = new MyOrientedBoundingBoxD(ent.PositionComp.WorldAABB.Center, ent.PositionComp.LocalAABB.HalfExtents, rotMatrix);
                    if (lineCheck && obb.Intersects(ref extBeam) == null || !lineCheck && !obb.Intersects(ref p.PruneSphere))
                    {
                        continue;
                    }
                    Vector3D?voxelHit = null;
                    if (voxel != null)
                    {
                        if (voxel.RootVoxel != voxel)
                        {
                            continue;
                        }
                        if (voxel == ai.MyPlanet)
                        {
                            if (p.CachedPlanetHit)
                            {
                                IHitInfo cachedPlanetResult;
                                if (p.Info.WeaponCache.VoxelHits[p.CachedId].NewResult(out cachedPlanetResult))
                                {
                                    voxelHit = cachedPlanetResult.Position;
                                }
                                else
                                {
                                    continue;
                                }
                            }

                            if (p.LinePlanetCheck)
                            {
                                var    check        = false;
                                var    surfacePos   = ai.MyPlanet.GetClosestSurfacePointGlobal(ref p.Position);
                                var    planetCenter = ai.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 <= (planetBeam.Length * planetBeam.Length) || endPointToCenter > startPointToCenter && prevEndPointToCenter > p.DistanceToTravelSqr || surfaceToCenter > Vector3D.DistanceSquared(planetCenter, p.LastPosition))
                                {
                                    check = true;
                                }
                                if (check)
                                {
                                    using (voxel.Pin())
                                        voxel.GetIntersectionWithLine(ref planetBeam, out voxelHit);
                                }
                            }
                        }
                        else
                        {
                            using (voxel.Pin())
                                voxel.GetIntersectionWithLine(ref beam, out voxelHit);
                        }

                        if (!voxelHit.HasValue)
                        {
                            continue;
                        }
                    }
                    var hitEntity = HitEntityPool.Get();
                    hitEntity.Clean();
                    hitEntity.Info         = p.Info;
                    hitEntity.Entity       = ent;
                    hitEntity.Intersection = beam;
                    hitEntity.SphereCheck  = !lineCheck;
                    hitEntity.PruneSphere  = p.PruneSphere;

                    if (voxelHit != null)
                    {
                        var hitPos = voxelHit.Value;
                        hitEntity.HitPos = hitPos;

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

                    if (grid != null)
                    {
                        if (!p.Info.AmmoDef.Const.IsBeamWeapon && beam.Length <= grid.GridSize * 2 && grid.IsSameConstructAs(p.Info.Target.FiringCube.CubeGrid))
                        {
                            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))
                            {
                                continue;
                            }
                        }
                        if (!(p.Info.EwarActive && p.Info.AmmoDef.Const.EwarEffect))
                        {
                            hitEntity.EventType = Grid;
                        }
                        else if (!p.Info.AmmoDef.Const.Pulse)
                        {
                            hitEntity.EventType = Effect;
                        }
                        else
                        {
                            hitEntity.EventType = Field;
                        }

                        if (p.Info.AmmoDef.Const.AreaEffect == DotField)
                        {
                            hitEntity.DamageOverTime = true;
                        }
                    }
                    else if (destroyable != null)
                    {
                        hitEntity.EventType = Destroyable;
                    }
                    else if (voxel != null)
                    {
                        hitEntity.EventType = Voxel;
                    }
                    found = true;
                    p.Info.HitList.Add(hitEntity);
                }
            }

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

                var sphere = new BoundingSphereD(p.Info.Target.Projectile.Position, p.Info.Target.Projectile.Info.AmmoDef.Const.CollisionSize);
                sphere.Include(new BoundingSphereD(p.Info.Target.Projectile.LastPosition, 1));
                var rayCheck   = useLine && sphere.Intersects(new RayD(p.LastPosition, p.Info.Direction)) != null;
                var testSphere = p.PruneSphere;
                testSphere.Radius = hitTolerance;

                if (rayCheck || sphere.Intersects(testSphere))
                {
                    found = ProjectileHit(p, p.Info.Target.Projectile, lineCheck, ref beam);
                }
            }
            p.SegmentList.Clear();

            return(found && GenerateHitInfo(p));
        }
示例#23
0
        public static bool SpawnWeather(MyWeatherEffectDefinition weather, Vector3D position, float radius)
        {
            MyPlanet closestPlanet = MyGamePruningStructure.GetClosestPlanet(position);

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

            var sessionWeather           = MySession.Static.GetComponent <MySectorWeatherComponent>();
            var sessionWeatherPlanetData = _planetWeatherGet(sessionWeather);

            if (Math.Abs((double)radius) < 1)
            {
                radius = 0.1122755f * closestPlanet.AtmosphereRadius;
            }
            var weatherPosition = new Vector3D?(closestPlanet.GetClosestSurfacePointGlobal(ref position));

            MyObjectBuilder_WeatherEffect builderWeatherEffect1 = new MyObjectBuilder_WeatherEffect()
            {
                Weather  = weather.Id.SubtypeName,
                Position = weatherPosition.Value,
                Radius   = radius
            };
            List <MyObjectBuilder_WeatherEffect> builderWeatherEffectList = new List <MyObjectBuilder_WeatherEffect>();

            BoundingSphereD boundingSphereD = new BoundingSphereD(weatherPosition.Value, (double)radius);

            for (int index1 = 0; index1 < sessionWeatherPlanetData.Count; ++index1)
            {
                if (sessionWeatherPlanetData[index1].PlanetId == closestPlanet.EntityId)
                {
                    builderWeatherEffectList.Clear();
                    for (int index2 = 0; index2 < sessionWeatherPlanetData[index1].Weathers.Count; ++index2)
                    {
                        BoundingSphereD sphere = new BoundingSphereD(sessionWeatherPlanetData[index1].Weathers[index2].Position, (double)sessionWeatherPlanetData[index1].Weathers[index2].Radius);
                        if (boundingSphereD.Intersects(sphere))
                        {
                            builderWeatherEffectList.Add(sessionWeatherPlanetData[index1].Weathers[index2]);
                        }
                    }
                    foreach (MyObjectBuilder_WeatherEffect builderWeatherEffect in builderWeatherEffectList)
                    {
                        sessionWeatherPlanetData[index1].Weathers.Remove(builderWeatherEffect);
                    }
                }
            }

            bool flag = false;

            for (int index = 0; index < sessionWeatherPlanetData.Count; ++index)
            {
                if (sessionWeatherPlanetData[index].PlanetId == closestPlanet.EntityId)
                {
                    sessionWeatherPlanetData[index].Weathers.Add(builderWeatherEffect1);
                    flag = true;
                    break;
                }
            }

            if (!flag)
            {
                var weatherPlanetData = new MyObjectBuilder_WeatherPlanetData()
                {
                    PlanetId = closestPlanet.EntityId
                };
                weatherPlanetData.Weathers.Add(builderWeatherEffect1);
                sessionWeatherPlanetData.Add(weatherPlanetData);
            }

            SyncWeather();

            return(true);
        }
示例#24
0
        public bool Drill(bool collectOre = true, bool performCutout = true, bool assignDamagedMaterial = false)
        {
            ProfilerShort.Begin("MyDrillBase::Drill()");

            bool drillingSuccess = false;

            MySoundPair sound = null;

            if ((m_drillEntity.Parent != null) && (m_drillEntity.Parent.Physics != null) && !m_drillEntity.Parent.Physics.Enabled)
            {
                return(false);
            }

            if (performCutout)
            {
                StopSparkParticles();
                StopDustParticles();
                var          entitiesInRange = m_sensor.EntitiesInRange;
                MyStringHash targetMaterial  = MyStringHash.NullOrEmpty;
                bool         targetIsBlock   = false;
                foreach (var entry in entitiesInRange)
                {
                    drillingSuccess = false;
                    var entity = entry.Value.Entity;
                    if (entity.MarkedForClose)
                    {
                        continue;
                    }
                    if (entity is MyCubeGrid)
                    {
                        var grid = entity as MyCubeGrid;
                        if (grid.Physics != null && grid.Physics.Enabled)
                        {
                            drillingSuccess = TryDrillBlocks(grid, entry.Value.DetectionPoint, !Sync.IsServer, out targetMaterial);
                            targetIsBlock   = true;
                        }
                        if (drillingSuccess)
                        {
                            m_initialHeatup = false;
                            CreateParticles(entry.Value.DetectionPoint, false, true, false);
                        }
                    }
                    else if (entity is MyVoxelBase)
                    {
                        ProfilerShort.Begin("Drill voxel map");
                        var voxels = entity as MyVoxelBase;
                        drillingSuccess = TryDrillVoxels(voxels, entry.Value.DetectionPoint, collectOre, !Sync.IsServer, assignDamagedMaterial);
                        ProfilerShort.BeginNextBlock("Create particles");
                        if (drillingSuccess)
                        {
                            Vector3D drillHitPoint = entry.Value.DetectionPoint;
                            if (targetMaterial == MyStringHash.NullOrEmpty)
                            {
                                var voxelMaterial = voxels.GetMaterialAt(ref drillHitPoint);
                                if (voxelMaterial != null)
                                {
                                    targetMaterial = MyStringHash.GetOrCompute(voxelMaterial.MaterialTypeName);
                                }
                            }
                            CreateParticles(entry.Value.DetectionPoint, true, false, true);
                        }
                        ProfilerShort.End();
                    }
                    else if (entity is MyFloatingObject)
                    {
                        var sphere = (BoundingSphereD)m_cutOut.Sphere;
                        sphere.Radius *= 1.33f;
                        if (entity.GetIntersectionWithSphere(ref sphere))
                        {
                            MyFloatingObject flObj = entity as MyFloatingObject;
                            if (Sync.IsServer)
                            {
                                if (flObj.Item.Content.TypeId == typeof(MyObjectBuilder_Ore))
                                {
                                    var invOwn = (m_drillEntity != null && m_drillEntity.HasInventory) ? m_drillEntity : null;
                                    if (invOwn == null)
                                    {
                                        invOwn = (m_drillEntity as MyHandDrill).Owner;
                                    }

                                    System.Diagnostics.Debug.Assert((invOwn.GetInventory(0) as MyInventory) != null, "Null or unexpected inventory type!");
                                    (invOwn.GetInventory(0) as MyInventory).TakeFloatingObject(flObj);
                                }
                                else
                                {
                                    (entity as MyFloatingObject).DoDamage(70, MyDamageType.Drill, true, attackerId: m_drillEntity != null ? m_drillEntity.EntityId : 0);
                                }
                            }
                            drillingSuccess = true;
                        }
                    }
                    else if (entity is MyCharacter)
                    {
                        var sphere = (BoundingSphereD)m_cutOut.Sphere;
                        sphere.Radius *= 0.8f;
                        var character = entity as MyCharacter;
                        if (targetMaterial == MyStringHash.NullOrEmpty)
                        {
                            targetMaterial = MyStringHash.GetOrCompute((entity as MyCharacter).Definition.PhysicalMaterial);
                        }
                        if (entity.GetIntersectionWithSphere(ref sphere))
                        {
                            //MyRenderProxy.DebugDrawSphere(sphere.Center, sphere.Radius, Color.Green.ToVector3(), 1, true);

                            //damage tracking
                            if ((m_drillEntity is MyHandDrill) && (m_drillEntity as MyHandDrill).Owner == MySession.Static.LocalCharacter && character != MySession.Static.LocalCharacter && character.IsDead == false)
                            {
                                MySession.Static.TotalDamageDealt += 20;
                            }

                            if (Sync.IsServer)
                            {
                                character.DoDamage(20, MyDamageType.Drill, true, attackerId: m_drillEntity != null ? m_drillEntity.EntityId : 0);
                            }
                            drillingSuccess = true;
                        }
                        else
                        {
                            BoundingSphereD headSphere = new BoundingSphereD(character.PositionComp.WorldMatrix.Translation + character.WorldMatrix.Up * 1.25f, 0.6f);
                            //MyRenderProxy.DebugDrawSphere(headSphere.Center, headSphere.Radius, Color.Red.ToVector3(), 1, false);
                            if (headSphere.Intersects(sphere))
                            {
                                //MyRenderProxy.DebugDrawSphere(sphere.Center, sphere.Radius, Color.Green.ToVector3(), 1, true);

                                //damage tracking
                                if ((m_drillEntity is MyHandDrill) && (m_drillEntity as MyHandDrill).Owner == MySession.Static.LocalCharacter && character != MySession.Static.LocalCharacter && character.IsDead == false)
                                {
                                    MySession.Static.TotalDamageDealt += 20;
                                }

                                if (Sync.IsServer)
                                {
                                    character.DoDamage(20, MyDamageType.Drill, true, attackerId: m_drillEntity != null ? m_drillEntity.EntityId : 0);
                                }
                                drillingSuccess = true;
                            }
                        }
                    }
                    if (drillingSuccess)
                    {
                        m_lastContactTime = MySandboxGame.TotalGamePlayTimeInMilliseconds;
                    }
                }
                if (targetMaterial != null && targetMaterial != MyStringHash.NullOrEmpty)
                {
                    sound = MyMaterialPropertiesHelper.Static.GetCollisionCue(MyMaterialPropertiesHelper.CollisionType.Start, m_drillMaterial, targetMaterial);
                    if (sound == null || sound == MySoundPair.Empty)//target material was not set in definition - using metal/rock sound
                    {
                        if (targetIsBlock)
                        {
                            targetMaterial = m_metalMaterial;
                        }
                        else
                        {
                            targetMaterial = m_rockMaterial;
                        }
                    }
                    sound = MyMaterialPropertiesHelper.Static.GetCollisionCue(MyMaterialPropertiesHelper.CollisionType.Start, m_drillMaterial, targetMaterial);
                }
            }

            if (sound != null && sound != MySoundPair.Empty)
            {
                StartLoopSound(sound);
            }
            else
            {
                StartIdleSound(m_idleSoundLoop);
            }

            if (!IsDrilling)
            {
                IsDrilling = true;
                m_animationLastUpdateTime = MySandboxGame.TotalGamePlayTimeInMilliseconds;
            }

            ProfilerShort.End();
            return(drillingSuccess);
        }
示例#25
0
        internal void EwarEffects()
        {
            switch (Info.AmmoDef.Const.AreaEffect)
            {
            case AreaEffectType.AntiSmart:
                var eWarSphere = new BoundingSphereD(Position, Info.AmmoDef.Const.AreaEffectSize);

                DynTrees.GetAllProjectilesInSphere(Info.System.Session, ref eWarSphere, EwaredProjectiles, false);
                for (int j = 0; j < EwaredProjectiles.Count; j++)
                {
                    var netted = EwaredProjectiles[j];

                    if (eWarSphere.Intersects(new BoundingSphereD(netted.Position, netted.Info.AmmoDef.Const.CollisionSize)))
                    {
                        if (netted.Info.Target.FiringCube.CubeGrid.IsSameConstructAs(Info.Target.FiringCube.CubeGrid) || netted.Info.Target.IsProjectile)
                        {
                            continue;
                        }
                        if (Info.WeaponRng.ClientProjectileRandom.NextDouble() * 100f < Info.AmmoDef.Const.PulseChance || !Info.AmmoDef.Const.Pulse)
                        {
                            Info.BaseEwarPool -= (float)netted.Info.AmmoDef.Const.HealthHitModifier;
                            if (Info.BaseEwarPool <= 0 && Info.BaseHealthPool-- > 0)
                            {
                                Info.EwarActive = true;
                                netted.Info.Target.Projectile   = this;
                                netted.Info.Target.IsProjectile = true;
                                Seekers.Add(netted);
                            }
                        }

                        Info.WeaponRng.ClientProjectileCurrentCounter++;
                    }
                }
                EwaredProjectiles.Clear();
                return;

            case AreaEffectType.PushField:
                if (Info.EwarAreaPulse && Info.WeaponRng.ClientProjectileRandom.NextDouble() * 100f <= Info.AmmoDef.Const.PulseChance || !Info.AmmoDef.Const.Pulse)
                {
                    Info.EwarActive = true;
                }
                break;

            case AreaEffectType.PullField:
                if (Info.EwarAreaPulse && Info.WeaponRng.ClientProjectileRandom.NextDouble() * 100f <= Info.AmmoDef.Const.PulseChance || !Info.AmmoDef.Const.Pulse)
                {
                    Info.EwarActive = true;
                }
                break;

            case AreaEffectType.JumpNullField:
                if (Info.EwarAreaPulse && Info.WeaponRng.ClientProjectileRandom.NextDouble() * 100f <= Info.AmmoDef.Const.PulseChance || !Info.AmmoDef.Const.Pulse)
                {
                    Info.EwarActive = true;
                }
                break;

            case AreaEffectType.AnchorField:
                if (Info.EwarAreaPulse && Info.WeaponRng.ClientProjectileRandom.NextDouble() * 100f <= Info.AmmoDef.Const.PulseChance || !Info.AmmoDef.Const.Pulse)
                {
                    Info.EwarActive = true;
                }
                break;

            case AreaEffectType.EnergySinkField:
                if (Info.EwarAreaPulse && Info.WeaponRng.ClientProjectileRandom.NextDouble() * 100f <= Info.AmmoDef.Const.PulseChance || !Info.AmmoDef.Const.Pulse)
                {
                    Info.EwarActive = true;
                }
                break;

            case AreaEffectType.EmpField:
                if (Info.EwarAreaPulse && Info.WeaponRng.ClientProjectileRandom.NextDouble() * 100f <= Info.AmmoDef.Const.PulseChance || !Info.AmmoDef.Const.Pulse)
                {
                    Info.EwarActive = true;
                }
                break;

            case AreaEffectType.OffenseField:
                if (Info.EwarAreaPulse && Info.WeaponRng.ClientProjectileRandom.NextDouble() * 100f <= Info.AmmoDef.Const.PulseChance || !Info.AmmoDef.Const.Pulse)
                {
                    Info.EwarActive = true;
                }
                break;

            case AreaEffectType.NavField:
                if (!Info.AmmoDef.Const.Pulse || Info.EwarAreaPulse && Info.WeaponRng.ClientProjectileRandom.NextDouble() * 100f <= Info.AmmoDef.Const.PulseChance)
                {
                    Info.EwarActive = true;
                }
                break;

            case AreaEffectType.DotField:
                if (Info.EwarAreaPulse && Info.WeaponRng.ClientProjectileRandom.NextDouble() * 100f <= Info.AmmoDef.Const.PulseChance || !Info.AmmoDef.Const.Pulse)
                {
                    Info.EwarActive = true;
                }
                break;
            }
            Info.WeaponRng.ClientProjectileCurrentCounter++;
        }
        private void ActivateCommon()
        {
            BoundingSphereD globalSphere = new BoundingSphereD(Vector3D.Transform(m_detectorSphere.Center, CubeGrid.WorldMatrix), m_detectorSphere.Radius);

            if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW)
            {
                MyRenderProxy.DebugDrawSphere(globalSphere.Center, (float)globalSphere.Radius, Color.Red.ToVector3(), 1.0f, false);
            }

            m_isActivatedOnSomething = false;
            ProfilerShort.Begin("Query");
            var res = MyEntities.GetTopMostEntitiesInSphere(ref globalSphere);

            m_entitiesInContact.Clear();
            foreach (MyEntity entity in res)
            {
                var rootEntity = entity.GetTopMostParent();
                if (CanInteractWith(rootEntity))
                {
                    m_entitiesInContact.Add(rootEntity);
                }
            }
            res.Clear();
            ProfilerShort.End();

            //TODO:cache blocks on this grid
            foreach (var entry in m_entitiesInContact)
            {
                MyCubeGrid  grid      = entry as MyCubeGrid;
                MyCharacter character = entry as MyCharacter;

                if (grid != null)
                {
                    m_tempBlocksBuffer.Clear();
                    grid.GetBlocksInsideSphere(ref globalSphere, m_tempBlocksBuffer);
                    m_blocksToActivateOn.UnionWith(m_tempBlocksBuffer);
                }
                if (character != null && Sync.IsServer)
                {
                    MyStringHash damageType = MyDamageType.Drill;
                    if (this is IMyShipGrinder)
                    {
                        damageType = MyDamageType.Grind;
                    }
                    else if (this is IMyShipWelder)
                    {
                        damageType = MyDamageType.Weld;
                    }
                    if (globalSphere.Intersects(character.PositionComp.WorldAABB))
                    {
                        character.DoDamage(20, damageType, true, attackerId: EntityId);
                    }
                }
            }

            m_isActivatedOnSomething |= Activate(m_blocksToActivateOn);

            m_activateCounter++;
            m_lastTimeActivate = MySandboxGame.TotalGamePlayTimeInMilliseconds;

            PlayLoopSound(m_isActivatedOnSomething);

            m_blocksToActivateOn.Clear();
        }
示例#27
0
        public MyDetectedEntityInfo Raycast(double distance, Vector3D direction)
        {
            if (Vector3D.IsZero(direction))
            {
                throw new ArgumentOutOfRangeException("direction", "Direction cannot be 0,0,0");
            }

            //mods can disable raycast on a block by setting the distance limit to 0 (-1 means infinite)
            if (distance <= 0 || (BlockDefinition.RaycastDistanceLimit > -1 && distance > BlockDefinition.RaycastDistanceLimit))
            {
                return(new MyDetectedEntityInfo());
            }

            if (AvailableScanRange < distance || !this.CheckIsWorking())
            {
                return(new MyDetectedEntityInfo());
            }

            AvailableScanRange -= distance;

            var startPos  = this.WorldMatrix.Translation;
            var targetPos = startPos + direction * distance;

            //try a physics raycast first
            //very accurate, but very slow
            List <MyPhysics.HitInfo> hits = new List <MyPhysics.HitInfo>();

            MyPhysics.CastRay(startPos, targetPos, hits);

            foreach (var hit in hits)
            {
                var entity = (MyEntity)hit.HkHitInfo.GetHitEntity();
                if (entity == this)
                {
                    continue;
                }

                m_lastRay = new RaycastInfo()
                {
                    Distance = distance, Start = startPos, End = targetPos, Hit = hit.Position
                };
                return(MyDetectedEntityInfoHelper.Create(entity, this.OwnerId, hit.Position));
            }

            //long-distance planet scanning
            //fastest way is to intersect planet bounding boxes then treat the planet as a sphere
            LineD line   = new LineD(startPos, targetPos);
            var   voxels = new List <MyLineSegmentOverlapResult <MyVoxelBase> >();

            MyGamePruningStructure.GetVoxelMapsOverlappingRay(ref line, voxels);

            foreach (var result in voxels)
            {
                var planet = result.Element as MyPlanet;
                if (planet == null)
                {
                    continue;
                }

                double distCenter = Vector3D.DistanceSquared(this.PositionComp.GetPosition(), planet.PositionComp.GetPosition());
                var    gravComp   = planet.Components.Get <MyGravityProviderComponent>();
                if (gravComp == null)
                {
                    continue;
                }

                if (!gravComp.IsPositionInRange(startPos) && distCenter > planet.MaximumRadius * planet.MaximumRadius)
                {
                    var boundingSphere = new BoundingSphereD(planet.PositionComp.GetPosition(), planet.MaximumRadius);
                    var rayd           = new RayD(startPos, direction);
                    var intersection   = boundingSphere.Intersects(rayd);

                    if (!intersection.HasValue)
                    {
                        continue;
                    }

                    if (distance < intersection.Value)
                    {
                        continue;
                    }

                    var hitPos = startPos + direction * intersection.Value;
                    m_lastRay = new RaycastInfo()
                    {
                        Distance = distance, Start = startPos, End = targetPos, Hit = hitPos
                    };
                    return(MyDetectedEntityInfoHelper.Create(result.Element, this.OwnerId, hitPos));
                }

                //if the camera is inside gravity, query voxel storage
                if (planet.RootVoxel.Storage == null)
                {
                    continue;
                }
                var start = Vector3D.Transform(line.From, planet.PositionComp.WorldMatrixInvScaled);
                start += planet.SizeInMetresHalf;
                var end = Vector3D.Transform(line.To, planet.PositionComp.WorldMatrixInvScaled);
                end += planet.SizeInMetresHalf;

                var voxRay = new LineD(start, end);

                double startOffset;
                double endOffset;
                if (!planet.RootVoxel.Storage.DataProvider.Intersect(ref voxRay, out startOffset, out endOffset))
                {
                    continue;
                }

                var from = voxRay.From;
                voxRay.From = from + voxRay.Direction * voxRay.Length * startOffset;
                voxRay.To   = from + voxRay.Direction * voxRay.Length * endOffset;

                start = voxRay.From - planet.SizeInMetresHalf;
                start = Vector3D.Transform(start, planet.PositionComp.WorldMatrix);

                m_lastRay = new RaycastInfo()
                {
                    Distance = distance, Start = startPos, End = targetPos, Hit = start
                };
                return(MyDetectedEntityInfoHelper.Create(result.Element, this.OwnerId, start));
            }

            m_lastRay = new RaycastInfo()
            {
                Distance = distance, Start = startPos, End = targetPos, Hit = null
            };
            return(new MyDetectedEntityInfo());
        }
示例#28
0
        private bool IsInStoppingDistance()
        {
            int currentIndex = m_waypoints.IndexOf(CurrentWaypoint);
            double currentDstSqr = (WorldMatrix.Translation - CurrentWaypoint.Coords).LengthSquared();
            double dstError = CubeGrid.GridSize * 3;

            if (m_automaticBehaviour != null && m_automaticBehaviour.IsActive)
            {
                dstError = m_automaticBehaviour.WaypointThresholdDistance;
            }
            else if (m_waypointThresholdDistance > 0)
            {
                dstError = m_waypointThresholdDistance;
            }
            else if (m_dockingModeEnabled || (m_currentFlightMode == FlightMode.OneWay && currentIndex == m_waypoints.Count - 1))
            {
                if (CubeGrid.GridSize >= 0.5f)
                    dstError = CubeGrid.GridSize * 0.25;
                else
                    dstError = CubeGrid.GridSize;
            }

            if (MyFakes.ENABLE_VR_REMOTE_CONTROL_WAYPOINTS_FAST_MOVEMENT)
            {
                // Check if movement from previous position to current position intersects waypoint sphere.
                if (currentDstSqr < dstError * dstError)
                    return true;

                double prevDstSqr = (m_previousWorldPosition - CurrentWaypoint.Coords).LengthSquared();
                if (prevDstSqr < dstError * dstError)
                    return true;

                var dir = WorldMatrix.Translation - m_previousWorldPosition;
                double rayLength = dir.Normalize();
                if (rayLength > 0.01)
                {
                    RayD ray = new RayD(m_previousWorldPosition, dir);
                    BoundingSphereD sphere = new BoundingSphereD(CurrentWaypoint.Coords, dstError);
                    double? intersection = sphere.Intersects(ray);
                    return (intersection != null) ? intersection.Value <= rayLength : false;
                }
            }

            return currentDstSqr < dstError * dstError;
        }
示例#29
0
        public bool Drill(bool collectOre = true, bool performCutout = true, bool assignDamagedMaterial = false)
        {
            ProfilerShort.Begin("MyDrillBase::Drill()");

            bool drillingSuccess = false;

            MySoundPair sound = null;

            if ((m_drillEntity.Parent != null) && (m_drillEntity.Parent.Physics != null) && !m_drillEntity.Parent.Physics.Enabled)
                return false;

            if (performCutout)
            {
                StopSparkParticles();
                StopDustParticles();
                var entitiesInRange = m_sensor.EntitiesInRange;
                MyStringHash targetMaterial = MyStringHash.NullOrEmpty;
                MyStringHash bestMaterial = MyStringHash.NullOrEmpty;
                float distanceBest = float.MaxValue;
                bool targetIsBlock = false;
                foreach (var entry in entitiesInRange)
                {
                    drillingSuccess = false;
                    var entity = entry.Value.Entity;
                    if (entity.MarkedForClose)
                        continue;
                    if (entity is MyCubeGrid)
                    {
                        var grid = entity as MyCubeGrid;
                        if (grid.Physics != null && grid.Physics.Enabled)
                        {
                            drillingSuccess = TryDrillBlocks(grid, entry.Value.DetectionPoint, !Sync.IsServer, out targetMaterial);
                            targetIsBlock = true;
                        }
                        if (drillingSuccess)
                        {
                            m_initialHeatup = false;
                            CreateParticles(entry.Value.DetectionPoint, false, true, false);
                        }
                    }
                    else if (entity is MyVoxelBase)
                    {
                        ProfilerShort.Begin("Drill voxel map");
                        var voxels = entity as MyVoxelBase;
                        drillingSuccess = TryDrillVoxels(voxels, entry.Value.DetectionPoint, collectOre, !Sync.IsServer, assignDamagedMaterial);
                        ProfilerShort.BeginNextBlock("Create particles");
                        if (drillingSuccess)
                        {
                            Vector3D drillHitPoint = entry.Value.DetectionPoint;
                            if(targetMaterial == MyStringHash.NullOrEmpty)
                            {
                                var voxelMaterial = voxels.GetMaterialAt(ref drillHitPoint);
                                if (voxelMaterial != null)
                                    targetMaterial = MyStringHash.GetOrCompute(voxelMaterial.MaterialTypeName);
                            }
                            CreateParticles(entry.Value.DetectionPoint, true, false, true);
                        }
                        ProfilerShort.End();
                    }
                    else if (entity is MyFloatingObject)
                    {
                        var sphere = (BoundingSphereD)m_cutOut.Sphere;
                        sphere.Radius *= 1.33f;
                        if (entity.GetIntersectionWithSphere(ref sphere))
                        {
                            MyFloatingObject flObj = entity as MyFloatingObject;
                            if (Sync.IsServer)
                            {
                                if (flObj.Item.Content.TypeId == typeof(MyObjectBuilder_Ore))
                                {
                                    var invOwn = (m_drillEntity != null && m_drillEntity.HasInventory) ? m_drillEntity : null;
                                    if (invOwn == null)
                                        invOwn = (m_drillEntity as MyHandDrill).Owner;

                                    System.Diagnostics.Debug.Assert((invOwn.GetInventory(0) as MyInventory) != null, "Null or unexpected inventory type!");
                                    (invOwn.GetInventory(0) as MyInventory).TakeFloatingObject(flObj);
                                }
                                else
                                    (entity as MyFloatingObject).DoDamage(70, MyDamageType.Drill, true, attackerId: m_drillEntity != null ? m_drillEntity.EntityId : 0);
                            }
                            drillingSuccess = true;
                        }
                    }
                    else if (entity is MyCharacter)
                    {
                        var sphere = (BoundingSphereD)m_cutOut.Sphere;
                        sphere.Radius *= 0.8f;
                        var character = entity as MyCharacter;
                        if (targetMaterial == MyStringHash.NullOrEmpty)
                            targetMaterial = MyStringHash.GetOrCompute((entity as MyCharacter).Definition.PhysicalMaterial);
                        if (entity.GetIntersectionWithSphere(ref sphere))
                        {
                            //MyRenderProxy.DebugDrawSphere(sphere.Center, sphere.Radius, Color.Green.ToVector3(), 1, true);

                            //damage tracking
                            if ((m_drillEntity is MyHandDrill) && (m_drillEntity as MyHandDrill).Owner == MySession.Static.LocalCharacter && character != MySession.Static.LocalCharacter && character.IsDead == false)
                                MySession.Static.TotalDamageDealt += 20;

                            if (Sync.IsServer)
                                character.DoDamage(20, MyDamageType.Drill, true, attackerId: m_drillEntity != null ? m_drillEntity.EntityId : 0);
                            drillingSuccess = true;
                        }
                        else
                        {
                            BoundingSphereD headSphere = new BoundingSphereD(character.PositionComp.WorldMatrix.Translation + character.WorldMatrix.Up * 1.25f, 0.6f);
                            //MyRenderProxy.DebugDrawSphere(headSphere.Center, headSphere.Radius, Color.Red.ToVector3(), 1, false);
                            if (headSphere.Intersects(sphere))
                            {
                                //MyRenderProxy.DebugDrawSphere(sphere.Center, sphere.Radius, Color.Green.ToVector3(), 1, true);

                                //damage tracking
                                if ((m_drillEntity is MyHandDrill) && (m_drillEntity as MyHandDrill).Owner == MySession.Static.LocalCharacter && character != MySession.Static.LocalCharacter && character.IsDead == false)
                                    MySession.Static.TotalDamageDealt += 20;

                                if (Sync.IsServer)
                                    character.DoDamage(20, MyDamageType.Drill, true, attackerId: m_drillEntity != null ? m_drillEntity.EntityId : 0);
                                drillingSuccess = true;
                            }
                        }
                    }
                    if (drillingSuccess)
                    {
                        m_lastContactTime = MySandboxGame.TotalGamePlayTimeInMilliseconds;
                        float dist = Vector3.DistanceSquared(entry.Value.DetectionPoint, Sensor.Center);
                        if (targetMaterial != null && targetMaterial != MyStringHash.NullOrEmpty && dist < distanceBest)
                        {
                            bestMaterial = targetMaterial;
                            distanceBest = dist;
                        }
                    }
                }

                if (bestMaterial != null && bestMaterial != MyStringHash.NullOrEmpty)
                {
                    sound = MyMaterialPropertiesHelper.Static.GetCollisionCue(MyMaterialPropertiesHelper.CollisionType.Start, m_drillMaterial, bestMaterial);
                    if (sound == null || sound == MySoundPair.Empty)//target material was not set in definition - using metal/rock sound
                    {
                        if (targetIsBlock)
                        {
                            bestMaterial = m_metalMaterial;
                        }
                        else
                        {
                            bestMaterial = m_rockMaterial;
                        }
                    }
                    sound = MyMaterialPropertiesHelper.Static.GetCollisionCue(MyMaterialPropertiesHelper.CollisionType.Start, m_drillMaterial, bestMaterial);
                }
            }

            if (sound != null && sound != MySoundPair.Empty)
                StartLoopSound(sound);
            else
                StartIdleSound(m_idleSoundLoop);

            if (!IsDrilling)
            {
                IsDrilling = true;
                m_animationLastUpdateTime = MySandboxGame.TotalGamePlayTimeInMilliseconds;
            }

            ProfilerShort.End();
            return drillingSuccess;
        }
示例#30
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();
        }
示例#31
0
        private static MyTuple <bool, float> TAPI_IntersectEntToShieldFast(List <MyEntity> entities, RayD ray, bool onlyIfOnline, bool enenmyOnly = false, long requesterId = 0, float maxLengthSqr = float.MaxValue)
        {
            if (enenmyOnly)
            {
                if (requesterId == 0)
                {
                    return(new MyTuple <bool, float>(false, 0));
                }
            }

            float closestOtherDist  = float.MaxValue;
            float closestFriendDist = float.MaxValue;
            bool  closestOther      = false;
            bool  closestFriend     = false;

            for (int i = 0; i < entities.Count; i++)
            {
                var entity = entities[i];
                ShieldGridComponent c;
                if (entity != null && Session.Instance.IdToBus.TryGetValue(entity.EntityId, out c) && c?.DefenseShields?.DsState?.State != null && c.DefenseShields.MyCube != null)
                {
                    var s = c.DefenseShields;
                    if (onlyIfOnline && (!s.DsState.State.Online || s.DsState.State.Lowered) || s.ReInforcedShield)
                    {
                        continue;
                    }

                    lock (s.MatrixLock) {
                        var normSphere = new BoundingSphereD(Vector3.Zero, 1f);
                        var kRay       = new RayD(Vector3D.Zero, Vector3D.Forward);

                        var      ellipsoidMatrixInv = s.DetectMatrixOutsideInv;
                        Vector3D krayPos;
                        Vector3D.Transform(ref ray.Position, ref ellipsoidMatrixInv, out krayPos);

                        Vector3D nDir;
                        Vector3D.TransformNormal(ref ray.Direction, ref ellipsoidMatrixInv, out nDir);

                        Vector3D krayDir;
                        Vector3D.Normalize(ref nDir, out krayDir);

                        kRay.Direction = krayDir;
                        kRay.Position  = krayPos;
                        var nullDist = normSphere.Intersects(kRay);

                        if (!nullDist.HasValue)
                        {
                            continue;
                        }

                        var hitPos = krayPos + (krayDir * -nullDist.Value);

                        var      ellipsoidMatrix = s.DetectMatrixOutside;
                        Vector3D worldHitPos;
                        Vector3D.Transform(ref hitPos, ref ellipsoidMatrix, out worldHitPos);
                        var intersectDist = Vector3.DistanceSquared(worldHitPos, ray.Position);
                        if (intersectDist <= 0 || intersectDist > maxLengthSqr)
                        {
                            continue;
                        }

                        var firstOrLast   = enenmyOnly && (!closestFriend || intersectDist < closestFriendDist);
                        var notEnemyCheck = false;
                        if (firstOrLast)
                        {
                            var relationship = MyIDModule.GetRelationPlayerBlock(requesterId, s.MyCube.OwnerId);
                            var enemy        = relationship != MyRelationsBetweenPlayerAndBlock.Owner && relationship != MyRelationsBetweenPlayerAndBlock.FactionShare;
                            notEnemyCheck = !enemy;
                        }

                        if (notEnemyCheck)
                        {
                            closestFriendDist = intersectDist;
                            closestFriend     = true;
                        }
                        else
                        {
                            closestOtherDist = intersectDist;
                            closestOther     = true;
                        }
                    }
                }
            }

            if (!enenmyOnly && closestOther || closestOther && !closestFriend)
            {
                return(new MyTuple <bool, float>(true, closestOtherDist));
            }

            if (closestFriend && !closestOther || closestFriendDist < closestOtherDist)
            {
                return(new MyTuple <bool, float>(false, closestFriendDist));
            }

            if (!closestOther)
            {
                return(new MyTuple <bool, float>(false, 0));
            }

            return(new MyTuple <bool, float>(true, closestOtherDist));
        }