예제 #1
0
        public override void UpdateBeforeSimulation()
        {
            base.UpdateBeforeSimulation();

            m_updateCounter++;
            if (m_updateCounter % 100 == 0 && MySession.Static.LocalCharacter != null)
            {
                m_detectedGrids.Clear();
                BoundingSphereD playerSphere = new BoundingSphereD(MySession.Static.LocalCharacter.PositionComp.GetPosition(), 500f);
                MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref playerSphere, m_detectedGrids);
                for (int i = 0; i < m_detectedGrids.Count; i++)
                {
                    MyCubeGrid grid = m_detectedGrids[i] as MyCubeGrid;
                    if (grid != null)
                    {
                        foreach (var block in grid.CubeBlocks)
                        {
                            if (block.FatBlock is MyFunctionalBlock)
                            {
                                (block.FatBlock as MyFunctionalBlock).UpdateSoundEmitters();
                            }
                        }
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Destroys missiles in blast radius.
        /// </summary>
        private void DestroyAllNearbyMissiles()
        {
            if (myCluster != null || m_destroyedNearbyMissiles)
            {
                return;
            }
            m_destroyedNearbyMissiles = true;

            BoundingSphereD explosion = new BoundingSphereD(MyEntity.GetPosition(), myAmmo.MissileDefinition.MissileExplosionRadius);

            Log.DebugLog("Explosion: " + explosion);
            List <MyEntity> entitiesInExplosion = new List <MyEntity>();

            MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref explosion, entitiesInExplosion, MyEntityQueryType.Dynamic);

            foreach (MyEntity entity in entitiesInExplosion)
            {
                if (!entity.Closed && entity.IsMissile() && entity != MyEntity)
                {
                    Log.DebugLog("Explode: " + entity + ", position: " + entity.PositionComp.GetPosition());
                    ((MyAmmoBase)entity).Explode();
                }
            }

            explosion.Radius *= 10f;
            entitiesInExplosion.Clear();
            MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref explosion, entitiesInExplosion, MyEntityQueryType.Dynamic);
            foreach (MyEntity entity in entitiesInExplosion)
            {
                if (!entity.Closed && entity.IsMissile() && entity != MyEntity)
                {
                    Log.DebugLog("nearby: " + entity + ", position: " + entity.PositionComp.GetPosition());
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Takes a point and radius and returns all entities found within the sphere
        /// </summary>
        /// <param name="detectionCenter">Point of scan origin</param>
        /// <param name="range">How far from the origin you want to scan for entities</param>
        /// <returns>An enumerable list of entities</returns>
        public IEnumerable <MyEntity> DetectEntitiesInSphere(Vector3D detectionCenter, double range)
        {
            BoundingSphereD pruneSphere = new BoundingSphereD(detectionCenter, range);
            List <MyEntity> pruneList   = new List <MyEntity>();

            MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref pruneSphere, pruneList, MyEntityQueryType.Dynamic);
            return(pruneList);
        }
예제 #4
0
        public bool SpaceCollisionDetection(Vector3D detectionCenter)
        {
            BoundingSphereD locationSphere = new BoundingSphereD(detectionCenter, 75);
            List <MyEntity> pruneList      = new List <MyEntity>();

            MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref locationSphere, pruneList, MyEntityQueryType.Both);
            return(pruneList.Count > 0);
        }
예제 #5
0
 private void GetNearby(float range)
 {
     if (m_nearbyRange < range)
     {
         range++;
         m_nearbyEntities.Clear();
         BoundingSphereD nearby = new BoundingSphereD(Entity.GetPosition(), range);
         MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref nearby, m_nearbyEntities);
         m_nearbyRange = range;
     }
 }
예제 #6
0
        public void CleanupAsteroids(bool deleteStorage = false)
        {
            var voxelMaps = MyEntities.GetEntities().OfType <MyVoxelMap>();

            var resetIds = new List <long>();

            //Parallel.ForEach(voxelMaps, map =>
            foreach (var map in voxelMaps)
            {
                try
                {
                    if (map.StorageName == null || map.Storage.DataProvider == null)
                    {
                        continue;
                    }

                    var s            = map.PositionComp.WorldVolume;
                    var nearEntities = new List <MyEntity>();

                    MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref s, nearEntities);

                    if (nearEntities.Any(e => e is MyCubeGrid || e is MyCharacter))
                    {
                        continue;
                    }

                    long id = map.EntityId;

                    if (deleteStorage)
                    {
                        map.Close();
                    }
                    else
                    {
                        map.Storage.Reset(MyStorageDataTypeFlags.All);
                    }

                    if (!deleteStorage)
                    {
                        lock (resetIds)
                            resetIds.Add(id);
                    }
                }
                catch (Exception e)
                {
                    _log.Error($"{e.Message}\n{e.StackTrace}");
                }
            }                            //);

            ModCommunication.SendMessageToClients(new VoxelResetMessage(resetIds.ToArray()));

            Context.Respond($"Reset {resetIds.Count} voxel maps.");
        }
예제 #7
0
 protected virtual void UpdateInternal()
 {
     if (this.DoQuery)
     {
         this.m_queryResult.Clear();
         TriggerType triggerType = this.m_triggerType;
         if (triggerType == TriggerType.AABB)
         {
             MyGamePruningStructure.GetTopMostEntitiesInBox(ref this.m_AABB, this.m_queryResult, MyEntityQueryType.Both);
         }
         else
         {
             if (triggerType != TriggerType.Sphere)
             {
                 throw new ArgumentOutOfRangeException();
             }
             MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref this.m_boundingSphere, this.m_queryResult, MyEntityQueryType.Both);
         }
         int index = 0;
         while (index < this.m_queryResult.Count)
         {
             MyEntity entity = this.m_queryResult[index];
             if (!this.QueryEvaluator(entity))
             {
                 this.m_queryResult.RemoveAtFast <MyEntity>(index);
                 continue;
             }
             triggerType = this.m_triggerType;
             if (triggerType == TriggerType.AABB)
             {
                 if (!this.m_AABB.Intersects(this.m_queryResult[index].PositionComp.WorldAABB))
                 {
                     this.m_queryResult.RemoveAtFast <MyEntity>(index);
                     continue;
                 }
                 index++;
                 continue;
             }
             if (triggerType != TriggerType.Sphere)
             {
                 index++;
                 continue;
             }
             if (!this.m_boundingSphere.Intersects(this.m_queryResult[index].PositionComp.WorldAABB))
             {
                 this.m_queryResult.RemoveAtFast <MyEntity>(index);
                 continue;
             }
             index++;
         }
     }
 }
예제 #8
0
        public static IEnumerable <MyEntity> DetectTopMostEntitiesInSphere(Vector3D detectionCenter, double range, bool reportOrigin = false)
        {
            if (reportOrigin)
            {
                AddGpsLocation($"DetectTopMostEntitiesInSphere {range}", detectionCenter);
            }

            BoundingSphereD pruneSphere = new BoundingSphereD(detectionCenter, range);
            List <MyEntity> pruneList   = new List <MyEntity>();

            MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref pruneSphere, pruneList);
            return(pruneList);
        }
예제 #9
0
        public void CleanupAsteroidsDistant(double distance = 1000, bool deleteStorage = false)
        {
            var voxelMaps = MyEntities.GetEntities().OfType <MyVoxelMap>();

            var resetIds = new List <long>();
            int count    = 0;

            foreach (var map in voxelMaps)
            {
                try
                {
                    if (map.StorageName == null || map.Storage.DataProvider == null)
                    {
                        continue;
                    }

                    var s            = new BoundingSphereD(map.PositionComp.GetPosition(), distance);
                    var nearEntities = new List <MyEntity>();

                    MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref s, nearEntities);

                    if (nearEntities.Any(e => e is MyCubeGrid || e is MyCharacter))
                    {
                        continue;
                    }

                    count++;

                    long id = map.EntityId;

                    if (deleteStorage)
                    {
                        using (PinDelete())
                            map.Close();
                    }
                    else
                    {
                        map.Storage.Reset(MyStorageDataTypeFlags.All);
                        resetIds.Add(id);
                    }
                }
                catch (Exception e)
                {
                    _log.Error($"{e.Message}\n{e.StackTrace}");
                }
            }

            ModCommunication.SendMessageToClients(new VoxelResetMessage(resetIds.ToArray()));

            Context.Respond($"Reset {count} voxel maps.");
        }
예제 #10
0
 public static void ApplyEMP(BoundingSphereD location, float strength, TimeSpan duration)
 {
     MyAPIGateway.Utilities.TryInvokeOnGameThread(() => {
         MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref location, s_entitiesEMP);
         foreach (IMyEntity entity in s_entitiesEMP)
         {
             IMyCubeGrid grid = entity as IMyCubeGrid;
             if (grid != null)
             {
                 EMP e = new EMP();
                 e.Start(grid, duration, ref strength, long.MinValue);
             }
         }
         s_entitiesEMP.Clear();
     });
 }
예제 #11
0
        public static void GetRealPlayers(Vector3D center, float radius, List <long> realPlayers)
        {
            List <IMyIdentity> realPlayersIdentities = new List <IMyIdentity>();

            MyAPIGateway.Players.GetAllIdentites(realPlayersIdentities, p => !string.IsNullOrEmpty(p?.DisplayName));
            var pruneSphere = new BoundingSphereD(center, radius);
            var pruneList   = new List <MyEntity>();

            MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref pruneSphere, pruneList);

            foreach (var ent in pruneList)
            {
                if (ent == null || !(ent is IMyCubeGrid || ent is IMyCharacter))
                {
                    continue;
                }

                IMyPlayer player = null;

                if (ent is IMyCharacter)
                {
                    player = MyAPIGateway.Players.GetPlayerControllingEntity(ent);
                    if (player == null)
                    {
                        continue;
                    }
                }
                else
                {
                    var playerTmp = MyAPIGateway.Players.GetPlayerControllingEntity(ent);

                    if (playerTmp?.Character != null)
                    {
                        player = playerTmp;
                    }
                }

                if (player == null)
                {
                    continue;
                }
                if (realPlayersIdentities.Contains(player.Identity))
                {
                    realPlayers.Add(player.IdentityId);
                }
            }
        }
예제 #12
0
        private void DrawDisabledGuns()
        {
            if (Tick600 || Tick60 && QuickDisableGunsCheck)
            {
                QuickDisableGunsCheck         = false;
                _nearbyGridsTestSphere.Center = CameraPos;
                _gridsNearCamera.Clear();
                _uninitializedBlocks.Clear();

                MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref _nearbyGridsTestSphere, _gridsNearCamera);
                for (int i = _gridsNearCamera.Count - 1; i >= 0; i--)
                {
                    var grid = _gridsNearCamera[i] as MyCubeGrid;
                    if (grid?.Physics != null && !grid.MarkedForClose && !grid.IsPreview && !grid.Physics.IsPhantom)
                    {
                        var fatBlocks = grid.GetFatBlocks();
                        for (int j = 0; j < fatBlocks.Count; j++)
                        {
                            var block = fatBlocks[j];
                            if (block.IsFunctional && WeaponPlatforms.ContainsKey(block.BlockDefinition.Id))
                            {
                                GridAi gridAi;
                                if (!GridTargetingAIs.TryGetValue(block.CubeGrid, out gridAi) || !gridAi.WeaponBase.ContainsKey(block))
                                {
                                    _uninitializedBlocks.Add(block);
                                }
                            }
                        }
                    }
                }
            }

            for (int i = 0; i < _uninitializedBlocks.Count; i++)
            {
                var badBlock = _uninitializedBlocks[i];
                if (badBlock.InScene)
                {
                    var lookSphere = new BoundingSphereD(badBlock.PositionComp.WorldAABB.Center, 30f);
                    if (Camera.IsInFrustum(ref lookSphere))
                    {
                        MyOrientedBoundingBoxD blockBox;
                        SUtils.GetBlockOrientedBoundingBox(badBlock, out blockBox);
                        DsDebugDraw.DrawBox(blockBox, _uninitializedColor);
                    }
                }
            }
        }
예제 #13
0
        internal void ComputeAccelSphere()
        {
            NearByEntityCache.Clear();
            if (MarkedForClose)
            {
                return;
            }

            AccelChecked = true;

            var numOfEntities = NearByEntities > 0 ? NearByEntities : 1f;
            var ratio         = (MyProjectiles / numOfEntities) / 10f;
            var checkVol      = Math.Max(ratio > 1 ? ScanVolume.Radius : ScanVolume.Radius * ratio, 500f);

            NearByEntitySphere = new BoundingSphereD(MyGrid.PositionComp.WorldAABB.Center, checkVol);
            var qType = ClosestStaticSqr < (checkVol * 2) * (checkVol * 2) ? MyEntityQueryType.Both : MyEntityQueryType.Dynamic;

            MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref NearByEntitySphere, NearByEntityCache, qType);
        }
예제 #14
0
        public override void UpdateBeforeSimulation()
        {
            if (HyperDriveLogic.hyperDriveBlock.Enabled)
            {
                //var viewDistance = Session.SessionSettings.ViewDistance;
                var viewSphere = new BoundingSphereD(MyAPIGateway.Session.Player.GetPosition(), 50000);
                var entList    = new List <MyEntity>();
                MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref viewSphere, entList);

                foreach (var v in entList)
                {
                    if (v == HyperDriveLogic.hyperDriveBlock.CubeGrid)
                    {
                        continue;
                    }
                    if (HyperDriveLogic.hyper && HyperDriveLogic.hyperFactor > 30)
                    {
                        if (v is MyVoxelBase)
                        {
                            var myBase = v as MyVoxelBase;
                            if (myBase.ContentChanged)
                            {
                                continue;
                            }
                            v.Physics.Enabled = false;
                            v.Render.UpdateRenderObject(false);
                        }
                        else
                        {
                            v.Render.UpdateRenderObject(false);
                        }
                    }
                    else if (!HyperDriveLogic.hyper)
                    {
                        if (v is MyVoxelBase)
                        {
                            v.Physics.Enabled = true;
                        }
                        v.Render.UpdateRenderObject(true);
                    }
                }
            }
        }
예제 #15
0
        // This is broken as f**k
        public static IEnumerable <MyEntity> DetectPlayersInSphere(Vector3D detectionCenter, double range, bool reportOrigin = false)
        {
            if (reportOrigin)
            {
                AddGpsLocation($"DetectPlayersInSphere {range}", detectionCenter);
            }

            BoundingSphereD pruneSphere = new BoundingSphereD(detectionCenter, range);
            List <MyEntity> pruneList   = new List <MyEntity>();

            MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref pruneSphere, pruneList);
            List <IMyPlayer> players = new List <IMyPlayer>();

            MyAPIGateway.Multiplayer.Players.GetPlayers(players, x => ValidPlayer(x.IdentityId));
            pruneList.RemoveAll(x => players.Any(y => y.IdentityId != x.EntityId));
            foreach (MyEntity ent in pruneList)
            {
                AddGpsLocation($"DetectPlayersInSphere ({range}): {((IMyEntity)ent).DisplayName}", ((IMyEntity)ent).GetPosition());
            }
            return(pruneList);
        }
예제 #16
0
        void FindFloatingObjects()
        {
            var entities = Mod.Entities;

            entities.Clear();
            floatingObjects.Clear();

            if (Range < RANGE_OFF_EXCLUSIVE || !block.IsWorking || !block.CubeGrid.Physics.Enabled)
            {
                if ((NeedsUpdate & MyEntityUpdateEnum.EACH_FRAME) != 0)
                {
                    UpdateEmissive();
                    NeedsUpdate &= ~MyEntityUpdateEnum.EACH_FRAME;
                }

                return;
            }

            if ((NeedsUpdate & MyEntityUpdateEnum.EACH_FRAME) == 0)
            {
                NeedsUpdate |= MyEntityUpdateEnum.EACH_FRAME;
            }

            var collectPos = block.WorldMatrix.Translation + (block.WorldMatrix.Forward * offset);
            var sphere     = new BoundingSphereD(collectPos, Range + 10);

            MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref sphere, entities, MyEntityQueryType.Dynamic);

            foreach (var ent in entities)
            {
                var floatingObject = ent as IMyFloatingObject;

                if (floatingObject != null && floatingObject.Physics != null)
                {
                    floatingObjects.Add(floatingObject);
                }
            }

            entities.Clear();
        }
예제 #17
0
        /// <summary>
        /// Returns the closest grid to the position
        /// </summary>
        public static MyCubeGrid GetApproximateGrid(Vector3 position, MyEntityQueryType queryType = MyEntityQueryType.Both)
        {
            BoundingSphereD sphere   = new BoundingSphereD(position, 1);
            List <MyEntity> entities = new List <MyEntity>();

            MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref sphere, entities, queryType);

            foreach (var entity in entities)
            {
                if (entity.IsPreview || entity.Physics == null)
                {
                    continue;
                }

                if (entity is MyCubeGrid)
                {
                    return(entity as MyCubeGrid);
                }
            }
            entities.Clear();
            return(null);
        }
예제 #18
0
        /// <summary>
        /// Checks if a position is airtight
        /// </summary>
        public static bool IsPositionAirtight(Vector3D position)
        {
            if (!MyAPIGateway.Session.SessionSettings.EnableOxygenPressurization)
            {
                return(false);
            }

            BoundingSphereD sphere   = new BoundingSphereD(position, 5);
            List <MyEntity> entities = new List <MyEntity>();

            MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref sphere, entities);

            foreach (var entity in entities)
            {
                MyCubeGrid grid = entity as MyCubeGrid;

                if (grid != null && grid.IsRoomAtPositionAirtight(grid.WorldToGridInteger(position)))
                {
                    return(true);
                }
            }
            return(false);
        }
예제 #19
0
        private void PrepEmpBlast()
        {
            var stackCount   = 0;
            var warHeadSize  = 0;
            var warHeadYield = 0d;
            var epiCenter    = Vector3D.Zero;

            WarHeadBlast empChild;

            while (EmpStore.TryDequeue(out empChild))
            {
                if (empChild.CustomData.Contains("@EMP"))
                {
                    stackCount++;
                    warHeadSize  = empChild.WarSize;
                    warHeadYield = empChild.Yield;
                    epiCenter   += empChild.Position;
                }
            }

            if (stackCount == 0)
            {
                EmpWork.EventComplete();
                return;
            }
            epiCenter /= stackCount;
            var rangeCap = MathHelper.Clamp(stackCount * warHeadYield, warHeadYield, SyncDist);

            _warHeadGridHits.Clear();
            _pruneWarGrids.Clear();

            var sphere = new BoundingSphereD(epiCenter, rangeCap);

            MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref sphere, _pruneWarGrids);

            foreach (var ent in _pruneWarGrids)
            {
                var grid = ent as MyCubeGrid;
                if (grid != null)
                {
                    ShieldGridComponent sComp;
                    grid.Components.TryGet(out sComp);
                    if (sComp?.DefenseShields != null && sComp.DefenseShields.NotFailed)
                    {
                        continue;
                    }

                    var gridCenter = grid.PositionComp.WorldVolume.Center;
                    var testDir    = Vector3D.Normalize(gridCenter - epiCenter);
                    var impactPos  = gridCenter + (testDir * -grid.PositionComp.WorldVolume.Radius);

                    IHitInfo hitInfo;
                    MyAPIGateway.Physics.CastRay(epiCenter, impactPos, out hitInfo, CollisionLayers.DefaultCollisionLayer);
                    if (hitInfo?.HitEntity == null)
                    {
                        _warHeadGridHits.Add(grid);
                    }
                }
            }

            EmpWork.StoreEmpBlast(epiCenter, warHeadSize, warHeadYield, stackCount, rangeCap);
        }
예제 #20
0
        internal void SeekEnemy()
        {
            var mineInfo      = Info.ConsumableDef.Trajectory.Mines;
            var detectRadius  = mineInfo.DetectRadius;
            var deCloakRadius = mineInfo.DeCloakRadius;

            var wakeRadius = detectRadius > deCloakRadius ? detectRadius : deCloakRadius;

            PruneSphere = new BoundingSphereD(Position, wakeRadius);
            var inRange  = false;
            var activate = false;
            var minDist  = double.MaxValue;

            if (!MineActivated)
            {
                MyEntity closestEnt = null;
                MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref PruneSphere, MyEntityList, MyEntityQueryType.Dynamic);
                for (int i = 0; i < MyEntityList.Count; i++)
                {
                    var ent       = MyEntityList[i];
                    var grid      = ent as MyCubeGrid;
                    var character = ent as IMyCharacter;
                    if (grid == null && character == null || ent.MarkedForClose || !ent.InScene)
                    {
                        continue;
                    }
                    Sandbox.ModAPI.Ingame.MyDetectedEntityInfo entInfo;
                    bool peace;
                    MyRelationsBetweenPlayerAndBlock newRelation;

                    if (!Info.Ai.CreateEntInfo(ent, Info.Ai.AiOwner, out entInfo))
                    {
                        continue;
                    }
                    switch (entInfo.Relationship)
                    {
                    case MyRelationsBetweenPlayerAndBlock.Owner:
                        continue;

                    case MyRelationsBetweenPlayerAndBlock.FactionShare:
                        continue;
                    }
                    var entSphere = ent.PositionComp.WorldVolume;
                    entSphere.Radius += Info.ConsumableDef.Const.CollisionSize;
                    var dist = MyUtils.GetSmallestDistanceToSphereAlwaysPositive(ref Position, ref entSphere);
                    if (dist >= minDist)
                    {
                        continue;
                    }
                    minDist    = dist;
                    closestEnt = ent;
                }
                MyEntityList.Clear();

                if (closestEnt != null)
                {
                    ForceNewTarget();
                    Info.Target.Entity = closestEnt;
                }
            }
            else if (Info.Target.Entity != null && !Info.Target.Entity.MarkedForClose)
            {
                var entSphere = Info.Target.Entity.PositionComp.WorldVolume;
                entSphere.Radius += Info.ConsumableDef.Const.CollisionSize;
                minDist           = MyUtils.GetSmallestDistanceToSphereAlwaysPositive(ref Position, ref entSphere);
            }
            else
            {
                TriggerMine(true);
            }

            if (EnableAv)
            {
                if (Info.AvShot.Cloaked && minDist <= deCloakRadius)
                {
                    Info.AvShot.Cloaked = false;
                }
                else if (Info.AvShot.ConsumableDef.Trajectory.Mines.Cloak && !Info.AvShot.Cloaked && minDist > deCloakRadius)
                {
                    Info.AvShot.Cloaked = true;
                }
            }

            if (minDist <= Info.ConsumableDef.Const.CollisionSize)
            {
                activate = true;
            }
            if (minDist <= detectRadius)
            {
                inRange = true;
            }
            if (MineActivated)
            {
                if (!inRange)
                {
                    TriggerMine(true);
                }
            }
            else if (inRange)
            {
                ActivateMine();
            }

            if (activate)
            {
                TriggerMine(false);
                MyEntityList.Add(Info.Target.Entity);
            }
        }
예제 #21
0
        void Scan()
        {
            m_lastScan = MySession.Static.GameplayFrameCounter;
            ProfilerShort.Begin("QueryTargets");
            BoundingSphereD bs = new BoundingSphereD(Vector3D.Transform(m_queryLocal.Center, m_grid.WorldMatrix), m_queryLocal.Radius);

            m_targetRoots.Clear();
            m_targetBlocks.Clear();

            ProfilerShort.Begin("MyGamePruningStructure.GetAllTop...");
            MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref bs, m_targetRoots);
            ProfilerShort.End();

            int targetCount = m_targetRoots.Count;

            m_ownersA.AddList(m_grid.SmallOwners);
            m_ownersA.AddList(m_grid.BigOwners);
            for (int i = 0; i < targetCount; i++)
            {
                var grid = m_targetRoots[i] as MyCubeGrid; //perf: using grid owners to not querry friendly ships for blocks
                if (grid != null)
                {
                    if (grid.Physics != null && !grid.Physics.Enabled)
                    {
                        continue;
                    }

                    ProfilerShort.Begin("Friend checks");
                    bool enemy = false;
                    if (grid.BigOwners.Count == 0 && grid.SmallOwners.Count == 0)
                    {
                        foreach (var owner in m_ownersA)
                        {
                            if (MyIDModule.GetRelation(owner, 0) == VRage.Game.MyRelationsBetweenPlayerAndBlock.Enemies)
                            {
                                enemy = true;
                                break;
                            }
                        }
                    }
                    else
                    {
                        m_ownersB.AddList(grid.BigOwners);
                        m_ownersB.AddList(grid.SmallOwners);


                        foreach (var owner in m_ownersA)
                        {
                            foreach (var other in m_ownersB)
                            {
                                if (MyIDModule.GetRelation(owner, other) == VRage.Game.MyRelationsBetweenPlayerAndBlock.Enemies)
                                {
                                    enemy = true;
                                    break;
                                }
                            }
                        }
                        m_ownersB.Clear();
                    }
                    ProfilerShort.End();
                    if (enemy)
                    {
                        ProfilerShort.Begin("grid.Hierarchy.QuerySphere");
                        var list = m_targetBlocks.GetOrAddList(grid);
                        grid.Hierarchy.QuerySphere(ref bs, list);
                        ProfilerShort.End();
                    }
                    else
                    {
                        MyIDModule module;
                        //performance unfriendly case when grid is not clearly neutral or enemy
                        foreach (var block in grid.GetFatBlocks())
                        {
                            var moduleOwner = ((MyEntity)block) as IMyComponentOwner <MyIDModule>;
                            if (!(moduleOwner != null && moduleOwner.GetComponent(out module)))
                            {
                                continue;
                            }

                            var myID = block.OwnerId;
                            foreach (var owner in m_ownersA)
                            {
                                if (MyIDModule.GetRelation(owner, myID) == VRage.Game.MyRelationsBetweenPlayerAndBlock.Enemies)
                                {
                                    enemy = true;
                                    break;
                                }
                            }
                            if (enemy)
                            {
                                break;
                            }
                        }

                        if (enemy)
                        {
                            ProfilerShort.Begin("grid.Hierarchy.QuerySphere");
                            var list = m_targetBlocks.GetOrAddList(grid);
                            grid.Hierarchy.QuerySphere(ref bs, list);
                            ProfilerShort.End();
                        }
                    }
                }
            }
            m_ownersA.Clear();

            ProfilerShort.Begin("Filter small objects");
            for (int i = m_targetRoots.Count - 1; i >= 0; i--)
            {
                var target = m_targetRoots[i];
                if (target is Sandbox.Game.Entities.Debris.MyDebrisBase ||
                    target is MyFloatingObject ||
                    (target.Physics != null && !target.Physics.Enabled) ||
                    target.GetTopMostParent().Physics == null || !target.GetTopMostParent().Physics.Enabled)
                {
                    m_targetRoots.RemoveAtFast(i);
                }
            }
            ProfilerShort.End();
            ProfilerShort.End();
        }
예제 #22
0
        /// <summary>
        /// Called when a node is reached. Tests against targets and creates new nodes.
        /// </summary>
        /// <param name="pnSet">The active set.</param>
        /// <param name="currentNode">The node that was reached.</param>
        /// <param name="input">Param for CanTravelSegment, Offset and Direction should be correct.</param>
        /// <param name="proximity">Result from CanTravelSegment, how close the ship would come to an entity when traveling to this node from its parent.</param>
        private void ReachedNode(FindingSet pnSet, ref PathNode currentNode, ref PathTester.TestInput input, float proximity)
        {
            // impose a penalty for going near entities, this does not affect this node but will affect its children
            // this really helps prevent pathfinder getting stuck but the penalty might be too high
            float penalty = 10f * (100f - MathHelper.Clamp(proximity, 0f, 100f));

            Log.DebugLog(SetName(pnSet) + " Reached node: " + ReportRelativePosition(currentNode.Position) + " from " + ReportRelativePosition(pnSet.m_reachedNodes[currentNode.ParentKey].Position) +
                         ", reached: " + pnSet.m_reachedNodes.Count + ", open: " + pnSet.m_openNodes.Count + ", proximity: " + proximity + ", penalty: " + penalty);
            currentNode.DistToCur += penalty;
            long cNodePosHash = currentNode.Key;

            pnSet.m_reachedNodes.Add(cNodePosHash, currentNode);

            if (!m_canChangeCourse)
            {
                // test from current node position to destination
                Log.DebugLog(SetName(pnSet) + " Running backwards search", Logger.severity.ERROR, condition: pnSet != m_forward);
                Vector3D.Subtract(ref m_currentPosition, ref pnSet.m_referencePosition, out input.Offset);
                input.Length = (float)Vector3D.Distance(currentNode.Position, pnSet.m_referencePosition);
                if (CanTravelSegment(ref input, out proximity))
                {
                    Log.DebugLog(SetName(pnSet) + " Reached destination from node: " + ReportRelativePosition(currentNode.Position));
                    Log.DebugLog("Backwards start is not reference position", Logger.severity.ERROR, condition: m_backwardList[0].m_startPosition != pnSet.m_referencePosition);
                    BuildPath(cNodePosHash, m_backwardList[0], pnSet.m_referencePosition.GetHash());
                    return;
                }
#if SHOW_REACHED
                ShowPosition(currentNode, SetName(pnSet));
#endif
                return;
            }

            foreach (PathNodeSet target in pnSet.m_targets)
            {
                if (target.HasReached(cNodePosHash))
                {
                    Log.DebugLog(SetName(pnSet) + " Opposite set has same position");
                    if (pnSet == m_forward)
                    {
                        BuildPath(cNodePosHash, target, cNodePosHash);
                    }
                    else
                    {
                        BuildPath(cNodePosHash, pnSet, cNodePosHash);
                    }
                    return;
                }
            }

            Vector3D        obstructPosition = m_obstructingEntity.GetPosition();
            Vector3D        currentNodeWorld; Vector3D.Add(ref obstructPosition, ref currentNode.Position, out currentNodeWorld);
            BoundingSphereD sphere = new BoundingSphereD()
            {
                Center = currentNodeWorld, Radius = m_autopilotShipBoundingRadius + 100f
            };
            m_entitiesRepulse.Clear();             // use repulse list as prune/avoid is needed for CanTravelSegment
            MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref sphere, m_entitiesRepulse);
            if (m_entitiesRepulse.Count == 0 && BlueSkyReached(pnSet, currentNode, ref currentNodeWorld))
            {
                return;
            }

#if SHOW_REACHED
            ShowPosition(currentNode, SetName(pnSet));
#endif

            if (pnSet.NodeDistance < FindingSet.DefaultNodeDistance && pnSet.m_reachedNodes.Count % 10 == 0 && pnSet.m_openNodes.Count > 100)
            {
                Log.DebugLog("Reached: " + pnSet.m_reachedNodes.Count + ", trying with higher node distance");
                pnSet.ChangeNodeDistance(false, m_canChangeCourse);
                return;
            }

            pnSet.CreatePathNode(ref currentNode, m_canChangeCourse);
        }
예제 #23
0
        private void CheckHits()
        {
            for (int x = ActiveProjetiles.Count - 1; x >= 0; x--)
            {
                var p = ActiveProjetiles[x];

                if ((int)p.State > 3)
                {
                    continue;
                }

                if (p.Info.Ai.ProInMinCacheRange > 99999 && !p.Info.Ai.AccelChecked)
                {
                    p.Info.Ai.ComputeAccelSphere();
                }

                p.UseEntityCache = p.Info.Ai.AccelChecked && p.Info.DistanceTraveled <= p.Info.Ai.NearByEntitySphere.Radius && !p.Info.Ai.MarkedForClose;
                var triggerRange  = p.Info.ConsumableDef.Const.EwarTriggerRange > 0 && !p.Info.EwarAreaPulse ? p.Info.ConsumableDef.Const.EwarTriggerRange : 0;
                var useEwarSphere = (triggerRange > 0 || p.Info.EwarActive) && p.Info.ConsumableDef.Const.Pulse;
                p.Beam = useEwarSphere ? new LineD(p.Position + (-p.Info.Direction * p.Info.ConsumableDef.Const.EwarTriggerRange), p.Position + (p.Info.Direction * p.Info.ConsumableDef.Const.EwarTriggerRange)) : new LineD(p.LastPosition, p.Position);

                if ((p.FieldTime <= 0 && p.State != ProjectileState.OneAndDone && p.Info.DistanceTraveled * p.Info.DistanceTraveled >= p.DistanceToTravelSqr))
                {
                    p.PruneSphere.Center = p.Position;
                    p.PruneSphere.Radius = p.Info.ConsumableDef.Const.DetonationRadius;

                    var dInfo = p.Info.ConsumableDef.AreaEffect.Detonation;
                    if (p.MoveToAndActivate || dInfo.DetonateOnEnd && p.Info.Age >= dInfo.MinArmingTime && (!dInfo.ArmOnlyOnHit || p.Info.ObjectsHit > 0))
                    {
                        if (!p.UseEntityCache)
                        {
                            MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref p.PruneSphere, p.MyEntityList, p.PruneQuery);
                        }

                        if (p.Info.System.TrackProjectile)
                        {
                            foreach (var lp in p.Info.Ai.LiveProjectile)
                            {
                                if (p.PruneSphere.Contains(lp.Position) != ContainmentType.Disjoint && lp != p.Info.Target.Projectile)
                                {
                                    ProjectileHit(p, lp, p.Info.ConsumableDef.Const.CollisionIsLine, ref p.Beam);
                                }
                            }
                        }

                        p.State = ProjectileState.Detonate;

                        if (p.EnableAv)
                        {
                            p.Info.AvShot.ForceHitParticle = true;
                        }
                    }
                    else
                    {
                        p.State = ProjectileState.Detonate;
                    }

                    p.EarlyEnd            = true;
                    p.Info.Hit.SurfaceHit = p.Position;
                    p.Info.Hit.LastHit    = p.Position;
                }

                p.SphereCheck = false;
                p.LineCheck   = false;

                if (p.MineSeeking && !p.MineTriggered)
                {
                    p.SeekEnemy();
                }
                else if (useEwarSphere)
                {
                    if (p.Info.EwarActive)
                    {
                        p.PruneSphere = new BoundingSphereD(p.Position, 0).Include(new BoundingSphereD(p.LastPosition, 0));
                        var currentRadius = p.Info.TriggerGrowthSteps < p.Info.ConsumableDef.Const.AreaEffectSize ? p.Info.TriggerMatrix.Scale.AbsMax() : p.Info.ConsumableDef.Const.AreaEffectSize;
                        if (p.PruneSphere.Radius < currentRadius)
                        {
                            p.PruneSphere.Center = p.Position;
                            p.PruneSphere.Radius = currentRadius;
                        }
                    }
                    else
                    {
                        p.PruneSphere = new BoundingSphereD(p.Position, triggerRange);
                    }

                    if (p.PruneSphere.Contains(p.DeadSphere) == ContainmentType.Disjoint)
                    {
                        p.SphereCheck = true;
                    }
                }
                else if (p.Info.ConsumableDef.Const.CollisionIsLine)
                {
                    p.PruneSphere.Center = p.Position;
                    p.PruneSphere.Radius = p.Info.ConsumableDef.Const.CollisionSize;
                    if (p.Info.ConsumableDef.Const.IsBeamWeapon || p.PruneSphere.Contains(p.DeadSphere) == ContainmentType.Disjoint)
                    {
                        p.LineCheck = true;
                    }
                }
                else
                {
                    p.SphereCheck = true;
                    p.PruneSphere = new BoundingSphereD(p.Position, 0).Include(new BoundingSphereD(p.LastPosition, 0));
                    if (p.PruneSphere.Radius < p.Info.ConsumableDef.Const.CollisionSize)
                    {
                        p.PruneSphere.Center = p.Position;
                        p.PruneSphere.Radius = p.Info.ConsumableDef.Const.CollisionSize;
                    }
                }
            }

            var apCount  = ActiveProjetiles.Count;
            var minCount = Session.Settings.Enforcement.ServerOptimizations ? 96 : 99999;
            var stride   = apCount < minCount ? 100000 : 48;

            MyAPIGateway.Parallel.For(0, apCount, i =>
            {
                var p = ActiveProjetiles[i];
                if (p.SphereCheck)
                {
                    if (p.DynamicGuidance && p.PruneQuery == MyEntityQueryType.Dynamic && p.Info.System.Session.Tick60)
                    {
                        p.CheckForNearVoxel(60);
                    }

                    if (!p.UseEntityCache)
                    {
                        MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref p.PruneSphere, p.MyEntityList, p.PruneQuery);
                    }
                }
                else if (p.LineCheck)
                {
                    if (p.DynamicGuidance && p.PruneQuery == MyEntityQueryType.Dynamic && p.Info.System.Session.Tick60)
                    {
                        p.CheckForNearVoxel(60);
                    }

                    if (!p.UseEntityCache)
                    {
                        MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref p.Beam, p.MySegmentList, p.PruneQuery);
                    }
                }

                p.CheckType = p.UseEntityCache && p.SphereCheck ? CheckTypes.CachedSphere : p.UseEntityCache ? CheckTypes.CachedRay : p.SphereCheck ? CheckTypes.Sphere : CheckTypes.Ray;

                if (p.Info.Target.IsProjectile || p.UseEntityCache && p.Info.Ai.NearByEntityCache.Count > 0 || p.CheckType == CheckTypes.Ray && p.MySegmentList.Count > 0 || p.CheckType == CheckTypes.Sphere && p.MyEntityList.Count > 0)
                {
                    ValidateHits.Add(p);
                }
            }, stride);
            ValidateHits.ApplyAdditions();
        }
        /// <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;
                        }
                    }
                }
            }
        }
예제 #25
0
        private bool CalculateSafePositionAndSpawn(bool keepOriginalLocation, Vector3D Target)
        {
            //This has to be ran on the main game thread!
            if (keepOriginalLocation)
            {
                var sphere = FindBoundingSphere(_grids);
                sphere.Center = Target;
                List <MyEntity> entities = new List <MyEntity>();
                MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref sphere, entities);


                bool PotentialGrids = false;
                foreach (var entity in entities)
                {
                    if (entity is MyCubeGrid)
                    {
                        PotentialGrids = true;
                        _Response.Respond("There are potentially other grids in the way. Attempting to spawn around the location to avoid collisions.");
                        break;
                    }
                }


                if (PotentialGrids)
                {
                    var pos = FindPastePosition(Target);
                    if (!pos.HasValue)
                    {
                        _Response.Respond("No free spawning zone found! Stopping load!");
                        return(false);
                    }

                    if (!UpdateGridsPosition(pos.Value))
                    {
                        _Response.Respond("The File to be imported does not seem to be compatible with the server!");
                        return(false);
                    }
                    else
                    {
                        return(true);
                    }
                }
                else
                {
                    return(true);
                }
            }


            //Everything else is loading for near point
            if (!keepOriginalLocation)
            {
                /* Where do we want to paste the grids? Lets find out. */
                var pos = FindPastePosition(Target);
                if (pos == null)
                {
                    _Response.Respond("No free spawning zone found! Stopping load!");
                    return(false);
                }

                var newPosition = pos.Value;

                /* Update GridsPosition if that doesnt work get out of here. */
                if (!UpdateGridsPosition(newPosition))
                {
                    _Response.Respond("The File to be imported does not seem to be compatible with the server!");
                    return(false);
                }
            }
            return(true);
        }
예제 #26
0
        public static bool LoadShipBlueprint(MyObjectBuilder_ShipBlueprintDefinition shipBlueprint,
                                             Vector3D playerPosition, bool keepOriginalLocation, long steamID, string Name, CommandContext context = null, bool force = false)
        {
            var grids = shipBlueprint.CubeGrids;

            if (grids == null || grids.Length == 0)
            {
                Log.Warn("No grids in blueprint!");

                if (context != null)
                {
                    context.Respond("No grids in blueprint!");
                }

                return(false);
            }

            foreach (var grid in grids)
            {
                foreach (MyObjectBuilder_CubeBlock block in grid.CubeBlocks)
                {
                    long ownerID = AlliancePlugin.GetIdentityByNameOrId(steamID.ToString()).IdentityId;
                    block.Owner   = ownerID;
                    block.BuiltBy = ownerID;
                }
            }

            List <MyObjectBuilder_EntityBase> objectBuilderList = new List <MyObjectBuilder_EntityBase>(grids.ToList());

            if (!keepOriginalLocation)
            {
                /* Where do we want to paste the grids? Lets find out. */
                var pos = FindPastePosition(grids, playerPosition);
                if (pos == null)
                {
                    Log.Warn("No free Space found!");

                    if (context != null)
                    {
                        context.Respond("No free space available!");
                    }

                    return(false);
                }

                var newPosition = pos.Value;

                /* Update GridsPosition if that doesnt work get out of here. */
                if (!UpdateGridsPosition(grids, newPosition))
                {
                    if (context != null)
                    {
                        context.Respond("The File to be imported does not seem to be compatible with the server!");
                    }

                    return(false);
                }
                Sandbox.Game.Entities.Character.MyCharacter player = MySession.Static.Players.GetPlayerByName(AlliancePlugin.GetIdentityByNameOrId(steamID.ToString()).DisplayName).Character;
                MyGps           gps           = CreateGps(pos.Value, Color.LightGreen, 60, Name);
                MyGpsCollection gpsCollection = (MyGpsCollection)MyAPIGateway.Session?.GPS;
                MyGps           gpsRef        = gps;
                long            entityId      = 0L;
                entityId = gps.EntityId;
                gpsCollection.SendAddGps(player.GetPlayerIdentityId(), ref gpsRef, entityId, true);
            }
            else if (!force)
            {
                var sphere = FindBoundingSphere(grids);

                var position = grids[0].PositionAndOrientation.Value;

                sphere.Center = position.Position;

                List <MyEntity> entities = new List <MyEntity>();
                MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref sphere, entities);

                foreach (var entity in entities)
                {
                    if (entity is MyCubeGrid)
                    {
                        if (context != null)
                        {
                            context.Respond("There are potentially other grids in the way. If you are certain is free you can set 'force' to true!");
                        }

                        return(false);
                    }
                }
            }
            /* Stop grids */
            foreach (var grid in grids)
            {
                grid.AngularVelocity = new SerializableVector3();
                grid.LinearVelocity  = new SerializableVector3();

                Random random = new Random();
            }
            /* Remapping to prevent any key problems upon paste. */
            MyEntities.RemapObjectBuilderCollection(objectBuilderList);

            bool hasMultipleGrids = objectBuilderList.Count > 1;

            if (!hasMultipleGrids)
            {
                foreach (var ob in objectBuilderList)
                {
                    MyEntities.CreateFromObjectBuilderParallel(ob, true);
                }
            }
            else
            {
                MyEntities.Load(objectBuilderList, out _);
            }

            return(true);
        }
예제 #27
0
        private void CheckHits()
        {
            foreach (var p in ActiveProjetiles)
            {
                p.Miss = false;

                if (!p.Active || (int)p.State > 3)
                {
                    continue;
                }
                var triggerRange  = p.Info.AmmoDef.Const.EwarTriggerRange > 0 && !p.Info.TriggeredPulse ? p.Info.AmmoDef.Const.EwarTriggerRange : 0;
                var useEwarSphere = triggerRange > 0 || p.Info.EwarActive;
                p.Beam = useEwarSphere ? new LineD(p.Position + (-p.Info.Direction * p.Info.AmmoDef.Const.EwarTriggerRange), p.Position + (p.Info.Direction * p.Info.AmmoDef.Const.EwarTriggerRange)) : new LineD(p.LastPosition, p.Position);

                if ((p.FieldTime <= 0 && p.State != ProjectileState.OneAndDone && p.Info.DistanceTraveled * p.Info.DistanceTraveled >= p.DistanceToTravelSqr))
                {
                    var dInfo = p.Info.AmmoDef.AreaEffect.Detonation;
                    p.PruneSphere.Center = p.Position;
                    p.PruneSphere.Radius = dInfo.DetonationRadius;

                    if (p.MoveToAndActivate || dInfo.DetonateOnEnd && (!dInfo.ArmOnlyOnHit || p.Info.ObjectsHit > 0))
                    {
                        MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref p.PruneSphere, p.CheckList,
                                                                             p.PruneQuery);
                        for (int i = 0; i < p.CheckList.Count; i++)
                        {
                            p.SegmentList.Add(new MyLineSegmentOverlapResult <MyEntity>
                            {
                                Distance = 0, Element = p.CheckList[i]
                            });
                        }
                        if (p.Info.System.TrackProjectile)
                        {
                            foreach (var lp in p.Info.Ai.LiveProjectile)
                            {
                                if (p.PruneSphere.Contains(lp.Position) != ContainmentType.Disjoint && lp != p.Info.Target.Projectile)
                                {
                                    ProjectileHit(p, lp, p.Info.AmmoDef.Const.CollisionIsLine, ref p.Beam);
                                }
                            }
                        }

                        p.CheckList.Clear();
                        p.State            = ProjectileState.Detonate;
                        p.ForceHitParticle = true;
                    }
                    else
                    {
                        p.State = ProjectileState.Detonate;
                    }

                    p.Hit.HitPos = p.Position;
                }

                var sphere = false;
                var line   = false;

                if (p.MineSeeking && !p.MineTriggered)
                {
                    p.SeekEnemy();
                }
                else if (useEwarSphere)
                {
                    if (p.Info.EwarActive)
                    {
                        p.PruneSphere = new BoundingSphereD(p.Position, 0).Include(new BoundingSphereD(p.LastPosition, 0));
                        var currentRadius = p.Info.TriggerGrowthSteps < p.Info.AmmoDef.Const.AreaEffectSize ? p.Info.TriggerMatrix.Scale.AbsMax() : p.Info.AmmoDef.Const.AreaEffectSize;
                        if (p.PruneSphere.Radius < currentRadius)
                        {
                            p.PruneSphere.Center = p.Position;
                            p.PruneSphere.Radius = currentRadius;
                        }
                    }
                    else
                    {
                        p.PruneSphere = new BoundingSphereD(p.Position, triggerRange);
                    }

                    if (p.PruneSphere.Contains(p.DeadSphere) == ContainmentType.Disjoint)
                    {
                        sphere = true;
                    }
                }
                else if (p.Info.AmmoDef.Const.CollisionIsLine)
                {
                    p.PruneSphere.Center = p.Position;
                    p.PruneSphere.Radius = p.Info.AmmoDef.Const.CollisionSize;
                    if (p.Info.AmmoDef.Const.IsBeamWeapon || p.PruneSphere.Contains(p.DeadSphere) == ContainmentType.Disjoint)
                    {
                        line = true;
                    }
                }
                else
                {
                    sphere        = true;
                    p.PruneSphere = new BoundingSphereD(p.Position, 0).Include(new BoundingSphereD(p.LastPosition, 0));
                    if (p.PruneSphere.Radius < p.Info.AmmoDef.Const.CollisionSize)
                    {
                        p.PruneSphere.Center = p.Position;
                        p.PruneSphere.Radius = p.Info.AmmoDef.Const.CollisionSize;
                    }
                }

                if (sphere)
                {
                    if (p.DynamicGuidance && p.PruneQuery == MyEntityQueryType.Dynamic && p.Info.Ai.Session.Tick60)
                    {
                        p.CheckForNearVoxel(60);
                    }

                    MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref p.PruneSphere, p.CheckList, p.PruneQuery);
                    for (int i = 0; i < p.CheckList.Count; i++)
                    {
                        p.SegmentList.Add(new MyLineSegmentOverlapResult <MyEntity> {
                            Distance = 0, Element = p.CheckList[i]
                        });
                    }
                    p.CheckList.Clear();
                }
                else if (line)
                {
                    if (p.DynamicGuidance && p.PruneQuery == MyEntityQueryType.Dynamic && p.Info.Ai.Session.Tick60)
                    {
                        p.CheckForNearVoxel(60);
                    }
                    MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref p.Beam, p.SegmentList, p.PruneQuery);
                }

                if (p.Info.Target.IsProjectile || p.SegmentList.Count > 0)
                {
                    ValidateHits.Add(p);
                    continue;
                }

                p.Miss = true;
                p.Info.HitList.Clear();
            }
        }
예제 #28
0
        private bool CheckEnemyDistance(LoadType LoadingAtSavePoint, Vector3D Position = new Vector3D())
        {
            if (LoadingAtSavePoint == LoadType.ForceLoadMearPlayer)
            {
                Position = PlayerPosition;
            }

            MyFaction PlayersFaction = MySession.Static.Factions.GetPlayerFaction(IdentityID);
            bool      EnemyFoundFlag = false;



            if (Config.DistanceCheck > 0)
            {
                //Check enemy location! If under limit return!

                foreach (MyPlayer P in MySession.Static.Players.GetOnlinePlayers())
                {
                    if (P.Character == null || P.Character.MarkedForClose)
                    {
                        continue;
                    }

                    Vector3D Pos;
                    if (P.Character.IsUsing is MyCryoChamber || P.Character.IsUsing is MyCockpit)
                    {
                        Pos = (P.Character.IsUsing as MyCockpit).PositionComp.GetPosition();
                    }
                    else
                    {
                        Pos = P.GetPosition();
                    }


                    long PlayerID = P.Identity.IdentityId;
                    if (PlayerID == 0L)
                    {
                        continue;
                    }
                    if (PlayerID == IdentityID)
                    {
                        continue;
                    }

                    MyFaction TargetPlayerFaction = MySession.Static.Factions.GetPlayerFaction(PlayerID);
                    if (PlayersFaction != null && TargetPlayerFaction != null)
                    {
                        if (PlayersFaction.FactionId == TargetPlayerFaction.FactionId)
                        {
                            continue;
                        }

                        //Neutrals count as allies not friends for some reason
                        MyRelationsBetweenFactions Relation = MySession.Static.Factions.GetRelationBetweenFactions(PlayersFaction.FactionId, TargetPlayerFaction.FactionId).Item1;
                        if (Relation == MyRelationsBetweenFactions.Neutral || Relation == MyRelationsBetweenFactions.Friends)
                        {
                            continue;
                        }
                    }


                    if (Vector3D.Distance(Position, Pos) == 0)
                    {
                        continue;
                    }

                    if (Vector3D.Distance(Position, Pos) <= Config.DistanceCheck)
                    {
                        Chat?.Respond("Unable to load grid! Enemy within " + Config.DistanceCheck + "m!");
                        GpsSender.SendGps(Position, "Failed Hangar Load! (Enemy nearby)", IdentityID);
                        EnemyFoundFlag = true;
                        break;
                    }
                }
            }


            if (Config.GridDistanceCheck > 0 && Config.GridCheckMinBlock > 0 && EnemyFoundFlag == false)
            {
                BoundingSphereD SpawnSphere = new BoundingSphereD(Position, Config.GridDistanceCheck);

                List <MyEntity> entities = new List <MyEntity>();
                MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref SpawnSphere, entities);



                //This is looping through all grids in the specified range. If we find an enemy, we need to break and return/deny spawning
                foreach (MyCubeGrid Grid in entities.OfType <MyCubeGrid>())
                {
                    if (Grid == null || Grid.MarkedForClose)
                    {
                        continue;
                    }

                    if (Grid.BigOwners.Count <= 0 || Grid.CubeBlocks.Count < Config.GridCheckMinBlock)
                    {
                        continue;
                    }

                    if (Grid.BigOwners.Contains(IdentityID))
                    {
                        continue;
                    }



                    //if the player isnt big owner, we need to scan for faction mates
                    bool FoundAlly = true;
                    foreach (long Owner in Grid.BigOwners)
                    {
                        MyFaction TargetPlayerFaction = MySession.Static.Factions.GetPlayerFaction(Owner);


                        if (PlayersFaction != null && TargetPlayerFaction != null)
                        {
                            if (PlayersFaction.FactionId == TargetPlayerFaction.FactionId)
                            {
                                continue;
                            }

                            MyRelationsBetweenFactions Relation = MySession.Static.Factions.GetRelationBetweenFactions(PlayersFaction.FactionId, TargetPlayerFaction.FactionId).Item1;
                            if (Relation == MyRelationsBetweenFactions.Enemies)
                            {
                                FoundAlly = false;
                                break;
                            }
                        }
                        else
                        {
                            FoundAlly = false;
                            break;
                        }
                    }


                    if (!FoundAlly)
                    {
                        //Stop loop
                        Chat?.Respond("Unable to load grid! Enemy within " + Config.GridDistanceCheck + "m!");
                        GpsSender.SendGps(Position, "Failed Hangar Load! (Enemy nearby)", IdentityID);
                        EnemyFoundFlag = true;
                        break;
                    }
                }
            }
            return(!EnemyFoundFlag);
        }
예제 #29
0
        /// <summary>
        /// Test if it is safe for the grid to rotate.
        /// </summary>
        /// <param name="axis">Normalized axis of rotation in world space.</param>
        /// <returns>True iff the path is clear.</returns>
        private bool in_TestRotate(Vector3 axis)
        {
            IMyCubeGrid myGrid       = m_block.CubeGrid;
            Vector3     centreOfMass = myGrid.Physics.CenterOfMassWorld;
            float       longestDim   = myGrid.GetLongestDim();

            // calculate height
            Matrix  toMyLocal     = myGrid.WorldMatrixNormalizedInv;
            Vector3 myLocalCoM    = Vector3.Transform(centreOfMass, toMyLocal);
            Vector3 myLocalAxis   = Vector3.Transform(axis, toMyLocal.GetOrientation());
            Vector3 myLocalCentre = myGrid.LocalAABB.Center;             // CoM may not be on ship (it now considers mass from attached grids)
            Ray     upper         = new Ray(myLocalCentre + myLocalAxis * longestDim * 2f, -myLocalAxis);
            float?  upperBound    = myGrid.LocalAABB.Intersects(upper);

            if (!upperBound.HasValue)
            {
                Log.AlwaysLog("Math fail, upperBound does not have a value", Logger.severity.FATAL);
            }
            Ray   lower      = new Ray(myLocalCentre - myLocalAxis * longestDim * 2f, myLocalAxis);
            float?lowerBound = myGrid.LocalAABB.Intersects(lower);

            if (!lowerBound.HasValue)
            {
                Log.AlwaysLog("Math fail, lowerBound does not have a value", Logger.severity.FATAL);
            }
            //Log.DebugLog("LocalAABB: " + myGrid.LocalAABB + ", centre: " + myLocalCentre + ", axis: " + myLocalAxis + ", longest dimension: " + longestDim + ", upper ray: " + upper + ", lower ray: " + lower);
            float height = longestDim * 4f - upperBound.Value - lowerBound.Value;

            float furthest = 0f;

            foreach (IMyCubeGrid grid in AttachedGrid.AttachedGrids(myGrid, Attached.AttachedGrid.AttachmentKind.Physics, true))
            {
                CubeGridCache cache = CubeGridCache.GetFor(grid);
                if (cache == null)
                {
                    return(false);
                }
                foreach (Vector3I cell in cache.OccupiedCells())
                {
                    Vector3 rejection       = Vector3.Reject(cell * myGrid.GridSize, myLocalAxis);
                    float   cellDistSquared = Vector3.DistanceSquared(myLocalCoM, rejection);
                    if (cellDistSquared > furthest)
                    {
                        furthest = cellDistSquared;
                    }
                }
            }
            float length = (float)Math.Sqrt(furthest) + myGrid.GridSize;

            //Log.DebugLog("height: " + height + ", length: " + length);

            BoundingSphereD surroundingSphere = new BoundingSphereD(centreOfMass, Math.Max(length, height) * MathHelper.Sqrt2);

            m_obstructions.Clear();
            MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref surroundingSphere, m_obstructions);

            LineSegment axisSegment = new LineSegment();

            m_closestPlanet = null;

            foreach (MyEntity entity in m_collector.Invoke(m_obstructions))
            {
                if (entity is IMyVoxelBase)
                {
                    IMyVoxelMap voxel = entity as IMyVoxelMap;
                    if (voxel != null)
                    {
                        if (voxel.GetIntersectionWithSphere(ref surroundingSphere))
                        {
                            Log.DebugLog("Too close to " + voxel.getBestName() + ", CoM: " + centreOfMass.ToGpsTag("Centre of Mass") + ", required distance: " + surroundingSphere.Radius);
                            ObstructingEntity = voxel;
                            return(false);
                        }
                        continue;
                    }

                    if (m_closestPlanet == null)
                    {
                        MyPlanet planet = entity as MyPlanet;
                        if (planet == null)
                        {
                            continue;
                        }

                        double distToPlanetSq = Vector3D.DistanceSquared(centreOfMass, planet.PositionComp.GetPosition());
                        if (distToPlanetSq < planet.MaximumRadius * planet.MaximumRadius)
                        {
                            m_closestPlanet = planet;

                            if (m_planetObstruction)
                            {
                                Log.DebugLog("planet blocking");
                                ObstructingEntity = m_closestPlanet;
                                return(false);
                            }
                        }
                    }
                    continue;
                }

                IMyCubeGrid grid = entity as IMyCubeGrid;
                if (grid != null)
                {
                    Matrix  toLocal     = grid.WorldMatrixNormalizedInv;
                    Vector3 localAxis   = Vector3.Transform(axis, toLocal.GetOrientation());
                    Vector3 localCentre = Vector3.Transform(centreOfMass, toLocal);
                    axisSegment.From = localCentre - localAxis * height;
                    axisSegment.To   = localCentre + localAxis * height;

                    CubeGridCache cache = CubeGridCache.GetFor(grid);
                    if (cache == null)
                    {
                        return(false);
                    }
                    foreach (Vector3I cell in cache.OccupiedCells())
                    {
                        if (axisSegment.PointInCylinder(length, cell * grid.GridSize))
                        {
                            Log.DebugLog("axis segment: " + axisSegment.From + " to " + axisSegment.To + ", radius: " + length + ", hit " + grid.nameWithId() + " at " + cell);
                            ObstructingEntity = grid;
                            return(false);
                        }
                    }

                    continue;
                }

                Log.DebugLog("No tests for object: " + entity.getBestName(), Logger.severity.INFO);
                ObstructingEntity = entity;
                return(false);
            }

            MyAPIGateway.Utilities.TryInvokeOnGameThread(TestPlanet);
            ObstructingEntity = null;
            return(true);
        }
예제 #30
0
        private bool LoadShipBlueprint(MyObjectBuilder_ShipBlueprintDefinition shipBlueprint,
                                       Vector3D playerPosition, bool keepOriginalLocation, Chat chat, bool force = false)
        {
            var grids = shipBlueprint.CubeGrids;

            if (grids == null || grids.Length == 0)
            {
                Hangar.Debug("No grids in blueprint!");
                chat.Respond("No grids in blueprint!");

                return(false);
            }


            bool LoadNearPosition = false;
            //For loading in the same location

            ParallelSpawner Spawner  = new ParallelSpawner(grids);
            var             position = grids[0].PositionAndOrientation.Value;

            if (keepOriginalLocation)
            {
                var sphere = FindBoundingSphere(grids);



                sphere.Center = position.Position;

                List <MyEntity> entities = new List <MyEntity>();
                MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref sphere, entities);

                foreach (var entity in entities)
                {
                    if (entity is MyCubeGrid)
                    {
                        chat.Respond("There are potentially other grids in the way. Loading near the original point.");

                        LoadNearPosition = true;
                    }
                }

                if (!LoadNearPosition)
                {
                    /* Remapping to prevent any key problems upon paste. */
                    MyEntities.RemapObjectBuilderCollection(grids);

                    Spawner.Start();

                    return(true);
                }
            }



            /*
             *  Everything else is loading for near player
             *
             *
             *
             */



            /* Where do we want to paste the grids? Lets find out. */
            var pos = FindPastePosition(grids, position.Position);

            if (pos == null)
            {
                Hangar.Debug("No free Space found!");
                chat.Respond("No free space available!");

                return(false);
            }

            var newPosition = pos.Value;

            /* Update GridsPosition if that doesnt work get out of here. */
            if (!UpdateGridsPosition(grids, newPosition))
            {
                chat.Respond("The File to be imported does not seem to be compatible with the server!");

                return(false);
            }


            MyEntities.RemapObjectBuilderCollection(grids);
            Spawner.Start();
            return(true);
        }