protected void GenerateObjectSeeds(ref BoundingSphereD sphere)
        {
            ProfilerShort.Begin("GenerateObjectSeedsInBox");

            BoundingBoxD box = BoundingBoxD.CreateFromSphere(sphere);

            Vector3I cellId = Vector3I.Floor(box.Min / CELL_SIZE);

            for (var iter = GetCellsIterator(sphere); iter.IsValid(); iter.GetNext(out cellId))
            {
                if (m_cells.ContainsKey(cellId))
                {
                    continue;
                }

                var cellBox = new BoundingBoxD(cellId * CELL_SIZE, (cellId + 1) * CELL_SIZE);
                if (sphere.Contains(cellBox) == ContainmentType.Disjoint)
                {
                    continue;
                }

                var cell = GenerateProceduralCell(ref cellId);
                if (cell != null)
                {
                    m_cells.Add(cellId, cell);
                    var cellBBox = cell.BoundingVolume;
                    cell.proxyId = m_cellsTree.AddProxy(ref cellBBox, cell, 0);
                }
            }
            ProfilerShort.End();
        }
        public IEnumerable <OffenderProximityInfo> ScanProximity(IEnumerable <DefenderGridInfo> defenders)
        {
            var tmpNearEntities = new List <MyEntity>();

            foreach (var defender in defenders)
            {
                var lookout = _config.MaxProximity * 10;
                var sphere  = new BoundingSphereD(defender.Position, lookout);
                var bb      = BoundingBoxD.CreateFromSphere(sphere);
                var obb     = MyOrientedBoundingBoxD.CreateFromBoundingBox(bb);
                MyGamePruningStructure.GetAllEntitiesInOBB(ref obb, tmpNearEntities);

                foreach (var entity in tmpNearEntities)
                {
                    Log.Trace($"near entity: \"{entity.DisplayName}\"");

                    if (TryGetOffender(entity, defender, out var offender))
                    {
                        yield return(offender);
                    }
                }

                tmpNearEntities.Clear();
            }
        }
        /// <summary>
        /// Generates all Cells data that are within sphere, if they have not been generated.
        /// </summary>
        /// <param name="sphere">Bounding Sphere of the cells to generate</param>
        protected void GenerateObjectsData(ref BoundingSphereD sphere)
        {
            BoundingBoxD box = BoundingBoxD.CreateFromSphere(sphere);

            Vector3I cellId = Vector3I.Floor(box.Min / CELL_SIZE);

            for (var it = GetCellsIterator(sphere); it.IsValid(); it.GetNext(out cellId))
            {
                if (m_cells.ContainsKey(cellId))
                {
                    continue;
                }

                BoundingBoxD cellBounds = new BoundingBoxD(cellId * CELL_SIZE, (cellId + 1) * CELL_SIZE);
                if (!(sphere.Contains(cellBounds) != ContainmentType.Disjoint))
                {
                    continue;
                }

                MyProceduralCell cell = GenerateCell(ref cellId);
                if (cell != null)
                {
                    m_cells.Add(cellId, cell);

                    BoundingBoxD aabb = cell.BoundingVolume;
                    cell.proxyId = m_cellsTree.AddProxy(ref aabb, cell, 0u);
                }
            }
        }
예제 #4
0
 public static void AddBroadcaster(MyRadioBroadcaster broadcaster)
 {
     if (broadcaster.RadioProxyID == MyConstants.PRUNING_PROXY_ID_UNITIALIZED)
     {
         BoundingBoxD box = BoundingBoxD.CreateFromSphere(new BoundingSphereD(broadcaster.BroadcastPosition, broadcaster.BroadcastRadius));
         broadcaster.RadioProxyID = m_aabbTree.AddProxy(ref box, broadcaster, 0);
     }
 }
예제 #5
0
 public static void MoveBroadcaster(MyRadioBroadcaster broadcaster)
 {
     if (broadcaster.RadioProxyID != MyConstants.PRUNING_PROXY_ID_UNITIALIZED)
     {
         BoundingBoxD box = BoundingBoxD.CreateFromSphere(new BoundingSphereD(broadcaster.BroadcastPosition, broadcaster.BroadcastRadius));
         m_aabbTree.MoveProxy(broadcaster.RadioProxyID, ref box, Vector3.Zero);
     }
 }
예제 #6
0
        internal void CheckForNearVoxel(uint steps)
        {
            var possiblePos = BoundingBoxD.CreateFromSphere(new BoundingSphereD(Position, ((MaxSpeed) * (steps + 1) * StepConst) + Info.ConsumableDef.Const.CollisionSize));

            if (MyGamePruningStructure.AnyVoxelMapInBox(ref possiblePos))
            {
                PruneQuery = MyEntityQueryType.Both;
            }
        }
예제 #7
0
        protected virtual bool TryDrillBlocks(MyCubeGrid grid, Vector3 worldPoint, bool onlyCheck, out MyStringHash blockMaterial)
        {
            var invWorld           = grid.PositionComp.WorldMatrixNormalizedInv;
            var gridLocalPosCenter = Vector3.Transform(m_sensor.Center, invWorld);
            var gridLocalPos       = Vector3.Transform(m_sensor.FrontPoint, invWorld);
            var gridLocalTarget    = Vector3.Transform(worldPoint, invWorld);

            var gridSpacePos = Vector3I.Round(gridLocalPos / grid.GridSize);
            var block        = grid.GetCubeBlock(gridSpacePos);

            if (block != null)
            {
                if (block.BlockDefinition.PhysicalMaterial.Id.SubtypeId == MyStringHash.NullOrEmpty)
                {
                    blockMaterial = m_metalMaterial;
                }
                else
                {
                    blockMaterial = block.BlockDefinition.PhysicalMaterial.Id.SubtypeId;
                }
            }
            else
            {
                blockMaterial = MyStringHash.NullOrEmpty;
            }

            int createDebris = 0;

            if (!onlyCheck)
            {
                if (block != null && block is IMyDestroyableObject && block.CubeGrid.BlocksDestructionEnabled)
                {
                    var destroyable = (block as IMyDestroyableObject);
                    destroyable.DoDamage(60, MyDamageType.Drill, Sync.IsServer, attackerId: m_drillEntity != null ? m_drillEntity.EntityId : 0);
                    createDebris = grid.Physics.ApplyDeformation(0.25f, 1.5f, 2f, gridLocalTarget, Vector3.Normalize(gridLocalPos - gridLocalPosCenter), MyDamageType.Drill, attackerId: m_drillEntity != null ? m_drillEntity.EntityId : 0);
                }
            }

            m_target = createDebris != 0 ? null : block;

            bool success = false;

            if (block != null)
            {
                if (createDebris != 0)
                {
                    BoundingSphereD bsphere = m_cutOut.Sphere;
                    BoundingBoxD    aabb    = BoundingBoxD.CreateFromSphere(bsphere);
                    MyDebris.Static.CreateExplosionDebris(ref bsphere, block.CubeGrid, ref aabb, 0.3f);
                }

                success = true;
            }

            return(success);
        }
예제 #8
0
        internal static void OnProjectileMoved(Projectile projectile, ref Vector3D velocity)
        {
            if (projectile.PruningProxyId == -1)
            {
                return;
            }
            BoundingSphereD sphere = new BoundingSphereD(projectile.Position, projectile.Info.AmmoDef.Const.AreaEffectSize);
            BoundingBoxD    result;

            BoundingBoxD.CreateFromSphere(ref sphere, out result);
            projectile.Info.Ai.Session.ProjectileTree.MoveProxy(projectile.PruningProxyId, ref result, velocity);
        }
예제 #9
0
        internal static void RegisterProjectile(Projectile projectile)
        {
            if (projectile.PruningProxyId != -1)
            {
                return;
            }
            BoundingSphereD sphere = new BoundingSphereD(projectile.Position, projectile.Info.AmmoDef.Const.AreaEffectSize);
            BoundingBoxD    result;

            BoundingBoxD.CreateFromSphere(ref sphere, out result);
            projectile.PruningProxyId = projectile.Info.Ai.Session.ProjectileTree.AddProxy(ref result, projectile, 0U, true);
        }
예제 #10
0
 public static void AddBroadcaster(MyRadioBroadcaster broadcaster)
 {
     if (broadcaster.Parent is MyCubeBlock)
     {
         MyCubeGrid grid = (broadcaster.Parent as MyCubeBlock).CubeGrid;
         Debug.Assert(grid.InScene, "adding broadcaster when grid is not in scene");
     }
     if (broadcaster.RadioProxyID == MyConstants.PRUNING_PROXY_ID_UNITIALIZED)
     {
         BoundingBoxD box = BoundingBoxD.CreateFromSphere(new BoundingSphereD(broadcaster.BroadcastPosition, broadcaster.BroadcastRadius));
         broadcaster.RadioProxyID = m_aabbTree.AddProxy(ref box, broadcaster, 0);
     }
 }
예제 #11
0
        private void EnsureDetector(string researchKey, Ob_Trigger_Location trigger)
        {
            var key = new ResearchStatefulKey(researchKey, trigger.StateStorageKey);

            if (_detectors.ContainsKey(key))
            {
                return;
            }
            var data = new DetectorData(key, trigger);

            _detectors.Add(key, data);
            var aabb = BoundingBoxD.CreateFromSphere(data.Detector);

            data.Handle = _detectorTree.AddProxy(ref aabb, data, 0);
        }
        /// <summary>
        /// Gets all seeds within said bounds.
        /// If a cell inside the bounds is not loaded, it will generate the seed but wont load the cell.
        /// </summary>
        /// <param name="bounds">Bounds to get seeds from</param>
        /// <param name="list">List to put seeds into.</param>
        public void GetSeedsInBounds(BoundingSphereD bounds, List <MyObjectSeed> list)
        {
            BoundingBoxD box    = BoundingBoxD.CreateFromSphere(bounds);
            Vector3I     cellId = Vector3I.Floor(box.Min / m_cellSize);

            for (var it = GetCellsIterator(box); it.IsValid(); it.GetNext(out cellId))
            {
                if (m_loadedCells.ContainsKey(cellId))
                {
                    m_loadedCells[cellId].GetAll(list, false);
                }
                else
                {
                    MyProceduralCell cell = GenerateCellSeeds(cellId);
                    cell.GetAll(list);
                }
            }
        }
예제 #13
0
        protected virtual bool TryDrillBlocks(MyCubeGrid grid, Vector3 worldPoint, bool onlyCheck)
        {
            var invWorld           = grid.PositionComp.GetWorldMatrixNormalizedInv();
            var gridLocalPosCenter = Vector3.Transform(m_sensor.Center, invWorld);
            var gridLocalPos       = Vector3.Transform(m_sensor.FrontPoint, invWorld);
            var gridLocalTarget    = Vector3.Transform(worldPoint, invWorld);

            var gridSpacePos = Vector3I.Round(gridLocalPos / grid.GridSize);
            var block        = grid.GetCubeBlock(gridSpacePos);

            bool createDebris = false;

            if (!onlyCheck && MySession.Static.DestructibleBlocks)
            {
                if (block != null && block is IMyDestroyableObject)
                {
                    var destroyable = (block as IMyDestroyableObject);
                    destroyable.DoDamage(60, MyDamageType.Drill, Sync.IsServer);
                }
                createDebris = grid.Physics.ApplyDeformation(0.25f, 1.5f, 2f, gridLocalTarget, Vector3.Normalize(gridLocalPos - gridLocalPosCenter), MyDamageType.Drill);
            }

            m_target = createDebris ? null : block;

            bool success = false;

            if (block != null)
            {
                if (createDebris)
                {
                    BoundingSphereD bsphere = m_cutOut.Sphere;
                    BoundingBoxD    aabb    = BoundingBoxD.CreateFromSphere(bsphere);
                    MyDebris.Static.CreateExplosionDebris(ref bsphere, block.CubeGrid, ref aabb, 0.3f);
                }

                success = true;
            }

            return(success);
        }
예제 #14
0
        public static unsafe bool CutOutSphereFast(MyVoxelBase voxelMap, ref Vector3D center, float radius, out Vector3I cacheMin, out Vector3I cacheMax, bool notifyChanged)
        {
            Vector3I vectori;
            Vector3I vectori2;
            MatrixD  worldMatrixInvScaled = voxelMap.PositionComp.WorldMatrixInvScaled;
            MatrixD *xdPtr1 = (MatrixD *)ref worldMatrixInvScaled;

            xdPtr1.Translation += voxelMap.SizeInMetresHalf;
            BoundingBoxD shapeAabb = BoundingBoxD.CreateFromSphere(new BoundingSphereD(center, (double)radius)).TransformFast(worldMatrixInvScaled);

            ComputeShapeBounds(voxelMap, ref shapeAabb, Vector3.Zero, voxelMap.Storage.Size, out vectori, out vectori2);
            cacheMin = vectori - 1;
            cacheMax = (Vector3I)(vectori2 + 1);
            voxelMap.Storage.ClampVoxelCoord(ref cacheMin, 1);
            voxelMap.Storage.ClampVoxelCoord(ref cacheMax, 1);
            CutOutSphere voxelOperator = new CutOutSphere {
                RadSq  = radius * radius,
                Center = Vector3D.Transform(center, worldMatrixInvScaled) - (cacheMin - voxelMap.StorageMin)
            };

            voxelMap.Storage.ExecuteOperationFast <CutOutSphere>(ref voxelOperator, MyStorageDataTypeFlags.Content, ref cacheMin, ref cacheMax, notifyChanged);
            return(voxelOperator.Changed);
        }
        /// <summary>
        /// Marks cells to load or keep loaded inside the bounds
        /// </summary>
        /// <param name="bounds">Spherical bounds</param>
        public void MarkToLoadCellsInBounds(BoundingSphereD bounds)
        {
            BoundingBoxD box    = BoundingBoxD.CreateFromSphere(bounds);
            Vector3I     cellId = Vector3I.Floor(box.Min / m_cellSize);

            for (var it = GetCellsIterator(box); it.IsValid(); it.GetNext(out cellId))
            {
                if (m_toLoadCells.Contains(cellId))
                {
                    continue;
                }

                BoundingBoxD cellBounds = new BoundingBoxD(cellId * m_cellSize, (cellId + 1) * m_cellSize);
                if (bounds.Contains(cellBounds) == ContainmentType.Disjoint)
                {
                    continue;
                }

                m_toLoadCells.Add(cellId);
            }

            m_toLoadCells.ApplyAdditions();
        }
예제 #16
0
        public override void UpdateWorldAABB()
        {
            m_localAABB = new BoundingBoxD(new Vector3D(-0.5), new Vector3D(0.5));

            if (IsTypeSpot)
            {
                if (m_spotParamsDirty)
                {
                    UpdateSpotParams();
                }

                m_localAABB = m_spotBoundingBox;
                m_aabb      = m_spotBoundingBox;
            }
            else
            if (IsTypePoint || IsTypeHemisphere)
            {
                m_localAABB = BoundingBoxD.CreateFromSphere(m_pointBoundingSphere);
                m_aabb      = m_localAABB;
            }

            base.UpdateWorldAABB();
        }
예제 #17
0
        private void UpdateState(int end = 0)
        {
            for (int i = ActiveProjetiles.Count - 1; i >= end; i--)
            {
                var p = ActiveProjetiles[i];
                ++p.Info.Age;
                ++p.Info.Ai.MyProjectiles;
                p.Info.Ai.ProjectileTicker = p.Info.System.Session.Tick;

                switch (p.State)
                {
                case ProjectileState.Destroy:
                    p.DestroyProjectile();
                    continue;

                case ProjectileState.Dead:
                    continue;

                case ProjectileState.OneAndDone:
                case ProjectileState.Depleted:
                case ProjectileState.Detonate:
                    if (p.Info.Age == 0 && p.State == ProjectileState.OneAndDone)
                    {
                        break;
                    }

                    p.ProjectileClose();
                    ProjectilePool.Push(p);
                    ActiveProjetiles.RemoveAtFast(i);
                    continue;
                }

                if (p.Info.Target.IsProjectile)
                {
                    if (p.Info.Target.Projectile.State != ProjectileState.Alive)
                    {
                        p.UnAssignProjectile(true);
                    }
                }
                if (!p.AtMaxRange)
                {
                    if (p.FeelsGravity)
                    {
                        var update = (p.Info.Age % 60 == 0 || (p.FakeGravityNear || p.EntitiesNear) && p.Info.Age % 10 == 0) && p.Info.Age > 0;
                        if (update)
                        {
                            float interference;
                            p.Gravity = Session.Physics.CalculateNaturalGravityAt(p.Position, out interference);
                            if (!p.Info.InPlanetGravity && !MyUtils.IsZero(p.Gravity))
                            {
                                p.FakeGravityNear = true;
                            }
                            else
                            {
                                p.FakeGravityNear = false;
                            }
                            p.EntitiesNear = false;
                        }
                        p.Velocity += (p.Gravity * p.Info.ConsumableDef.Trajectory.GravityMultiplier) * Projectile.StepConst;
                        Vector3D.Normalize(ref p.Velocity, out p.Info.Direction);
                    }

                    if (p.DeltaVelocityPerTick > 0 && !p.Info.EwarAreaPulse)
                    {
                        if (p.SmartsOn)
                        {
                            p.RunSmart();
                        }
                        else
                        {
                            var      accel = true;
                            Vector3D newVel;
                            if (p.FieldTime > 0)
                            {
                                var distToMax = p.Info.MaxTrajectory - p.Info.DistanceTraveled;

                                var stopDist = p.VelocityLengthSqr / 2 / (p.AccelInMetersPerSec);
                                if (distToMax <= stopDist)
                                {
                                    accel = false;
                                }

                                newVel = accel ? p.Velocity + p.AccelVelocity : p.Velocity - p.AccelVelocity;
                                p.VelocityLengthSqr = newVel.LengthSquared();

                                if (accel && p.VelocityLengthSqr > p.MaxSpeedSqr)
                                {
                                    newVel = p.Info.Direction * p.MaxSpeed;
                                }
                                else if (!accel && distToMax <= 0)
                                {
                                    newVel = Vector3D.Zero;
                                    p.VelocityLengthSqr = 0;
                                }
                            }
                            else
                            {
                                newVel = p.Velocity + p.AccelVelocity;
                                p.VelocityLengthSqr = newVel.LengthSquared();
                                if (p.VelocityLengthSqr > p.MaxSpeedSqr)
                                {
                                    newVel = p.Info.Direction * p.MaxSpeed;
                                }
                            }

                            p.Velocity = newVel;
                        }
                    }

                    if (p.State == ProjectileState.OneAndDone)
                    {
                        p.LastPosition = p.Position;
                        var beamEnd = p.Position + (p.Info.Direction * p.Info.MaxTrajectory);
                        p.TravelMagnitude = p.Position - beamEnd;
                        p.Position        = beamEnd;
                    }
                    else
                    {
                        if (p.ConstantSpeed || p.VelocityLengthSqr > 0)
                        {
                            p.LastPosition = p.Position;
                        }

                        p.TravelMagnitude = p.Info.Age != 0 ? p.Velocity * StepConst : p.InitalStep;
                        p.Position       += p.TravelMagnitude;
                    }

                    p.Info.PrevDistanceTraveled = p.Info.DistanceTraveled;

                    double distChanged;
                    Vector3D.Dot(ref p.Info.Direction, ref p.TravelMagnitude, out distChanged);
                    p.Info.DistanceTraveled += Math.Abs(distChanged);
                    if (p.Info.DistanceTraveled <= 500)
                    {
                        ++p.Info.Ai.ProInMinCacheRange;
                    }

                    if (p.DynamicGuidance)
                    {
                        if (p.PruningProxyId != -1)
                        {
                            var          sphere = new BoundingSphereD(p.Position, p.Info.ConsumableDef.Const.AreaEffectSize);
                            BoundingBoxD result;
                            BoundingBoxD.CreateFromSphere(ref sphere, out result);
                            Session.ProjectileTree.MoveProxy(p.PruningProxyId, ref result, p.Velocity);
                        }
                    }
                }
                if (p.ModelState == EntityState.Exists)
                {
                    var     up = MatrixD.Identity.Up;
                    MatrixD matrix;
                    MatrixD.CreateWorld(ref p.Position, ref p.Info.Direction, ref up, out matrix);

                    if (p.Info.ConsumableDef.Const.PrimeModel)
                    {
                        p.Info.AvShot.PrimeMatrix = matrix;
                    }
                    if (p.Info.ConsumableDef.Const.TriggerModel && p.Info.TriggerGrowthSteps < p.Info.ConsumableDef.Const.AreaEffectSize)
                    {
                        p.Info.TriggerMatrix = matrix;
                    }
                }

                if (p.State != ProjectileState.OneAndDone)
                {
                    if (p.Info.Age > p.Info.ConsumableDef.Const.MaxLifeTime)
                    {
                        p.DistanceToTravelSqr = p.Info.DistanceTraveled * p.Info.DistanceTraveled;
                        p.EarlyEnd            = true;
                    }

                    if (p.Info.DistanceTraveled * p.Info.DistanceTraveled >= p.DistanceToTravelSqr)
                    {
                        p.AtMaxRange = !p.MineSeeking;
                        if (p.FieldTime > 0)
                        {
                            p.FieldTime--;
                            if (p.Info.ConsumableDef.Const.IsMine && !p.MineSeeking && !p.MineActivated)
                            {
                                if (p.EnableAv)
                                {
                                    p.Info.AvShot.Cloaked = p.Info.ConsumableDef.Trajectory.Mines.Cloak;
                                }
                                p.MineSeeking = true;
                            }
                        }
                    }
                }
                else
                {
                    p.AtMaxRange = true;
                }

                if (p.Info.ConsumableDef.Const.Ewar)
                {
                    p.RunEwar();
                }
            }
        }
예제 #18
0
        internal void CreateShieldShape()
        {
            var width  = DsSet.Settings.Width;
            var height = DsSet.Settings.Height;
            var depth  = DsSet.Settings.Depth;

            var maxMulti = ShieldMode != ShieldType.SmallGrid ? 0.33333f : 1f;

            var xMax = GridIsMobile ? DsState.State.GridHalfExtents.X * maxMulti : float.MaxValue;
            var yMax = GridIsMobile ? DsState.State.GridHalfExtents.Y * maxMulti : float.MaxValue;
            var zMax = GridIsMobile ? DsState.State.GridHalfExtents.Z * maxMulti : float.MaxValue;

            var offsetMulti = ShieldMode != ShieldType.SmallGrid ? 1 : 0.2f;

            var wOffset           = MathHelper.Clamp(DsSet.Settings.ShieldOffset.X * offsetMulti, -xMax, xMax);
            var hOffset           = MathHelper.Clamp(DsSet.Settings.ShieldOffset.Y * offsetMulti, -yMax, yMax);
            var dOffset           = MathHelper.Clamp(DsSet.Settings.ShieldOffset.Z * offsetMulti, -zMax, zMax);
            var localOffsetMeters = new Vector3D(wOffset, hOffset, dOffset) * MyGrid.GridSize;

            var gridMatrix  = MyGrid.PositionComp.WorldMatrixRef;
            var worldOffset = Vector3D.TransformNormal(localOffsetMeters, gridMatrix);

            if (GridIsMobile)
            {
                DetectionCenter = MyGridCenter + worldOffset;

                _updateMobileShape = false;
                if (_shapeChanged)
                {
                    CreateMobileShape(localOffsetMeters);
                }
                DetectionMatrix     = ShieldShapeMatrix * gridMatrix;
                SQuaternion         = Quaternion.CreateFromRotationMatrix(gridMatrix);
                ShieldSphere.Center = DetectionCenter;
                ShieldSphere.Radius = ShieldSize.AbsMax();
            }
            else
            {
                IMyUpgradeModule emitter;
                if (_isServer)
                {
                    emitter = ShieldComp.StationEmitter.Emitter;
                }
                else
                {
                    emitter = (IMyUpgradeModule)MyEntities.GetEntityById(DsState.State.ActiveEmitterId, true);
                }

                if (emitter == null)
                {
                    UpdateDimensions = true;
                    return;
                }


                var blockGridPosMeters   = new Vector3D(emitter.Position) * MyGrid.GridSize;
                var localOffsetPosMeters = localOffsetMeters + blockGridPosMeters;
                var emitterCenter        = emitter.PositionComp.GetPosition();
                var offsetLMatrix        = Matrix.CreateWorld(localOffsetPosMeters, Vector3D.Forward, Vector3D.Up);

                var translationInWorldSpace = emitterCenter + worldOffset;

                OffsetEmitterWMatrix = MatrixD.CreateWorld(translationInWorldSpace, gridMatrix.Forward, gridMatrix.Up);

                DetectionCenter = OffsetEmitterWMatrix.Translation;

                var halfDistToCenter = 1000 - Vector3D.Distance(DetectionCenter, emitterCenter);
                var vectorScale      = new Vector3D(MathHelper.Clamp(width, 30, halfDistToCenter), MathHelper.Clamp(height, 30, halfDistToCenter), MathHelper.Clamp(depth, 30, halfDistToCenter));

                DetectionMatrix   = MatrixD.Rescale(OffsetEmitterWMatrix, vectorScale);
                ShieldShapeMatrix = MatrixD.Rescale(offsetLMatrix, vectorScale);

                ShieldSize          = DetectionMatrix.Scale;
                SQuaternion         = Quaternion.CreateFromRotationMatrix(OffsetEmitterWMatrix);
                ShieldSphere.Center = DetectionCenter;
                ShieldSphere.Radius = ShieldSize.AbsMax();
            }

            ShieldSphere3K.Center = DetectionCenter;
            WebSphere.Center      = DetectionCenter;

            SOriBBoxD.Center      = DetectionCenter;
            SOriBBoxD.Orientation = SQuaternion;

            if (_shapeChanged)
            {
                SOriBBoxD.HalfExtent = ShieldSize;
                ShieldAabbScaled.Min = -ShieldSize;
                ShieldAabbScaled.Max = ShieldSize;
                _ellipsoidSa.Update(DetectMatrixOutside.Scale.X, DetectMatrixOutside.Scale.Y, DetectMatrixOutside.Scale.Z);
                BoundingRange         = ShieldSize.AbsMax();
                ShieldSphere3K.Radius = BoundingRange + 3000;
                WebSphere.Radius      = BoundingRange + (IsStatic ? 20 : 10);

                _ellipsoidSurfaceArea = _ellipsoidSa.Surface;
                var magicMod       = DsState.State.Enhancer && ShieldMode == ShieldType.Station ? 100f : DsState.State.Enhancer && DsSet.Settings.FortifyShield ? 12f + Math.Sqrt(DsSet.Settings.Fit) : 1f;
                var ellipsoidMagic = _ellipsoidSurfaceArea / (MagicEllipsoidRatio * magicMod);
                var rawScaler      = Math.Sqrt(ellipsoidMagic);
                _sizeScaler = (float)rawScaler;

                /// Large ship bonus
                var size           = DsState.State.RealGridHalfExtents.Volume * 2;
                var scaleMod       = size * (size * 0.00000012d);
                var scaleSqrt      = Math.Sqrt(scaleMod) - 1d;
                var safeSqrt       = scaleSqrt <= 0 ? 0.1d : scaleSqrt;
                var volumeModifier = Math.Log10(safeSqrt);

                if (ShieldMode != ShieldType.Station && DsState.State.BlockDensity >= 1 && volumeModifier >= 1)
                {
                    _sizeScaler /= (float)volumeModifier;
                }
                ///

                if (_isServer)
                {
                    ShieldChangeState();
                    ShieldComp.ShieldVolume = DetectMatrixOutside.Scale.Volume;
                }
            }

            if (_shapeChanged)
            {
                var zeroMatrix   = Matrix.Zero;
                var shieldMatrix = (Matrix)ShieldShapeMatrix;
                if (!_isDedicated)
                {
                    _shellPassive.PositionComp.SetLocalMatrix(ref zeroMatrix, null, true);  // Bug - Cannot just change X coord, so I reset first.
                    ShellActive.PositionComp.SetLocalMatrix(ref zeroMatrix, null, true);
                    _shellPassive.PositionComp.SetLocalMatrix(ref shieldMatrix, null, true);
                    ShellActive.PositionComp.SetLocalMatrix(ref shieldMatrix, null, true);
                }
                ShieldEnt.PositionComp.SetLocalMatrix(ref zeroMatrix, null, true);
                ShieldEnt.PositionComp.SetLocalMatrix(ref shieldMatrix, null, true);
                ShieldEnt.PositionComp.LocalAABB    = BoundingBox.CreateFromHalfExtent(Vector3.Zero, (float)ShieldSize.AbsMax());
                ShieldEnt.PositionComp.WorldMatrix *= MyGrid.PositionComp.WorldMatrix.GetOrientation();

                ShapeChangeTick = _tick;
            }
            ShieldEnt.PositionComp.SetPosition(DetectionCenter);
            BoundingBoxD.CreateFromSphere(ref WebSphere, out WebBox);
            BoundingBoxD.CreateFromSphere(ref ShieldSphere3K, out ShieldBox3K);
        }
예제 #19
0
        public static MyDetectedEntityInfo Create(MyEntity entity, long sensorOwner, Vector3D?hitPosition = new Vector3D?())
        {
            MyDetectedEntityType             type;
            MyRelationsBetweenPlayerAndBlock neutral;
            string displayName;

            if (entity == null)
            {
                return(new MyDetectedEntityInfo());
            }
            MatrixD      zero     = MatrixD.Zero;
            Vector3      velocity = (Vector3)Vector3D.Zero;
            int          totalGamePlayTimeInMilliseconds = MySandboxGame.TotalGamePlayTimeInMilliseconds;
            BoundingBoxD worldAABB = entity.PositionComp.WorldAABB;

            if (entity.Physics != null)
            {
                zero     = entity.Physics.GetWorldMatrix().GetOrientation();
                velocity = entity.Physics.LinearVelocity;
            }
            MyCubeGrid topMostParent = entity.GetTopMostParent(null) as MyCubeGrid;

            if (topMostParent != null)
            {
                type    = (topMostParent.GridSizeEnum != MyCubeSize.Small) ? MyDetectedEntityType.LargeGrid : MyDetectedEntityType.SmallGrid;
                neutral = (topMostParent.BigOwners.Count != 0) ? MyIDModule.GetRelation(sensorOwner, topMostParent.BigOwners[0], MyOwnershipShareModeEnum.Faction, MyRelationsBetweenPlayerAndBlock.Enemies, MyRelationsBetweenFactions.Enemies, MyRelationsBetweenPlayerAndBlock.FactionShare) : MyRelationsBetweenPlayerAndBlock.NoOwnership;
                if ((neutral == MyRelationsBetweenPlayerAndBlock.Owner) || (neutral == MyRelationsBetweenPlayerAndBlock.FactionShare))
                {
                    displayName = topMostParent.DisplayName;
                }
                else
                {
                    displayName = (topMostParent.GridSizeEnum != MyCubeSize.Small) ? MyTexts.GetString(MySpaceTexts.DetectedEntity_LargeGrid) : MyTexts.GetString(MySpaceTexts.DetectedEntity_SmallGrid);
                }
                zero = topMostParent.WorldMatrix.GetOrientation();
                return(new MyDetectedEntityInfo(topMostParent.EntityId, displayName, type, hitPosition, zero, topMostParent.Physics.LinearVelocity, neutral, worldAABB, (long)totalGamePlayTimeInMilliseconds));
            }
            MyCharacter character = entity as MyCharacter;

            if (character != null)
            {
                type    = !character.IsPlayer ? MyDetectedEntityType.CharacterOther : MyDetectedEntityType.CharacterHuman;
                neutral = MyIDModule.GetRelation(sensorOwner, character.GetPlayerIdentityId(), MyOwnershipShareModeEnum.Faction, MyRelationsBetweenPlayerAndBlock.Enemies, MyRelationsBetweenFactions.Enemies, MyRelationsBetweenPlayerAndBlock.FactionShare);
                if ((neutral == MyRelationsBetweenPlayerAndBlock.Owner) || (neutral == MyRelationsBetweenPlayerAndBlock.FactionShare))
                {
                    displayName = character.DisplayNameText;
                }
                else
                {
                    displayName = !character.IsPlayer ? MyTexts.GetString(MySpaceTexts.DetectedEntity_CharacterOther) : MyTexts.GetString(MySpaceTexts.DetectedEntity_CharacterHuman);
                }
                return(new MyDetectedEntityInfo(entity.EntityId, displayName, type, hitPosition, zero, velocity, neutral, character.Model.BoundingBox.Transform(character.WorldMatrix), (long)totalGamePlayTimeInMilliseconds));
            }
            neutral = MyRelationsBetweenPlayerAndBlock.Neutral;
            MyFloatingObject obj2 = entity as MyFloatingObject;

            if (obj2 != null)
            {
                displayName = obj2.Item.Content.SubtypeName;
                return(new MyDetectedEntityInfo(entity.EntityId, displayName, MyDetectedEntityType.FloatingObject, hitPosition, zero, velocity, neutral, worldAABB, (long)totalGamePlayTimeInMilliseconds));
            }
            MyInventoryBagEntity entity2 = entity as MyInventoryBagEntity;

            if (entity2 != null)
            {
                displayName = entity2.DisplayName;
                return(new MyDetectedEntityInfo(entity.EntityId, displayName, MyDetectedEntityType.FloatingObject, hitPosition, zero, velocity, neutral, worldAABB, (long)totalGamePlayTimeInMilliseconds));
            }
            MyPlanet planet = entity as MyPlanet;

            if (planet != null)
            {
                displayName = MyTexts.GetString(MySpaceTexts.DetectedEntity_Planet);
                return(new MyDetectedEntityInfo(entity.EntityId, displayName, MyDetectedEntityType.Planet, hitPosition, zero, velocity, neutral, BoundingBoxD.CreateFromSphere(new BoundingSphereD(planet.PositionComp.GetPosition(), (double)planet.MaximumRadius)), (long)totalGamePlayTimeInMilliseconds));
            }
            MyVoxelPhysics physics = entity as MyVoxelPhysics;

            if (physics != null)
            {
                displayName = MyTexts.GetString(MySpaceTexts.DetectedEntity_Planet);
                return(new MyDetectedEntityInfo(entity.EntityId, displayName, MyDetectedEntityType.Planet, hitPosition, zero, velocity, neutral, BoundingBoxD.CreateFromSphere(new BoundingSphereD(physics.Parent.PositionComp.GetPosition(), (double)physics.Parent.MaximumRadius)), (long)totalGamePlayTimeInMilliseconds));
            }
            if (entity is MyVoxelMap)
            {
                displayName = MyTexts.GetString(MySpaceTexts.DetectedEntity_Asteroid);
                return(new MyDetectedEntityInfo(entity.EntityId, displayName, MyDetectedEntityType.Asteroid, hitPosition, zero, velocity, neutral, worldAABB, (long)totalGamePlayTimeInMilliseconds));
            }
            if (entity is MyMeteor)
            {
                displayName = MyTexts.GetString(MySpaceTexts.DetectedEntity_Meteor);
                return(new MyDetectedEntityInfo(entity.EntityId, displayName, MyDetectedEntityType.Meteor, hitPosition, zero, velocity, neutral, worldAABB, (long)totalGamePlayTimeInMilliseconds));
            }
            if (entity is MyMissile)
            {
                return(new MyDetectedEntityInfo(entity.EntityId, entity.DisplayName, MyDetectedEntityType.Missile, hitPosition, zero, velocity, neutral, worldAABB, (long)totalGamePlayTimeInMilliseconds));
            }
            Vector3D?nullable    = null;
            MatrixD  orientation = new MatrixD();
            Vector3  vector2     = new Vector3();

            return(new MyDetectedEntityInfo(0L, string.Empty, MyDetectedEntityType.Unknown, nullable, orientation, vector2, MyRelationsBetweenPlayerAndBlock.NoOwnership, new BoundingBoxD(), (long)MySandboxGame.TotalGamePlayTimeInMilliseconds));
        }
예제 #20
0
        public static MyDetectedEntityInfo Create(MyEntity entity, long sensorOwner, Vector3D?hitPosition = null)
        {
            if (entity == null)
            {
                return(new MyDetectedEntityInfo());
            }

            MatrixD orientation = MatrixD.Zero;
            Vector3 velocity    = Vector3D.Zero;
            int     timeStamp   = MySandboxGame.TotalGamePlayTimeInMilliseconds;
            MyDetectedEntityType             type;
            BoundingBoxD                     boundingBox = entity.PositionComp.WorldAABB;
            MyRelationsBetweenPlayerAndBlock relationship;
            string name;

            if (entity.Physics != null)
            {
                orientation = entity.Physics.GetWorldMatrix().GetOrientation();
                velocity    = entity.Physics.LinearVelocity;
            }

            //using GetTopMostParent in case we are looking at a MyCubeBlock; we want the grid the block is on
            var grid = entity.GetTopMostParent() as MyCubeGrid;

            if (grid != null)
            {
                if (grid.GridSizeEnum == MyCubeSize.Small)
                {
                    type = MyDetectedEntityType.SmallGrid;
                }
                else
                {
                    type = MyDetectedEntityType.LargeGrid;
                }

                if (grid.BigOwners.Count == 0)
                {
                    relationship = MyRelationsBetweenPlayerAndBlock.NoOwnership;
                }
                else
                {
                    relationship = MyIDModule.GetRelation(sensorOwner, grid.BigOwners[0], MyOwnershipShareModeEnum.Faction);
                }

                if (relationship == MyRelationsBetweenPlayerAndBlock.Owner || relationship == MyRelationsBetweenPlayerAndBlock.FactionShare)
                {
                    name = grid.DisplayName;
                }
                else
                {
                    if (grid.GridSizeEnum == MyCubeSize.Small)
                    {
                        name = MyTexts.GetString(MySpaceTexts.DetectedEntity_SmallGrid);
                    }
                    else
                    {
                        name = MyTexts.GetString(MySpaceTexts.DetectedEntity_LargeGrid);
                    }
                }

                return(new MyDetectedEntityInfo(grid.EntityId, name, type, hitPosition, orientation, velocity, relationship, boundingBox, timeStamp));
            }

            var character = entity as MyCharacter;

            if (character != null)
            {
                if (character.IsPlayer)
                {
                    type = MyDetectedEntityType.CharacterHuman;
                }
                else
                {
                    type = MyDetectedEntityType.CharacterOther;
                }

                relationship = MyIDModule.GetRelation(sensorOwner, character.GetPlayerIdentityId(), MyOwnershipShareModeEnum.Faction);

                if (relationship == MyRelationsBetweenPlayerAndBlock.Owner || relationship == MyRelationsBetweenPlayerAndBlock.FactionShare)
                {
                    name = character.DisplayNameText;
                }
                else
                {
                    if (character.IsPlayer)
                    {
                        name = MyTexts.GetString(MySpaceTexts.DetectedEntity_CharacterHuman);
                    }
                    else
                    {
                        name = MyTexts.GetString(MySpaceTexts.DetectedEntity_CharacterOther);
                    }
                }

                BoundingBoxD bound = character.Model.BoundingBox.Transform(character.WorldMatrix);

                return(new MyDetectedEntityInfo(entity.EntityId, name, type, hitPosition, orientation, velocity, relationship, bound, timeStamp));
            }

            relationship = MyRelationsBetweenPlayerAndBlock.Neutral;

            var floating = entity as MyFloatingObject;

            if (floating != null)
            {
                type = MyDetectedEntityType.FloatingObject;
                name = floating.Item.Content.SubtypeName;
                return(new MyDetectedEntityInfo(entity.EntityId, name, type, hitPosition, orientation, velocity, relationship, boundingBox, timeStamp));
            }

            var backpack = entity as MyInventoryBagEntity;

            if (backpack != null)
            {
                type = MyDetectedEntityType.FloatingObject;
                name = backpack.DisplayName;
                return(new MyDetectedEntityInfo(entity.EntityId, name, type, hitPosition, orientation, velocity, relationship, boundingBox, timeStamp));
            }

            var planet = entity as MyPlanet;

            if (planet != null)
            {
                type = MyDetectedEntityType.Planet;
                name = MyTexts.GetString(MySpaceTexts.DetectedEntity_Planet);
                //shrink the planet's bounding box to only encompass terrain
                boundingBox = BoundingBoxD.CreateFromSphere(new BoundingSphereD(planet.PositionComp.GetPosition(), planet.MaximumRadius));
                return(new MyDetectedEntityInfo(entity.EntityId, name, type, hitPosition, orientation, velocity, relationship, boundingBox, timeStamp));
            }

            var voxelPhysics = entity as MyVoxelPhysics;

            if (voxelPhysics != null)
            {
                type = MyDetectedEntityType.Planet;
                name = MyTexts.GetString(MySpaceTexts.DetectedEntity_Planet);
                //shrink the planet's bounding box to only encompass terrain
                boundingBox = BoundingBoxD.CreateFromSphere(new BoundingSphereD(voxelPhysics.Parent.PositionComp.GetPosition(), voxelPhysics.Parent.MaximumRadius));
                return(new MyDetectedEntityInfo(entity.EntityId, name, type, hitPosition, orientation, velocity, relationship, boundingBox, timeStamp));
            }

            var voxel = entity as MyVoxelMap;

            if (voxel != null)
            {
                type = MyDetectedEntityType.Asteroid;
                name = MyTexts.GetString(MySpaceTexts.DetectedEntity_Asteroid);
                return(new MyDetectedEntityInfo(entity.EntityId, name, type, hitPosition, orientation, velocity, relationship, boundingBox, timeStamp));
            }

            var meteor = entity as MyMeteor;

            if (meteor != null)
            {
                type = MyDetectedEntityType.Meteor;
                name = MyTexts.GetString(MySpaceTexts.DetectedEntity_Meteor);
                return(new MyDetectedEntityInfo(entity.EntityId, name, type, hitPosition, orientation, velocity, relationship, boundingBox, timeStamp));
            }

            var missile = entity as MyMissile;

            if (missile != null)
            {
                type = MyDetectedEntityType.Missile;
                name = entity.DisplayName;
                return(new MyDetectedEntityInfo(entity.EntityId, name, type, hitPosition, orientation, velocity, relationship, boundingBox, timeStamp));
            }

            //error case
            return(new MyDetectedEntityInfo(0, String.Empty, MyDetectedEntityType.Unknown, null, new MatrixD(), new Vector3(), MyRelationsBetweenPlayerAndBlock.NoOwnership, new BoundingBoxD(), MySandboxGame.TotalGamePlayTimeInMilliseconds));
        }
예제 #21
0
        internal void CreateShieldShape()
        {
            if (GridIsMobile)
            {
                _updateMobileShape = false;
                if (_shapeChanged)
                {
                    CreateMobileShape();
                }
                DetectionMatrix     = ShieldShapeMatrix * MyGrid.WorldMatrix;
                DetectionCenter     = MyGridCenter;
                _sQuaternion        = Quaternion.CreateFromRotationMatrix(MyGrid.WorldMatrix);
                ShieldSphere.Center = DetectionCenter;
                ShieldSphere.Radius = ShieldSize.AbsMax();
            }
            else
            {
                IMyUpgradeModule emitter;
                if (_isServer)
                {
                    emitter = ShieldComp.StationEmitter.Emitter;
                }
                else
                {
                    emitter = (IMyUpgradeModule)MyEntities.GetEntityById(DsState.State.ActiveEmitterId, true);
                }

                if (emitter == null)
                {
                    UpdateDimensions = true;
                    return;
                }

                var width  = DsSet.Settings.Width;
                var height = DsSet.Settings.Height;
                var depth  = DsSet.Settings.Depth;

                var wOffset = DsSet.Settings.ShieldOffset.X;
                var hOffset = DsSet.Settings.ShieldOffset.Y;
                var dOffset = DsSet.Settings.ShieldOffset.Z;

                var blockGridPosMeters   = new Vector3D(emitter.Position) * MyGrid.GridSize;
                var localOffsetMeters    = new Vector3D(wOffset, hOffset, dOffset) * MyGrid.GridSize;
                var localOffsetPosMeters = localOffsetMeters + blockGridPosMeters;
                var emitterCenter        = emitter.PositionComp.GetPosition();
                var offsetLMatrix        = Matrix.CreateWorld(localOffsetPosMeters, Vector3D.Forward, Vector3D.Up);

                var worldOffset             = Vector3D.TransformNormal(localOffsetMeters, MyGrid.WorldMatrix);
                var translationInWorldSpace = emitterCenter + worldOffset;

                OffsetEmitterWMatrix = MatrixD.CreateWorld(translationInWorldSpace, MyGrid.WorldMatrix.Forward, MyGrid.WorldMatrix.Up);

                DetectionCenter = OffsetEmitterWMatrix.Translation;

                var halfDistToCenter = 600 - Vector3D.Distance(DetectionCenter, emitterCenter);
                var vectorScale      = new Vector3D(MathHelper.Clamp(width, 30, halfDistToCenter), MathHelper.Clamp(height, 30, halfDistToCenter), MathHelper.Clamp(depth, 30, halfDistToCenter));

                DetectionMatrix   = MatrixD.Rescale(OffsetEmitterWMatrix, vectorScale);
                ShieldShapeMatrix = MatrixD.Rescale(offsetLMatrix, vectorScale);

                ShieldSize = DetectionMatrix.Scale;

                _sQuaternion        = Quaternion.CreateFromRotationMatrix(OffsetEmitterWMatrix);
                ShieldSphere.Center = DetectionCenter;
                ShieldSphere.Radius = ShieldSize.AbsMax();
            }

            ShieldSphere3K.Center = DetectionCenter;
            WebSphere.Center      = DetectionCenter;

            SOriBBoxD.Center      = DetectionCenter;
            SOriBBoxD.Orientation = _sQuaternion;
            if (_shapeChanged)
            {
                SOriBBoxD.HalfExtent = ShieldSize;
                ShieldAabbScaled.Min = ShieldSize;
                ShieldAabbScaled.Max = -ShieldSize;
                _ellipsoidSa.Update(DetectMatrixOutside.Scale.X, DetectMatrixOutside.Scale.Y, DetectMatrixOutside.Scale.Z);
                BoundingRange = ShieldSize.AbsMax();

                ShieldSphere3K.Radius = BoundingRange + 3000;
                WebSphere.Radius      = BoundingRange + 7;

                _ellipsoidSurfaceArea = _ellipsoidSa.Surface;
                EllipsoidVolume       = 1.333333 * Math.PI * DetectMatrixOutside.Scale.X * DetectMatrixOutside.Scale.Y * DetectMatrixOutside.Scale.Z;
                _shieldVol            = DetectMatrixOutside.Scale.Volume;
                if (_isServer)
                {
                    ShieldChangeState();
                    ShieldComp.ShieldVolume = DetectMatrixOutside.Scale.Volume;
                }
            }

            if (_shapeChanged)
            {
                var zeroMatrix   = Matrix.Zero;
                var shieldMatrix = (Matrix)ShieldShapeMatrix;
                if (!_isDedicated)
                {
                    _shellPassive.PositionComp.SetLocalMatrix(ref zeroMatrix, null, true);  // Bug - Cannot just change X coord, so I reset first.
                    _shellActive.PositionComp.SetLocalMatrix(ref zeroMatrix, null, true);
                    _shellPassive.PositionComp.SetLocalMatrix(ref shieldMatrix, null, true);
                    _shellActive.PositionComp.SetLocalMatrix(ref shieldMatrix, null, true);
                }
                ShieldEnt.PositionComp.SetLocalMatrix(ref zeroMatrix, null, true);
                ShieldEnt.PositionComp.SetLocalMatrix(ref shieldMatrix, null, true);
                ShieldEnt.PositionComp.LocalAABB    = BoundingBox.CreateFromHalfExtent(Vector3.Zero, (float)ShieldSize.AbsMax());
                ShieldEnt.PositionComp.WorldMatrix *= MyGrid.PositionComp.WorldMatrix.GetOrientation();
            }
            ShieldEnt.PositionComp.SetPosition(DetectionCenter);
            BoundingBoxD.CreateFromSphere(ref WebSphere, out WebBox);
            BoundingBoxD.CreateFromSphere(ref ShieldSphere3K, out ShieldBox3K);
        }
예제 #22
0
        private void UpdateState()
        {
            foreach (var p in ActiveProjetiles)
            {
                p.Info.Age++;
                p.Active = false;
                switch (p.State)
                {
                case ProjectileState.Destroy:
                    p.DestroyProjectile();
                    continue;

                case ProjectileState.Dead:
                    continue;

                case ProjectileState.Start:
                    p.Start();
                    break;

                case ProjectileState.OneAndDone:
                case ProjectileState.Depleted:
                case ProjectileState.Detonate:
                    p.ProjectileClose();
                    continue;
                }
                if (p.Info.Target.IsProjectile)
                {
                    if (p.Info.Target.Projectile.State != ProjectileState.Alive)
                    {
                        p.UnAssignProjectile(true);
                    }
                }

                if (p.FeelsGravity)
                {
                    var update = p.FakeGravityNear || p.EntitiesNear || p.Info.Ai.InPlanetGravity && p.Info.Age % 30 == 0 || !p.Info.Ai.InPlanetGravity && p.Info.Age % 10 == 0;
                    if (update)
                    {
                        p.Gravity = MyParticlesManager.CalculateGravityInPoint(p.Position);

                        if (!p.Info.Ai.InPlanetGravity && !MyUtils.IsZero(p.Gravity))
                        {
                            p.FakeGravityNear = true;
                        }
                        else
                        {
                            p.FakeGravityNear = false;
                        }
                    }
                    p.Velocity += (p.Gravity * p.Info.AmmoDef.Trajectory.GravityMultiplier) * Projectile.StepConst;
                    Vector3D.Normalize(ref p.Velocity, out p.Info.Direction);
                }

                if (p.AccelLength > 0 && !p.Info.TriggeredPulse)
                {
                    if (p.SmartsOn)
                    {
                        p.RunSmart();
                    }
                    else
                    {
                        var      accel = true;
                        Vector3D newVel;
                        if (p.FieldTime > 0)
                        {
                            var distToMax = p.Info.MaxTrajectory - p.Info.DistanceTraveled;

                            var stopDist = p.VelocityLengthSqr / 2 / (p.StepPerSec);
                            if (distToMax <= stopDist)
                            {
                                accel = false;
                            }

                            newVel = accel ? p.Velocity + p.AccelVelocity : p.Velocity - p.AccelVelocity;
                            p.VelocityLengthSqr = newVel.LengthSquared();

                            if (accel && p.VelocityLengthSqr > p.MaxSpeedSqr)
                            {
                                newVel = p.Info.Direction * p.MaxSpeed;
                            }
                            else if (!accel && distToMax <= 0)
                            {
                                newVel = Vector3D.Zero;
                                p.VelocityLengthSqr = 0;
                            }
                        }
                        else
                        {
                            newVel = p.Velocity + p.AccelVelocity;
                            p.VelocityLengthSqr = newVel.LengthSquared();
                            if (p.VelocityLengthSqr > p.MaxSpeedSqr)
                            {
                                newVel = p.Info.Direction * p.MaxSpeed;
                            }
                        }

                        p.Velocity = newVel;
                    }
                }

                if (p.State == ProjectileState.OneAndDone)
                {
                    p.LastPosition = p.Position;
                    var beamEnd = p.Position + (p.Info.Direction * p.Info.MaxTrajectory);
                    p.TravelMagnitude = p.Position - beamEnd;
                    p.Position        = beamEnd;
                }
                else
                {
                    if (p.ConstantSpeed || p.VelocityLengthSqr > 0)
                    {
                        p.LastPosition = p.Position;
                    }

                    p.TravelMagnitude = p.Velocity * StepConst;
                    p.Position       += p.TravelMagnitude;
                }

                p.Info.PrevDistanceTraveled = p.Info.DistanceTraveled;
                p.Info.DistanceTraveled    += Math.Abs(Vector3D.Dot(p.Info.Direction, p.Velocity * StepConst));
                if (p.ModelState == EntityState.Exists)
                {
                    var     up = MatrixD.Identity.Up;
                    MatrixD matrix;
                    MatrixD.CreateWorld(ref p.Position, ref p.Info.VisualDir, ref up, out matrix);
                    if (p.Info.AmmoDef.Const.PrimeModel)
                    {
                        p.Info.AvShot.PrimeMatrix = matrix;
                    }
                    if (p.Info.AmmoDef.Const.TriggerModel && p.Info.TriggerGrowthSteps < p.Info.AmmoDef.Const.AreaEffectSize)
                    {
                        p.Info.TriggerMatrix = matrix;
                    }

                    if (p.EnableAv && p.AmmoEffect != null && p.Info.AmmoDef.Const.AmmoParticle && p.Info.AmmoDef.Const.PrimeModel)
                    {
                        var offVec = p.Position + Vector3D.Rotate(p.Info.AmmoDef.AmmoGraphics.Particles.Ammo.Offset, p.Info.AvShot.PrimeMatrix);
                        p.AmmoEffect.WorldMatrix = p.Info.AvShot.PrimeMatrix;
                        p.AmmoEffect.SetTranslation(ref offVec);
                    }
                }
                else if (p.EnableAv && p.AmmoEffect != null && p.Info.AmmoDef.Const.AmmoParticle)
                {
                    var translation = p.AmmoEffect.WorldMatrix.Translation + p.TravelMagnitude;
                    p.AmmoEffect.SetTranslation(ref translation);
                }

                if (p.DynamicGuidance)
                {
                    if (p.PruningProxyId != -1)
                    {
                        var          sphere = new BoundingSphereD(p.Position, p.Info.AmmoDef.Const.AreaEffectSize);
                        BoundingBoxD result;
                        BoundingBoxD.CreateFromSphere(ref sphere, out result);
                        Session.ProjectileTree.MoveProxy(p.PruningProxyId, ref result, p.Velocity);
                    }
                }

                if (p.State != ProjectileState.OneAndDone)
                {
                    if (!p.SmartsOn && p.Info.Age > p.Info.AmmoDef.Const.MaxLifeTime)
                    {
                        p.DistanceToTravelSqr = p.Info.DistanceTraveled * p.Info.DistanceTraveled;
                        p.EarlyEnd            = true;
                    }

                    if (p.Info.DistanceTraveled * p.Info.DistanceTraveled >= p.DistanceToTravelSqr)
                    {
                        p.AtMaxRange = true;
                        if (p.FieldTime > 0)
                        {
                            p.FieldTime--;
                            if (p.Info.AmmoDef.Const.IsMine && !p.MineSeeking && !p.MineActivated)
                            {
                                if (p.EnableAv)
                                {
                                    p.Info.AvShot.Cloaked = p.Info.AmmoDef.Trajectory.Mines.Cloak;
                                }
                                p.MineSeeking = true;
                            }
                        }
                    }
                }
                else
                {
                    p.AtMaxRange = true;
                }
                if (p.Info.AmmoDef.Const.Ewar)
                {
                    p.RunEwar();
                }

                p.Active = true;
            }
        }
예제 #23
0
        public void GetAllInSphere(List <T> result, ref BoundingSphereD sphere, uint flags = 0)
        {
            var box = BoundingBoxD.CreateFromSphere(sphere);

            GetAllInBox(result, ref box, flags);
        }
 protected Vector3I.RangeIterator GetCellsIterator(BoundingSphereD sphere)
 {
     return(GetCellsIterator(BoundingBoxD.CreateFromSphere(sphere)));
 }
예제 #25
0
        private void CreateShieldShape()
        {
            /*
             * Basically find the point on the surface of the ellipsoid given a normal vector.
             * Equation for ellipsoid is x^2/a^2 + y^2/b^2 ... = 1
             * So given a normal vector x hat, y hat, z hat find the values for x y z that are parallel and satisfy that equation.
             * So x = dist*x normVec, y = dist * y normVec
             * a,b,c are the radii if the ellipsoid in X Y Z
             * So signed distance from surface is distance(point, origin) - distance(support(norm(point-origin)), origin)
             * support gives you the point on the surface in the given direction.
             */
            Asleep = false;

            if (GridIsMobile)
            {
                _updateMobileShape = false;
                if (_shapeChanged)
                {
                    CreateMobileShape();
                }
                DetectionMatrix     = ShieldShapeMatrix * MyGrid.WorldMatrix;
                DetectionCenter     = MyGridCenter;
                _sQuaternion        = Quaternion.CreateFromRotationMatrix(MyGrid.WorldMatrix);
                ShieldSphere.Center = DetectionCenter;
                ShieldSphere.Radius = ShieldSize.AbsMax();
            }
            else
            {
                var emitter = ShieldComp.StationEmitter.Emitter;
                var width   = DsSet.Settings.Width;
                var height  = DsSet.Settings.Height;
                var depth   = DsSet.Settings.Depth;

                var wOffset = DsSet.Settings.ShieldOffset.X;
                var hOffset = DsSet.Settings.ShieldOffset.Y;
                var dOffset = DsSet.Settings.ShieldOffset.Z;

                var blockGridPosMeters   = new Vector3D(emitter.Position) * MyGrid.GridSize;
                var localOffsetMeters    = new Vector3D(wOffset, hOffset, dOffset) * MyGrid.GridSize;
                var localOffsetPosMeters = localOffsetMeters + blockGridPosMeters;
                var emitterCenter        = emitter.PositionComp.GetPosition();
                var offsetLMatrix        = Matrix.CreateWorld(localOffsetPosMeters, Vector3D.Forward, Vector3D.Up);

                var worldOffset             = Vector3D.TransformNormal(localOffsetMeters, MyGrid.WorldMatrix);
                var translationInWorldSpace = emitterCenter + worldOffset;

                OffsetEmitterWMatrix = MatrixD.CreateWorld(translationInWorldSpace, MyGrid.WorldMatrix.Forward, MyGrid.WorldMatrix.Up);

                DetectionCenter = OffsetEmitterWMatrix.Translation;

                var halfDistToCenter = 600 - Vector3D.Distance(DetectionCenter, emitterCenter);
                var vectorScale      = new Vector3D(MathHelper.Clamp(width, 30, halfDistToCenter), MathHelper.Clamp(height, 30, halfDistToCenter), MathHelper.Clamp(depth, 30, halfDistToCenter));

                DetectionMatrix   = MatrixD.Rescale(OffsetEmitterWMatrix, vectorScale);
                ShieldShapeMatrix = MatrixD.Rescale(offsetLMatrix, vectorScale);

                ShieldSize = DetectionMatrix.Scale;

                _sQuaternion        = Quaternion.CreateFromRotationMatrix(OffsetEmitterWMatrix);
                ShieldSphere.Center = DetectionCenter;
                ShieldSphere.Radius = ShieldSize.AbsMax();
            }

            ShieldSphere3K.Center = DetectionCenter;
            WebSphere.Center      = DetectionCenter;

            SOriBBoxD.Center      = DetectionCenter;
            SOriBBoxD.Orientation = _sQuaternion;
            if (_shapeChanged)
            {
                SOriBBoxD.HalfExtent = ShieldSize;
                ShieldAabbScaled.Min = ShieldSize;
                ShieldAabbScaled.Max = -ShieldSize;
                _ellipsoidSa.Update(DetectMatrixOutside.Scale.X, DetectMatrixOutside.Scale.Y, DetectMatrixOutside.Scale.Z);
                BoundingRange = ShieldSize.AbsMax();

                ShieldSphere3K.Radius = BoundingRange + 3000;
                WebSphere.Radius      = BoundingRange + 7;

                _ellipsoidSurfaceArea = _ellipsoidSa.Surface;
                EllipsoidVolume       = 1.333333 * Math.PI * DetectMatrixOutside.Scale.X * DetectMatrixOutside.Scale.Y * DetectMatrixOutside.Scale.Z;
                _shieldVol            = DetectMatrixOutside.Scale.Volume;
                if (_isServer)
                {
                    if (Session.Enforced.Debug == 3)
                    {
                        Log.Line($"StateUpdate: CreateShieldShape - Broadcast:{DsState.State.Message} - ShieldId [{Shield.EntityId}]");
                    }
                    ShieldChangeState();
                    ShieldComp.ShieldVolume = DetectMatrixOutside.Scale.Volume;
                }
                if (Session.Enforced.Debug == 3)
                {
                    Log.Line($"CreateShape: shapeChanged - GridMobile:{GridIsMobile} - ShieldId [{Shield.EntityId}]");
                }
            }
            if (!DsState.State.Lowered)
            {
                SetShieldShape();
            }

            BoundingBoxD.CreateFromSphere(ref WebSphere, out WebBox);
            BoundingBoxD.CreateFromSphere(ref ShieldSphere3K, out ShieldBox3K);
        }