public override void Draw() { base.Draw(); if (MySession.Static == null) { return; } const float raycastDist = 200; var ray = new LineD(MySector.MainCamera.Position, MySector.MainCamera.Position + raycastDist * MySector.MainCamera.ForwardVector); var entities = new List <MyLineSegmentOverlapResult <MyEntity> >(); MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref ray, entities, MyEntityQueryType.Static); double closest = double.PositiveInfinity; foreach (var e in entities) { var voxel = e.Element as MyVoxelBase; if (voxel != null && e.Distance < closest) { m_selectedVoxel = voxel; } } if (m_selectedVoxel != null) { Text(Color.DarkOrange, 1.5f, "Selected Voxel: {0}:{1}", m_selectedVoxel.StorageName, m_selectedVoxel.EntityId); } }
internal bool GetAimedAtBlock(out MyCubeBlock cube) { cube = null; if (UiInput.AimRay.Length > 0) { AimRayEnts.Clear(); MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref UiInput.AimRay, AimRayEnts); foreach (var ent in AimRayEnts) { var grid = ent.Element as MyCubeGrid; if (grid?.Physics != null && grid.Physics.Enabled && !grid.Physics.IsPhantom && grid.InScene && !grid.IsPreview) { MyCube myCube; var hitV3I = grid.RayCastBlocks(UiInput.AimRay.From, UiInput.AimRay.To); if (hitV3I.HasValue && grid.TryGetCube(hitV3I.Value, out myCube)) { var slim = (IMySlimBlock)myCube.CubeBlock; if (slim.FatBlock != null) { cube = (MyCubeBlock)slim.FatBlock; return(true); } } } } } return(false); }
void GenerateEntityList(bool DetectVoxels, out HashSet <IMyCubeGrid> Grids, out HashSet <IMyCharacter> Characters, out HashSet <IMyFloatingObject> Flobjes, out HashSet <IMyVoxelBase> Voxels) { Grids = new HashSet <IMyCubeGrid>(); Characters = new HashSet <IMyCharacter>(); Flobjes = new HashSet <IMyFloatingObject>(); Voxels = new HashSet <IMyVoxelBase>(); LineD WorkingRay = new LineD(MyKernel.BeamDrawer.BeamStart, MyKernel.BeamDrawer.BeamEnd); List <MyLineSegmentOverlapResult <MyEntity> > Overlaps = new List <MyLineSegmentOverlapResult <MyEntity> >(50); MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref WorkingRay, Overlaps); if (Overlaps.Count == 0) { return; } if (DetectVoxels) { Overlaps.Select(x => x.Element as IMyEntity).SortByType(Grids, Characters, Flobjes, Voxels); } else { Overlaps.Select(x => x.Element as IMyEntity).SortByType(Grids, Characters, Flobjes); } }
void Work(int ticks = 1) { if (!MyAPIGateway.Multiplayer.IsServer) { return; } LineD WeldRay = new LineD(BeamStart, BeamEnd); List <IHitInfo> Hits = new List <IHitInfo>(); List <MyLineSegmentOverlapResult <MyEntity> > Overlaps = new List <MyLineSegmentOverlapResult <MyEntity> >(); MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref WeldRay, Overlaps); List <IMyCubeGrid> Grids = new List <IMyCubeGrid>(); List <IMyCharacter> Characters = new List <IMyCharacter>(); List <IMyFloatingObject> Flobjes = new List <IMyFloatingObject>(); Overlaps.Select(x => x.Element as IMyEntity).SortByType(Grids, Characters, Flobjes); ClosestGrid = Grids.OrderBy(Grid => Vector3D.DistanceSquared(Tool.GetPosition(), Grid.GetPosition())).FirstOrDefault(); foreach (IMyCharacter Char in Characters) { Char.DoDamage(GrinderSpeed, MyDamageType.Grind, true, null, Tool.EntityId); } foreach (IMyCubeGrid Grid in Grids) { if (Grid == Tool.CubeGrid) { continue; } try { List <IMySlimBlock> Blocks = Grid.GetBlocksOnRay(WeldRay.From, WeldRay.To); //if (!SessionCore.Debug && Blocks.Count == 0) return; if (IsWelder) { Weld(Blocks, ticks); } if (IsGrinder) { Grind(Blocks, ticks); } } catch (Exception Scrap) { SessionCore.LogError(Grid.DisplayName, Scrap); } } foreach (IMyFloatingObject Flobj in Flobjes) { ToolCargo.PickupItem(Flobj); } }
private static MyTuple <float?, IMyTerminalBlock> TAPI_ClosestShieldInLine(LineD line, bool onlyIfOnline) { var segment = SegmentPool.Get(); MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref line, segment, MyEntityQueryType.Dynamic); var ray = new RayD(line.From, line.Direction); var closest = float.MaxValue; IMyTerminalBlock closestShield = null; for (int i = 0; i < segment.Count; i++) { var ent = segment[i].Element; if (ent == null || ent.Physics != null && !ent.Physics.IsPhantom) { continue; } ShieldGridComponent c; if (Session.Instance.IdToBus.TryGetValue(ent.EntityId, out c) && c.DefenseShields != null) { if (onlyIfOnline && (!c.DefenseShields.DsState.State.Online || c.DefenseShields.DsState.State.Lowered)) { continue; } var s = c.DefenseShields; var intersectDist = CustomCollision.IntersectEllipsoid(s.DetectMatrixOutsideInv, s.DetectMatrixOutside, ray); if (!intersectDist.HasValue) { continue; } var ellipsoid = intersectDist ?? 0; if (ellipsoid > line.Length || ellipsoid > closest || CustomCollision.PointInShield(ray.Position, s.DetectMatrixOutsideInv)) { continue; } closest = ellipsoid; closestShield = s.Shield; } } segment.Clear(); SegmentPool.Return(segment); var response = new MyTuple <float?, IMyTerminalBlock>(); if (closestShield == null) { response.Item1 = null; response.Item2 = null; return(response); } response.Item1 = closest; response.Item2 = closestShield; return(response); }
public IMyCubeGrid GetTarget() { //var turretBase = Entity as Sandbox.ModAPI.IMyLargeTurretBase; //var fixedWeapon = Entity as Sandbox.ModAPI.IMyUserControllableGun; //if (turretBase != null) //{ // target = turretBase.Target; //} try { MyEntitySubpart subpart1 = cubeBlock.GetSubpart("GatlingTurretBase1"); MyEntitySubpart subpart2 = subpart1.GetSubpart("GatlingTurretBase2"); if (cubeBlock == null || cubeBlock.CubeGrid == null || subpart1 == null || subpart2 == null || subpart1.WorldMatrix == null || subpart2.WorldMatrix == null) { return(null); } var from = subpart2.WorldMatrix.Translation + subpart2.WorldMatrix.Forward * 0.3d; var to = subpart2.WorldMatrix.Translation + subpart2.WorldMatrix.Forward * 800d; LineD ray = new LineD(from, to); List <MyLineSegmentOverlapResult <MyEntity> > result = new List <MyLineSegmentOverlapResult <MyEntity> >(); MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref ray, result, MyEntityQueryType.Both); foreach (var resultItem in result) { if (resultItem.Element == null) { continue; } if (resultItem.Element.EntityId != cubeBlock.CubeGrid.EntityId) { if (resultItem.Element is IMyCubeGrid) { return(resultItem.Element as IMyCubeGrid); } } } } catch (KeyNotFoundException) { } return(null); }
void Work(int ticks = 1) { if (!MyAPIGateway.Multiplayer.IsServer) { return; } LineD WeldRay = new LineD(BeamStart, BeamEnd); List <IHitInfo> Hits = new List <IHitInfo>(); List <MyLineSegmentOverlapResult <MyEntity> > Overlaps = new List <MyLineSegmentOverlapResult <MyEntity> >(); MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref WeldRay, Overlaps); var Entities = Overlaps.Select(x => x.Element); var Grids = Entities.OfType <IMyCubeGrid>().Except(Tool.CubeGrid).OrderBy(x => Vector3D.DistanceSquared(BlockPosition, x.GetPosition())).ToList(); ClosestGrid = Grids.FirstOrDefault(); foreach (IMyCharacter Char in Entities.OfType <IMyCharacter>()) { Char.DoDamage(GrinderSpeed, MyDamageType.Grind, true, null, Tool.EntityId); } foreach (IMyCubeGrid Grid in Entities.OfType <IMyCubeGrid>()) { try { List <IMySlimBlock> Blocks = Grid.GetBlocksOnRay(WeldRay.From, WeldRay.To); //if (!SessionCore.Debug && Blocks.Count == 0) return; if (IsWelder) { Weld(Blocks, ticks); } if (IsGrinder) { Grind(Blocks, ticks); } } catch (Exception Scrap) { SessionCore.LogError(Grid.DisplayName, Scrap); } } }
private void Probe(Vector3D pos) { var ray = m_probedLine; ray.From += pos; ray.To += pos; var entities = new List <MyLineSegmentOverlapResult <MyEntity> >(); MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref ray, entities, MyEntityQueryType.Static); double closest = double.PositiveInfinity; foreach (var e in entities) { var voxel = e.Element as MyVoxelBase; if (voxel != null && e.Distance < closest) { m_probedVoxel = voxel; } } if (m_probedVoxel is MyVoxelPhysics) { m_probedVoxel = ((MyVoxelPhysics)m_probedVoxel).Parent; } if (m_probedVoxel != null && m_probedVoxel.Storage.DataProvider != null) { MyRenderProxy.DebugDrawLine3D(ray.From, ray.To, Color.Green, Color.Green, true); Vector3D start = Vector3D.Transform(ray.From, m_probedVoxel.PositionComp.WorldMatrixInvScaled); start += m_probedVoxel.SizeInMetresHalf; var end = Vector3D.Transform(ray.To, m_probedVoxel.PositionComp.WorldMatrixInvScaled); end += m_probedVoxel.SizeInMetresHalf; var voxRay = new LineD(start, end); double startOffset; double endOffset; // Intersect provider for nau var cont = m_probedVoxel.Storage.DataProvider.Intersect(ref voxRay, out startOffset, out endOffset); var from = voxRay.From; voxRay.From = from + voxRay.Direction * voxRay.Length * startOffset; voxRay.To = from + voxRay.Direction * voxRay.Length * endOffset; if (m_probeCount == 1) { Text(Color.Yellow, 1.5f, "Probing voxel map {0}:{1}", m_probedVoxel.StorageName, m_probedVoxel.EntityId); Text("Local Pos: {0}", start); Text("Intersects: {0}", cont); } if (cont) { start = voxRay.From - m_probedVoxel.SizeInMetresHalf; start = Vector3D.Transform(start, m_probedVoxel.PositionComp.WorldMatrix); end = voxRay.To - m_probedVoxel.SizeInMetresHalf; end = Vector3D.Transform(end, m_probedVoxel.PositionComp.WorldMatrix); MyRenderProxy.DebugDrawLine3D(start, end, Color.Red, Color.Red, true); } } else { if (m_probeCount == 1) { Text(Color.Yellow, 1.5f, "No voxel found"); } MyRenderProxy.DebugDrawLine3D(ray.From, ray.To, Color.Yellow, Color.Yellow, true); } }
private void CheckHits() { for (int x = ActiveProjetiles.Count - 1; x >= 0; x--) { var p = ActiveProjetiles[x]; if ((int)p.State > 3) { continue; } if (p.Info.Ai.ProInMinCacheRange > 99999 && !p.Info.Ai.AccelChecked) { p.Info.Ai.ComputeAccelSphere(); } p.UseEntityCache = p.Info.Ai.AccelChecked && p.Info.DistanceTraveled <= p.Info.Ai.NearByEntitySphere.Radius && !p.Info.Ai.MarkedForClose; var triggerRange = p.Info.ConsumableDef.Const.EwarTriggerRange > 0 && !p.Info.EwarAreaPulse ? p.Info.ConsumableDef.Const.EwarTriggerRange : 0; var useEwarSphere = (triggerRange > 0 || p.Info.EwarActive) && p.Info.ConsumableDef.Const.Pulse; p.Beam = useEwarSphere ? new LineD(p.Position + (-p.Info.Direction * p.Info.ConsumableDef.Const.EwarTriggerRange), p.Position + (p.Info.Direction * p.Info.ConsumableDef.Const.EwarTriggerRange)) : new LineD(p.LastPosition, p.Position); if ((p.FieldTime <= 0 && p.State != ProjectileState.OneAndDone && p.Info.DistanceTraveled * p.Info.DistanceTraveled >= p.DistanceToTravelSqr)) { p.PruneSphere.Center = p.Position; p.PruneSphere.Radius = p.Info.ConsumableDef.Const.DetonationRadius; var dInfo = p.Info.ConsumableDef.AreaEffect.Detonation; if (p.MoveToAndActivate || dInfo.DetonateOnEnd && p.Info.Age >= dInfo.MinArmingTime && (!dInfo.ArmOnlyOnHit || p.Info.ObjectsHit > 0)) { if (!p.UseEntityCache) { MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref p.PruneSphere, p.MyEntityList, p.PruneQuery); } if (p.Info.System.TrackProjectile) { foreach (var lp in p.Info.Ai.LiveProjectile) { if (p.PruneSphere.Contains(lp.Position) != ContainmentType.Disjoint && lp != p.Info.Target.Projectile) { ProjectileHit(p, lp, p.Info.ConsumableDef.Const.CollisionIsLine, ref p.Beam); } } } p.State = ProjectileState.Detonate; if (p.EnableAv) { p.Info.AvShot.ForceHitParticle = true; } } else { p.State = ProjectileState.Detonate; } p.EarlyEnd = true; p.Info.Hit.SurfaceHit = p.Position; p.Info.Hit.LastHit = p.Position; } p.SphereCheck = false; p.LineCheck = false; if (p.MineSeeking && !p.MineTriggered) { p.SeekEnemy(); } else if (useEwarSphere) { if (p.Info.EwarActive) { p.PruneSphere = new BoundingSphereD(p.Position, 0).Include(new BoundingSphereD(p.LastPosition, 0)); var currentRadius = p.Info.TriggerGrowthSteps < p.Info.ConsumableDef.Const.AreaEffectSize ? p.Info.TriggerMatrix.Scale.AbsMax() : p.Info.ConsumableDef.Const.AreaEffectSize; if (p.PruneSphere.Radius < currentRadius) { p.PruneSphere.Center = p.Position; p.PruneSphere.Radius = currentRadius; } } else { p.PruneSphere = new BoundingSphereD(p.Position, triggerRange); } if (p.PruneSphere.Contains(p.DeadSphere) == ContainmentType.Disjoint) { p.SphereCheck = true; } } else if (p.Info.ConsumableDef.Const.CollisionIsLine) { p.PruneSphere.Center = p.Position; p.PruneSphere.Radius = p.Info.ConsumableDef.Const.CollisionSize; if (p.Info.ConsumableDef.Const.IsBeamWeapon || p.PruneSphere.Contains(p.DeadSphere) == ContainmentType.Disjoint) { p.LineCheck = true; } } else { p.SphereCheck = true; p.PruneSphere = new BoundingSphereD(p.Position, 0).Include(new BoundingSphereD(p.LastPosition, 0)); if (p.PruneSphere.Radius < p.Info.ConsumableDef.Const.CollisionSize) { p.PruneSphere.Center = p.Position; p.PruneSphere.Radius = p.Info.ConsumableDef.Const.CollisionSize; } } } var apCount = ActiveProjetiles.Count; var minCount = Session.Settings.Enforcement.ServerOptimizations ? 96 : 99999; var stride = apCount < minCount ? 100000 : 48; MyAPIGateway.Parallel.For(0, apCount, i => { var p = ActiveProjetiles[i]; if (p.SphereCheck) { if (p.DynamicGuidance && p.PruneQuery == MyEntityQueryType.Dynamic && p.Info.System.Session.Tick60) { p.CheckForNearVoxel(60); } if (!p.UseEntityCache) { MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref p.PruneSphere, p.MyEntityList, p.PruneQuery); } } else if (p.LineCheck) { if (p.DynamicGuidance && p.PruneQuery == MyEntityQueryType.Dynamic && p.Info.System.Session.Tick60) { p.CheckForNearVoxel(60); } if (!p.UseEntityCache) { MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref p.Beam, p.MySegmentList, p.PruneQuery); } } p.CheckType = p.UseEntityCache && p.SphereCheck ? CheckTypes.CachedSphere : p.UseEntityCache ? CheckTypes.CachedRay : p.SphereCheck ? CheckTypes.Sphere : CheckTypes.Ray; if (p.Info.Target.IsProjectile || p.UseEntityCache && p.Info.Ai.NearByEntityCache.Count > 0 || p.CheckType == CheckTypes.Ray && p.MySegmentList.Count > 0 || p.CheckType == CheckTypes.Sphere && p.MyEntityList.Count > 0) { ValidateHits.Add(p); } }, stride); ValidateHits.ApplyAdditions(); }
/// <summary> /// Determines if a given entity is on a free line of sight. /// </summary> public bool IsInView(IMyEntity Target, out Vector3D?HitPosition) { HitPosition = null; try { float RayPower = Radar.ActiveRadar ? Radar.PowerModule.EffectiveRadarPower : 800; if (Radar.MyRadarGrid == null || Radar.MyRadarGrid.Grid == null) { RadarCore.LogError("IsInView", new Exception("Radar's RadarableGrid is null!"), IsExcessive: true); return(false); } LineD LineRay = new LineD(Radar.Position, Target.GetPosition()); if (LineRay.Length <= RadarCore.GuaranteedDetectionRange) { return(true); } List <MyLineSegmentOverlapResult <MyEntity> > Overlaps = new List <MyLineSegmentOverlapResult <MyEntity> >(); MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref LineRay, Overlaps); if (Overlaps == null || Overlaps.Count == 0) { return(false); } var TargetTop = Target.GetTopMostParent(); if (TargetTop == null) { RadarCore.LogError("IsInView", new Exception("Target's topmost parent is null!")); return(false); } var RadarTop = Radar.MyRadarGrid.Grid.GetTopMostParent(); if (TargetTop == null) { RadarCore.LogError("IsInView", new Exception("Radar's topmost parent is null!")); return(false); } foreach (var Overlap in Overlaps) { try { if (Overlap.Element == null || Overlap.Element.Physics == null) { continue; } LineD Intersect; var Entity = Overlap.Element as IMyEntity; if (!Entity.WorldAABB.Valid) { RadarCore.DebugWrite("IsInView.Iterate", "Found an entity with invalid WorldAABB. Skipping.", IsExcessive: true); continue; } if (Entity is IMyCubeGrid) { Entity.WorldAABB.Intersect(ref LineRay, out Intersect); } else { Entity.WorldVolume.Intersect(ref LineRay, out Intersect); } var OverlapTop = Entity.GetTopMostParent(); if (OverlapTop == null) { RadarCore.DebugWrite("IsInView.Iterate", "Found an entity with invalid topmost parent. Skipping.", IsExcessive: true); continue; } if (OverlapTop is MyPlanet) { MyPlanet Planet = OverlapTop as MyPlanet; if (Planet.HasAtmosphere) { BoundingSphereD Atmosphere = new BoundingSphereD(Planet.PositionComp.GetPosition(), Planet.AtmosphereRadius); LineD AtmoIntersect; Atmosphere.Intersect(ref LineRay, out AtmoIntersect); float Diminish = (float)(AtmoIntersect.Length * RadarCore.AtmoRayDiminishingCoefficient); RayPower -= Diminish; if (RayPower <= 0) { return(false); } } Vector3D TargetPos = Target.GetPosition(); if (Vector3D.DistanceSquared(Planet.GetClosestSurfacePointGlobal(ref TargetPos), TargetPos) < 1000 * 1000) { return(false); } } else if (OverlapTop == TargetTop) { HitPosition = Intersect.From; return(true); } else if (OverlapTop == RadarTop) { if (OverlapTop.GetPosition().DistanceTo(Radar.Position) > 1000) { List <Vector3I> GridHits = new List <Vector3I>(); Radar.MyRadarGrid.Grid.RayCastCells(Radar.Position, LineRay.To, GridHits); if (GridHits == null || GridHits.Count == 0) { continue; } if (GridHits.Contains(Radar.GridPosition)) { GridHits.Remove(Radar.GridPosition); } float Diminish = GridHits.Count * (Radar.MyRadarGrid.Grid.GridSizeEnum == MyCubeSize.Large ? 2.5f : 0.5f) * RadarCore.RayDiminishingCoefficient; RayPower -= Diminish; if (RayPower <= 0) { return(false); } } } else { float Diminish = (float)(Intersect.Length * RadarCore.RayDiminishingCoefficient); RayPower -= Diminish; if (RayPower <= 0) { return(false); } } } catch (Exception Scrap) { RadarCore.LogError("IsInView.Iterate", Scrap, IsExcessive: true); } } } catch (Exception Scrap) { RadarCore.LogError("IsInView", Scrap); } return(false); }
void Work(int ticks = 1) { if (IsDrill) { return; } LineD WeldRay = new LineD(BeamCtlModule.BeamStart, BeamCtlModule.BeamEnd); List <MyLineSegmentOverlapResult <MyEntity> > Overlaps = new List <MyLineSegmentOverlapResult <MyEntity> >(); MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref WeldRay, Overlaps); HashSet <IMyCubeGrid> Grids = new HashSet <IMyCubeGrid>(); HashSet <IMyCharacter> Characters = new HashSet <IMyCharacter>(); HashSet <IMyFloatingObject> Flobjes = new HashSet <IMyFloatingObject>(); Overlaps.Select(x => x.Element as IMyEntity).SortByType(Grids, Characters, Flobjes); Grids.Remove(ToolGrid); if (SessionCore.Settings.Debug && Vector3D.Distance(Tool.GetPosition(), MyAPIGateway.Session.LocalHumanPlayer.GetPosition()) <= 200) { string GridNames = ""; foreach (var grid in Grids) { GridNames += $"{grid.DisplayName};"; } DebugNote.Text = $"{Tool.CustomName}: processing {Grids.Count} entities: {GridNames}{(IsWelder ? $" sup.invs: {GridInventoryModule.GetAccessibleInventories(Tool).Count}; unbuilt: {(this as LaserWelder).UnbuiltBlocks.Count}" : "")}"; GridNames = null; } foreach (IMyCubeGrid Grid in Grids) { //if (Grid.EntityId == ToolGrid.EntityId) continue; try { ProcessGrid(Grid, ticks); } catch (Exception Scrap) { SessionCore.LogError(Grid.DisplayName, Scrap); } } if (MyAPIGateway.Session.IsServer) { foreach (IMyCharacter Char in Characters) { if (Char.WorldAABB.Intersects(ref WeldRay)) { Char.DoDamage(VanillaToolConstants.GrinderSpeed * ticks / 2, MyDamageType.Grind, true, null, Tool.EntityId); } } foreach (IMyFloatingObject Flobj in Flobjes) { if (CargoFillRatio < 0.75) { ToolCargo.PickupItem(Flobj); } else { break; } } } }
private void CheckHits() { foreach (var p in ActiveProjetiles) { p.Miss = false; if (!p.Active || (int)p.State > 3) { continue; } var triggerRange = p.Info.AmmoDef.Const.EwarTriggerRange > 0 && !p.Info.TriggeredPulse ? p.Info.AmmoDef.Const.EwarTriggerRange : 0; var useEwarSphere = triggerRange > 0 || p.Info.EwarActive; p.Beam = useEwarSphere ? new LineD(p.Position + (-p.Info.Direction * p.Info.AmmoDef.Const.EwarTriggerRange), p.Position + (p.Info.Direction * p.Info.AmmoDef.Const.EwarTriggerRange)) : new LineD(p.LastPosition, p.Position); if ((p.FieldTime <= 0 && p.State != ProjectileState.OneAndDone && p.Info.DistanceTraveled * p.Info.DistanceTraveled >= p.DistanceToTravelSqr)) { var dInfo = p.Info.AmmoDef.AreaEffect.Detonation; p.PruneSphere.Center = p.Position; p.PruneSphere.Radius = dInfo.DetonationRadius; if (p.MoveToAndActivate || dInfo.DetonateOnEnd && (!dInfo.ArmOnlyOnHit || p.Info.ObjectsHit > 0)) { MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref p.PruneSphere, p.CheckList, p.PruneQuery); for (int i = 0; i < p.CheckList.Count; i++) { p.SegmentList.Add(new MyLineSegmentOverlapResult <MyEntity> { Distance = 0, Element = p.CheckList[i] }); } if (p.Info.System.TrackProjectile) { foreach (var lp in p.Info.Ai.LiveProjectile) { if (p.PruneSphere.Contains(lp.Position) != ContainmentType.Disjoint && lp != p.Info.Target.Projectile) { ProjectileHit(p, lp, p.Info.AmmoDef.Const.CollisionIsLine, ref p.Beam); } } } p.CheckList.Clear(); p.State = ProjectileState.Detonate; p.ForceHitParticle = true; } else { p.State = ProjectileState.Detonate; } p.Hit.HitPos = p.Position; } var sphere = false; var line = false; if (p.MineSeeking && !p.MineTriggered) { p.SeekEnemy(); } else if (useEwarSphere) { if (p.Info.EwarActive) { p.PruneSphere = new BoundingSphereD(p.Position, 0).Include(new BoundingSphereD(p.LastPosition, 0)); var currentRadius = p.Info.TriggerGrowthSteps < p.Info.AmmoDef.Const.AreaEffectSize ? p.Info.TriggerMatrix.Scale.AbsMax() : p.Info.AmmoDef.Const.AreaEffectSize; if (p.PruneSphere.Radius < currentRadius) { p.PruneSphere.Center = p.Position; p.PruneSphere.Radius = currentRadius; } } else { p.PruneSphere = new BoundingSphereD(p.Position, triggerRange); } if (p.PruneSphere.Contains(p.DeadSphere) == ContainmentType.Disjoint) { sphere = true; } } else if (p.Info.AmmoDef.Const.CollisionIsLine) { p.PruneSphere.Center = p.Position; p.PruneSphere.Radius = p.Info.AmmoDef.Const.CollisionSize; if (p.Info.AmmoDef.Const.IsBeamWeapon || p.PruneSphere.Contains(p.DeadSphere) == ContainmentType.Disjoint) { line = true; } } else { sphere = true; p.PruneSphere = new BoundingSphereD(p.Position, 0).Include(new BoundingSphereD(p.LastPosition, 0)); if (p.PruneSphere.Radius < p.Info.AmmoDef.Const.CollisionSize) { p.PruneSphere.Center = p.Position; p.PruneSphere.Radius = p.Info.AmmoDef.Const.CollisionSize; } } if (sphere) { if (p.DynamicGuidance && p.PruneQuery == MyEntityQueryType.Dynamic && p.Info.Ai.Session.Tick60) { p.CheckForNearVoxel(60); } MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref p.PruneSphere, p.CheckList, p.PruneQuery); for (int i = 0; i < p.CheckList.Count; i++) { p.SegmentList.Add(new MyLineSegmentOverlapResult <MyEntity> { Distance = 0, Element = p.CheckList[i] }); } p.CheckList.Clear(); } else if (line) { if (p.DynamicGuidance && p.PruneQuery == MyEntityQueryType.Dynamic && p.Info.Ai.Session.Tick60) { p.CheckForNearVoxel(60); } MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref p.Beam, p.SegmentList, p.PruneQuery); } if (p.Info.Target.IsProjectile || p.SegmentList.Count > 0) { ValidateHits.Add(p); continue; } p.Miss = true; p.Info.HitList.Clear(); } }
/// <summary> /// Check opts, load/unload /// </summary> public void Update100() { if (m_holoEntities.Count != 0 && DateTime.UtcNow >= m_clearAllAt) { Log.DebugLog("clearing all holo entities"); foreach (SeenHolo sh in m_holoEntities.Values) { Log.DebugLog("removing " + sh.Seen.Entity.EntityId + "from m_holoEntities (clear all)"); OnRemove(sh); } m_holoEntities.Clear(); } if (!Enabled) { return; } Vector3D playerPos = MyAPIGateway.Session.Player.GetPosition(), holoCentre = m_offset.ToWorld(m_block); double distSquared = Vector3D.DistanceSquared(playerPos, holoCentre); m_playerCanSee = distSquared <= 1e4d; if (m_playerCanSee && distSquared > 100d) { List <MyLineSegmentOverlapResult <MyEntity> > entitiesInRay = ResourcePool <List <MyLineSegmentOverlapResult <MyEntity> > > .Get(); m_playerCanSee = false; MyEntity[] ignore = new MyEntity[] { (MyEntity)MyAPIGateway.Session.Player.Controller.ControlledEntity }; foreach (Vector3 vector in Static.Directions) { LineD ray = new LineD(playerPos, holoCentre + vector * m_radiusHolo); MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref ray, entitiesInRay); if (!RayCast.Obstructed(ray, entitiesInRay.Select(overlap => overlap.Element), ignore)) { m_playerCanSee = true; entitiesInRay.Clear(); break; } entitiesInRay.Clear(); } ResourcePool <List <MyLineSegmentOverlapResult <MyEntity> > > .Return(entitiesInRay); } if (!m_playerCanSee) { return; } RelayStorage storage = m_netClient.GetStorage(); if (storage == null) { ((IMyTerminalBlock)m_block).AppendCustomInfo("No network connection"); return; } m_clearAllAt = DateTime.UtcNow + Static.keepInCache; storage.ForEachLastSeen(CreateHolo); foreach (SeenHolo sh in m_holoEntities.Values) { if (CanDisplay(sh.Seen)) { if (!sh.Holo.Render.Visible) { Log.DebugLog("showing holo: " + sh.Seen.Entity.getBestName()); SetupProjection(sh.Holo); SetVisible(sh.Holo, true); } if (sh.Seen.Entity is MyCubeGrid && sh.ColouredByIntegrity != ((m_options & Option.IntegrityColours) != 0)) { if (sh.ColouredByIntegrity) { RestoreColour(sh); } else { ColourByIntegrity(sh); } } } else if (sh.Holo.Render.Visible) { Log.DebugLog("hiding holo: " + sh.Seen.Entity.getBestName()); SetVisible(sh.Holo, false); } } if (m_holoEntitiesRemove.Count != 0) { foreach (long entityId in m_holoEntitiesRemove) { Log.DebugLog("removing " + entityId + "from m_holoEntities"); SeenHolo sh; if (!m_holoEntities.TryGetValue(entityId, out sh)) { // this may be normal Log.DebugLog("not in m_holoEntities: " + entityId, Logger.severity.WARNING); continue; } OnRemove(sh); m_holoEntities.Remove(entityId); } m_holoEntitiesRemove.Clear(); } }
public void TargetIntersectionCheck() { _entityScanList.Clear(); _voxelScanList.Clear(); _entityScanList = new List <MyLineSegmentOverlapResult <MyEntity> >(); MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref Line, _entityScanList); IMyCubeGrid closestGrid = null; double closestGridDistance = -1; MySafeZone closestZone = null; double closestZoneDistance = -1; IMyCharacter closestCharacter = null; double closestCharacterDistance = -1; foreach (var item in _entityScanList) { var targetGrid = item.Element as IMyCubeGrid; var targetZone = item.Element as MySafeZone; var targetVoxel = item.Element as MyVoxelBase; var targetPlayer = item.Element as IMyCharacter; if (targetGrid != null) { if (targetGrid == _collisionSystem.RemoteControl.SlimBlock.CubeGrid || _collisionSystem.RemoteControl.SlimBlock.CubeGrid.IsSameConstructAs(targetGrid)) { continue; } if (closestGrid == null || (closestGrid != null && item.Distance < closestGridDistance)) { closestGrid = targetGrid; closestGridDistance = item.Distance; } } if (targetZone != null) { if (closestZone == null || (closestZone != null && item.Distance < closestZoneDistance)) { closestZone = targetZone; closestZoneDistance = item.Distance; } } if (targetVoxel != null) { _voxelScanList.Add(targetVoxel); } if (targetPlayer != null) { if (closestCharacter == null || (closestCharacter != null && item.Distance < closestCharacterDistance)) { closestCharacter = targetPlayer; closestCharacterDistance = item.Distance; } } } if (closestGrid != null) { double minDist = 0; double maxDist = 0; bool boxCheckResult = closestGrid.PositionComp.WorldAABB.Intersect(ref Ray, out minDist, out maxDist); Vector3D startBox = boxCheckResult ? (minDist - 5) * DirectionVector + StartPosition : StartPosition; Vector3D endBox = boxCheckResult ? (maxDist + 5) * DirectionVector + StartPosition : EndPosition; var blockPos = closestGrid.RayCastBlocks(startBox, endBox); if (!blockPos.HasValue) { return; } IMySlimBlock slimBlock = closestGrid.GetCubeBlock(blockPos.Value); if (slimBlock == null) { return; } Vector3D blockPosition = Vector3D.Zero; slimBlock.ComputeWorldCenter(out blockPosition); GridCoords = blockPosition; GridDistance = Vector3D.Distance(blockPosition, StartPosition); GridEntity = closestGrid; GridOwner = OwnershipHelper.GetOwnershipTypes(closestGrid, false); GridRelation = OwnershipHelper.GetTargetReputation(_collisionSystem.Owner, closestGrid, false); } if (closestZone != null) { SafezoneEntity = closestZone; SafezoneCoords = closestZoneDistance * DirectionVector + StartPosition; SafezoneDistance = closestZoneDistance; } if (closestCharacter != null) { PlayerEntity = closestCharacter; PlayerCoords = PlayerEntity.PositionComp.WorldAABB.Center; PlayerDistance = closestCharacterDistance; } }
void Work(int ticks = 1) { if (!MyAPIGateway.Multiplayer.IsServer) { return; } if (IsDrill) { return; } LineD WeldRay = new LineD(BeamStart, BeamEnd); List <MyLineSegmentOverlapResult <MyEntity> > Overlaps = new List <MyLineSegmentOverlapResult <MyEntity> >(); MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref WeldRay, Overlaps); HashSet <IMyCubeGrid> Grids = new HashSet <IMyCubeGrid>(); HashSet <IMyCharacter> Characters = new HashSet <IMyCharacter>(); HashSet <IMyFloatingObject> Flobjes = new HashSet <IMyFloatingObject>(); Overlaps.Select(x => x.Element as IMyEntity).SortByType(Grids, Characters, Flobjes); Grids.Remove(ToolGrid); if (SessionCore.Debug && Vector3D.Distance(BlockPosition, MyAPIGateway.Session.LocalHumanPlayer.GetPosition()) <= 200) { string GridNames = ""; foreach (var grid in Grids) { GridNames += $"{grid.DisplayName};"; } DebugNote.Text = $"{Tool.CustomName}: processing {Grids.Count} entities: {GridNames}"; GridNames = null; } foreach (IMyCubeGrid Grid in Grids) { //if (Grid.EntityId == ToolGrid.EntityId) continue; try { ProcessGrid(Grid, ticks); } catch (Exception Scrap) { SessionCore.LogError(Grid.DisplayName, Scrap); } } foreach (IMyCharacter Char in Characters) { if (Char.WorldAABB.Intersects(ref WeldRay)) { Char.DoDamage(GrinderSpeed * ticks / 2, MyDamageType.Grind, true, null, Tool.EntityId); } } foreach (IMyFloatingObject Flobj in Flobjes) { if ((double)ToolCargo.CurrentVolume / (double)ToolCargo.MaxVolume < 0.75) { ToolCargo.PickupItem(Flobj); } } /*if (Tool is IMyShipDrill) * { * List<MyLineSegmentOverlapResult<MyVoxelBase>> VoxelOverlaps = new List<MyLineSegmentOverlapResult<MyVoxelBase>>(); * MyGamePruningStructure.GetVoxelMapsOverlappingRay(ref WeldRay, VoxelOverlaps); * MyVoxelBase Voxel = VoxelOverlaps.OrderBy(x => Vector3D.DistanceSquared(BlockPosition, x.Element.PositionComp.GetPosition())).First().Element; * ProcessVoxel(Voxel, ticks); * }*/ }