internal void PartsInRange(out List<Part> partsInRange, out List<float> anglesFromTo, out List<float> distances) { // collect aircrafts that are near enough to have parts which could be targets List<Aircraft> aircraftsInRange = new List<Aircraft>(); foreach (var aircraft in (MyPart.Aircraft.Team == Team.PlayerTeam ? ((PlayLayer)MyPart.Layer).ActiveAircrafts : ((PlayLayer)MyPart.Layer).PlayerAircrafts)) // a bit dirty since technically NPC allies to the player could exist (someday), which would not be contained in PlayerAircrafts, but which would still (maybe) be part of the player team { // check if it is considered an enemy if (!MyPart.Aircraft.Team.IsEnemy(aircraft.Team) || aircraft.MyState.Equals(Aircraft.State.SHOT_DOWN)) continue; // check if in attention arc if (Collisions.CollideArcBoundingBox(MyPart.PositionWorldspace, AttentionRange, MyPart.TotalNullRotation, AttentionAngle, aircraft.BoundingBoxTransformedToWorld)) aircraftsInRange.Add(aircraft); } partsInRange = new List<Part>(); anglesFromTo = new List<float>(); distances = new List<float>(); foreach (var aircraft in aircraftsInRange) { foreach (var part in aircraft.TotalParts) { if (part.MyState == Part.State.DESTROYED) continue; // using the position as criterium is a bit dirty and could be improved on by using the bounding box instead (at the cost of performance) CCPoint vectorMyPartPart = part.PositionWorldspace - MyPart.PositionWorldspace; float distance = vectorMyPartPart.Length; if (distance <= AttentionRange) { var angleFromTo = Constants.AngleFromToDeg(MyPart.TotalRotation - MyPart.RotationFromNull, Constants.DxDyToCCDegrees(vectorMyPartPart.X, vectorMyPartPart.Y)); if ((float)Math.Abs(angleFromTo) <= AttentionAngle) { partsInRange.Add(part); anglesFromTo.Add(Constants.AngleFromToDeg(MyPart.TotalRotation, Constants.DxDyToCCDegrees(vectorMyPartPart.X, vectorMyPartPart.Y))); distances.Add(distance); } } } } }