コード例 #1
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;
            }
        }
コード例 #2
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);
        }
コード例 #3
0
        internal void Start()
        {
            Position = Info.Origin;
            AccelDir = Info.Direction;
            var cameraStart = Info.System.Session.CameraPos;

            Vector3D.DistanceSquared(ref cameraStart, ref Info.Origin, out DistanceFromCameraSqr);
            GenerateShrapnel = Info.ConsumableDef.Const.ShrapnelId > -1;
            var probability = Info.ConsumableDef.AmmoGraphics.VisualProbability;

            EnableAv                  = !Info.ConsumableDef.Const.VirtualBeams && !Info.System.Session.DedicatedServer && DistanceFromCameraSqr <= Info.System.Session.SyncDistSqr && (probability >= 1 || probability >= MyUtils.GetRandomDouble(0.0f, 1f));
            ModelState                = EntityState.None;
            LastEntityPos             = Position;
            LastHitEntVel             = null;
            Info.AvShot               = null;
            Info.Age                  = -1;
            ChaseAge                  = 0;
            NewTargets                = 0;
            ZombieLifeTime            = 0;
            LastOffsetTime            = 0;
            PruningProxyId            = -1;
            EntitiesNear              = false;
            CachedPlanetHit           = false;
            PositionChecked           = false;
            MineSeeking               = false;
            MineActivated             = false;
            MineTriggered             = false;
            LinePlanetCheck           = false;
            AtMaxRange                = false;
            ShieldBypassed            = false;
            FakeGravityNear           = false;
            HadTarget                 = false;
            WasTracking               = false;
            Intersecting              = false;
            EndStep                   = 0;
            Info.PrevDistanceTraveled = 0;
            Info.DistanceTraveled     = 0;
            PrevEndPointToCenterSqr   = double.MaxValue;


            CachedId        = Info.MuzzleId == -1 ? Info.WeaponCache.VirutalId : Info.MuzzleId;
            Guidance        = Info.ConsumableDef.Trajectory.Guidance;
            DynamicGuidance = Guidance != GuidanceType.None && Guidance != GuidanceType.TravelTo && !Info.ConsumableDef.Const.IsBeamWeapon && Info.EnableGuidance;
            if (DynamicGuidance)
            {
                DynTrees.RegisterProjectile(this);
            }
            FeelsGravity = Info.ConsumableDef.Const.FeelsGravity;

            Info.MyPlanet = Info.Ai.MyPlanet;
            if (!Info.System.Session.VoxelCaches.TryGetValue(Info.UniqueMuzzleId, out Info.VoxelCache))
            {
                Log.Line($"ProjectileStart VoxelCache Failure with Id:{Info.UniqueMuzzleId} BlockMarked:{Info.Target.FiringCube?.MarkedForClose}, setting to default cache:");
                Info.VoxelCache = Info.System.Session.VoxelCaches[ulong.MaxValue];
            }
            if (Info.MyPlanet != null)
            {
                Info.VoxelCache.PlanetSphere.Center = Info.Ai.ClosestPlanetCenter;
            }

            Info.MyShield            = Info.Ai.MyShield;
            Info.InPlanetGravity     = Info.Ai.InPlanetGravity;
            Info.AiVersion           = Info.Ai.Version;
            Info.Ai.ProjectileTicker = Info.Ai.Session.Tick;

            if (Guidance == GuidanceType.Smart && DynamicGuidance)
            {
                SmartsOn     = true;
                MaxChaseTime = Info.ConsumableDef.Const.MaxChaseTime;
                SmartSlot    = Info.WeaponRng.ClientProjectileRandom.Next(10);
                Info.WeaponRng.ClientProjectileCurrentCounter++;
            }
            else
            {
                MaxChaseTime = int.MaxValue;
                SmartsOn     = false;
                SmartSlot    = 0;
            }

            if (Info.Target.IsProjectile)
            {
                OriginTargetPos = Info.Target.Projectile.Position;
                Info.Target.Projectile.Seekers.Add(this);
            }
            else if (Info.Target.Entity != null)
            {
                OriginTargetPos = Info.Target.Entity.PositionComp.WorldAABB.Center;
            }
            else
            {
                OriginTargetPos = Vector3D.Zero;
            }
            LockedTarget = !Vector3D.IsZero(OriginTargetPos);

            if (SmartsOn && Info.ConsumableDef.Const.TargetOffSet && (LockedTarget || Info.Target.IsFakeTarget))
            {
                OffSetTarget();
                OffsetSqr = Info.ConsumableDef.Trajectory.Smarts.Inaccuracy * Info.ConsumableDef.Trajectory.Smarts.Inaccuracy;
            }
            else
            {
                TargetOffSet = Vector3D.Zero;
                OffsetSqr    = 0;
            }
            PrevTargetOffset = Vector3D.Zero;

            var targetSpeed = (float)(!Info.ConsumableDef.Const.IsBeamWeapon ? Info.ConsumableDef.Trajectory.DesiredSpeed : Info.MaxTrajectory * MyEngineConstants.UPDATE_STEPS_PER_SECOND);

            if (Info.ConsumableDef.Const.SpeedVariance && !Info.ConsumableDef.Const.IsBeamWeapon)
            {
                var min           = Info.ConsumableDef.Trajectory.SpeedVariance.Start;
                var max           = Info.ConsumableDef.Trajectory.SpeedVariance.End;
                var speedVariance = (float)Info.WeaponRng.ClientProjectileRandom.NextDouble() * (max - min) + min;
                Info.WeaponRng.ClientProjectileCurrentCounter++;
                DesiredSpeed = targetSpeed + speedVariance;
            }
            else
            {
                DesiredSpeed = targetSpeed;
            }

            float variance = 0;

            if (Info.ConsumableDef.Const.RangeVariance)
            {
                var min = Info.ConsumableDef.Trajectory.RangeVariance.Start;
                var max = Info.ConsumableDef.Trajectory.RangeVariance.End;
                variance            = (float)Info.WeaponRng.ClientProjectileRandom.NextDouble() * (max - min) + min;
                Info.MaxTrajectory -= variance;
                Info.WeaponRng.ClientProjectileCurrentCounter++;
            }

            if (Vector3D.IsZero(PredictedTargetPos))
            {
                PredictedTargetPos = Position + (AccelDir * Info.MaxTrajectory);
            }
            PrevTargetPos       = PredictedTargetPos;
            PrevTargetVel       = Vector3D.Zero;
            Info.ObjectsHit     = 0;
            Info.BaseHealthPool = Info.ConsumableDef.Health;
            Info.BaseEwarPool   = Info.ConsumableDef.Health;
            Info.TracerLength   = Info.ConsumableDef.Const.TracerLength <= Info.MaxTrajectory ? Info.ConsumableDef.Const.TracerLength : Info.MaxTrajectory;

            MaxTrajectorySqr = Info.MaxTrajectory * Info.MaxTrajectory;

            if (!Info.IsShrapnel)
            {
                StartSpeed = Info.ShooterVel;
            }

            MoveToAndActivate = LockedTarget && !Info.ConsumableDef.Const.IsBeamWeapon && Guidance == GuidanceType.TravelTo;

            if (MoveToAndActivate)
            {
                var distancePos = !Vector3D.IsZero(PredictedTargetPos) ? PredictedTargetPos : OriginTargetPos;
                if (variance > 0)
                {
                    var forward = Info.WeaponRng.ClientProjectileRandom.Next(100) < 50;
                    Info.WeaponRng.ClientProjectileCurrentCounter++;
                    distancePos = forward ? distancePos + (AccelDir * variance) : distancePos + (-AccelDir * variance);
                }
                Vector3D.DistanceSquared(ref Info.Origin, ref distancePos, out DistanceToTravelSqr);
            }
            else
            {
                DistanceToTravelSqr = MaxTrajectorySqr;
            }

            PickTarget = Info.ConsumableDef.Trajectory.Smarts.OverideTarget && !Info.Target.IsFakeTarget && !Info.LockOnFireState;
            if (PickTarget || LockedTarget)
            {
                NewTargets++;
            }

            var staticIsInRange  = Info.Ai.ClosestStaticSqr * 0.5 < MaxTrajectorySqr;
            var pruneStaticCheck = Info.Ai.ClosestPlanetSqr * 0.5 < MaxTrajectorySqr || Info.Ai.StaticGridInRange;

            PruneQuery = (DynamicGuidance && pruneStaticCheck) || FeelsGravity && staticIsInRange || !DynamicGuidance && !FeelsGravity && staticIsInRange ? MyEntityQueryType.Both : MyEntityQueryType.Dynamic;

            if (Info.Ai.PlanetSurfaceInRange && Info.Ai.ClosestPlanetSqr <= MaxTrajectorySqr)
            {
                LinePlanetCheck = true;
                PruneQuery      = MyEntityQueryType.Both;
            }

            if (DynamicGuidance && PruneQuery == MyEntityQueryType.Dynamic && staticIsInRange)
            {
                CheckForNearVoxel(60);
            }

            var accelPerSec = Info.ConsumableDef.Trajectory.AccelPerSec;

            ConstantSpeed       = accelPerSec <= 0;
            AccelInMetersPerSec = accelPerSec > 0 ? accelPerSec : DesiredSpeed;
            var desiredSpeed     = (AccelDir * DesiredSpeed);
            var relativeSpeedCap = StartSpeed + desiredSpeed;

            MaxVelocity          = relativeSpeedCap;
            MaxSpeed             = MaxVelocity.Length();
            MaxSpeedSqr          = MaxSpeed * MaxSpeed;
            DeltaVelocityPerTick = accelPerSec * StepConst;
            AccelVelocity        = (AccelDir * DeltaVelocityPerTick);

            if (ConstantSpeed)
            {
                Velocity          = MaxVelocity;
                VelocityLengthSqr = MaxSpeed * MaxSpeed;
            }
            else
            {
                Velocity = StartSpeed + AccelVelocity;
            }

            if (Info.IsShrapnel)
            {
                Vector3D.Normalize(ref Velocity, out Info.Direction);
            }

            InitalStep = !Info.IsShrapnel && ConstantSpeed ? desiredSpeed * StepConst : Velocity * StepConst;

            TravelMagnitude = Velocity * StepConst;
            FieldTime       = Info.ConsumableDef.Const.Ewar || Info.ConsumableDef.Const.IsMine ? Info.ConsumableDef.Trajectory.FieldTime : 0;
            State           = !Info.ConsumableDef.Const.IsBeamWeapon ? ProjectileState.Alive : ProjectileState.OneAndDone;

            if (EnableAv)
            {
                Info.AvShot = Info.System.Session.Av.AvShotPool.Get();
                Info.AvShot.Init(Info, AccelInMetersPerSec * StepConst, MaxSpeed, ref AccelDir);
                Info.AvShot.SetupSounds(DistanceFromCameraSqr); //Pool initted sounds per Projectile type... this is expensive
                if (Info.ConsumableDef.Const.HitParticle && !Info.ConsumableDef.Const.IsBeamWeapon || Info.ConsumableDef.Const.AreaEffect == AreaEffectType.Explosive && !Info.ConsumableDef.AreaEffect.Explosions.NoVisuals && Info.ConsumableDef.Const.AreaEffectSize > 0 && Info.ConsumableDef.Const.AreaEffectDamage > 0)
                {
                    var hitPlayChance = Info.ConsumableDef.AmmoGraphics.Particles.Hit.Extras.HitPlayChance;
                    Info.AvShot.HitParticleActive = hitPlayChance >= 1 || hitPlayChance >= MyUtils.GetRandomDouble(0.0f, 1f);
                }
                Info.AvShot.FakeExplosion = Info.AvShot.HitParticleActive && Info.ConsumableDef.Const.AreaEffect == AreaEffectType.Explosive && Info.ConsumableDef.AmmoGraphics.Particles.Hit.Name == string.Empty;
            }

            if (!Info.ConsumableDef.Const.PrimeModel && !Info.ConsumableDef.Const.TriggerModel)
            {
                ModelState = EntityState.None;
            }
            else
            {
                if (EnableAv)
                {
                    ModelState = EntityState.Exists;

                    double triggerModelSize = 0;
                    double primeModelSize   = 0;
                    if (Info.ConsumableDef.Const.TriggerModel)
                    {
                        triggerModelSize = Info.AvShot.TriggerEntity.PositionComp.WorldVolume.Radius;
                    }
                    if (Info.ConsumableDef.Const.PrimeModel)
                    {
                        primeModelSize = Info.AvShot.PrimeEntity.PositionComp.WorldVolume.Radius;
                    }
                    var largestSize = triggerModelSize > primeModelSize ? triggerModelSize : primeModelSize;

                    Info.AvShot.ModelSphereCurrent.Radius = largestSize * 2;
                }
            }

            if (EnableAv)
            {
                LineOrNotModel        = Info.ConsumableDef.Const.DrawLine || ModelState == EntityState.None && Info.ConsumableDef.Const.AmmoParticle;
                Info.AvShot.ModelOnly = !LineOrNotModel && ModelState == EntityState.Exists;
            }
        }
コード例 #4
0
 public static void GetTopmostEntitiesOverlappingRay(ref LineD ray, List<MyLineSegmentOverlapResult<MyEntity>> result, MyEntityQueryType qtype = MyEntityQueryType.Both)
 {
     ProfilerShort.Begin("MyGamePruningStructure::GetAllEntitiesInRay");
     if (qtype.HasDynamic())
         m_dynamicObjectsTree.OverlapAllLineSegment<MyEntity>(ref ray, result);
     if (qtype.HasStatic())
         m_staticObjectsTree.OverlapAllLineSegment<MyEntity>(ref ray, result, false);
     ProfilerShort.End();
 }
コード例 #5
0
 public static void GetAllEntitiesInRay(ref LineD ray, List<MyLineSegmentOverlapResult<MyEntity>> result, MyEntityQueryType qtype = MyEntityQueryType.Both)
 {
     VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyGamePruningStructure::GetAllEntitiesInRay");
     if (qtype.HasDynamic())
     m_dynamicObjectsTree.OverlapAllLineSegment<MyEntity>(ref ray, result);
     if (qtype.HasStatic())
     m_staticObjectsTree.OverlapAllLineSegment<MyEntity>(ref ray, result, false);
     int topmostCount = result.Count;
     for (int i = 0; i < topmostCount; i++)
     {
         if (result[i].Element.Hierarchy != null)
             result[i].Element.Hierarchy.QueryLine(ref ray, result);
     }
     VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
 }
コード例 #6
0
        public static void GetAllTargetsInSphere(ref BoundingSphereD sphere, List<MyEntity> result, MyEntityQueryType qtype = MyEntityQueryType.Both)
        {
            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyGamePruningStructure::GetAllTargetsInSphere");

            if (qtype.HasDynamic())
            m_dynamicObjectsTree.OverlapAllBoundingSphere<MyEntity>(ref sphere, result, false);
            if (qtype.HasStatic())
            m_staticObjectsTree.OverlapAllBoundingSphere<MyEntity>(ref sphere, result, false);
            int topmostCount = result.Count;
            for (int i = 0; i < topmostCount; i++)
            {
                if (result[i].Hierarchy != null)
                    result[i].Hierarchy.QuerySphere(ref sphere, result);
            }

            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
        }
コード例 #7
0
 public static void GetAllTopMostEntitiesInSphere(ref BoundingSphereD sphere, List<MyEntity> result, MyEntityQueryType qtype = MyEntityQueryType.Both)
 {
     VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyGamePruningStructure::GetAllTopMostEntitiesInSphere");
     if (qtype.HasDynamic())
     m_dynamicObjectsTree.OverlapAllBoundingSphere<MyEntity>(ref sphere, result, false);
     if (qtype.HasStatic())
     m_staticObjectsTree.OverlapAllBoundingSphere<MyEntity>(ref sphere, result, false);
     VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
 }
コード例 #8
0
 public static void GetTopmostEntitiesOverlappingRay(ref LineD ray, List <MyLineSegmentOverlapResult <MyEntity> > result, MyEntityQueryType qtype = MyEntityQueryType.Both)
 {
     ProfilerShort.Begin("MyGamePruningStructure::GetAllEntitiesInRay");
     if (qtype.HasDynamic())
     {
         m_dynamicObjectsTree.OverlapAllLineSegment <MyEntity>(ref ray, result);
     }
     if (qtype.HasStatic())
     {
         m_staticObjectsTree.OverlapAllLineSegment <MyEntity>(ref ray, result, false);
     }
     ProfilerShort.End();
 }
コード例 #9
0
        public static void GetAllEntitiesInRay(ref LineD ray, List <MyLineSegmentOverlapResult <MyEntity> > result, MyEntityQueryType qtype = MyEntityQueryType.Both)
        {
            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyGamePruningStructure::GetAllEntitiesInRay");
            if (qtype.HasDynamic())
            {
                m_dynamicObjectsTree.OverlapAllLineSegment <MyEntity>(ref ray, result);
            }
            if (qtype.HasStatic())
            {
                m_staticObjectsTree.OverlapAllLineSegment <MyEntity>(ref ray, result, false);
            }
            int topmostCount = result.Count;

            for (int i = 0; i < topmostCount; i++)
            {
                if (result[i].Element.Hierarchy != null)
                {
                    result[i].Element.Hierarchy.QueryLine(ref ray, result);
                }
            }
            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
        }
コード例 #10
0
        public static void GetAllTargetsInSphere(ref BoundingSphereD sphere, List <MyEntity> result, MyEntityQueryType qtype = MyEntityQueryType.Both)
        {
            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyGamePruningStructure::GetAllTargetsInSphere");

            if (qtype.HasDynamic())
            {
                m_dynamicObjectsTree.OverlapAllBoundingSphere <MyEntity>(ref sphere, result, false);
            }
            if (qtype.HasStatic())
            {
                m_staticObjectsTree.OverlapAllBoundingSphere <MyEntity>(ref sphere, result, false);
            }
            int topmostCount = result.Count;

            for (int i = 0; i < topmostCount; i++)
            {
                if (result[i].Hierarchy != null)
                {
                    result[i].Hierarchy.QuerySphere(ref sphere, result);
                }
            }

            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
        }
コード例 #11
0
 public static bool HasStatic(this MyEntityQueryType qtype)
 {
     return((qtype & MyEntityQueryType.Static) != 0);
 }
コード例 #12
0
 public static void GetAllTopMostEntitiesInSphere(ref BoundingSphereD sphere, List <MyEntity> result, MyEntityQueryType qtype = MyEntityQueryType.Both)
 {
     VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyGamePruningStructure::GetAllTopMostEntitiesInSphere");
     if (qtype.HasDynamic())
     {
         m_dynamicObjectsTree.OverlapAllBoundingSphere <MyEntity>(ref sphere, result, false);
     }
     if (qtype.HasStatic())
     {
         m_staticObjectsTree.OverlapAllBoundingSphere <MyEntity>(ref sphere, result, false);
     }
     VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
 }
コード例 #13
0
 public static bool HasDynamic(this MyEntityQueryType qtype) =>
 (((int)(qtype & MyEntityQueryType.Dynamic)) != 0);