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; } }
/// <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); }
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; } }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
public static bool HasStatic(this MyEntityQueryType qtype) { return((qtype & MyEntityQueryType.Static) != 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(); }
public static bool HasDynamic(this MyEntityQueryType qtype) => (((int)(qtype & MyEntityQueryType.Dynamic)) != 0);