static public EnemyShipIntel IGCUnpack(object data) { var unpacked = (MyTuple <MyTuple <Vector3D, Vector3D, double, double>, MyTuple <string, long, float, int> >)data; var esi = new EnemyShipIntel(); esi.IGCUnpackInto(unpacked); return(esi); }
static public bool PrioritizeTarget(EnemyShipIntel target) { if (target.CubeSize == MyCubeSize.Small && target.Radius < 4) { return(false); } if (target.CubeSize == MyCubeSize.Large && target.Radius < 8) { return(false); } return(true); }
public void TryAddEnemyShipIntel(Dictionary <MyTuple <IntelItemType, long>, IFleetIntelligence> intelDict, TimeSpan localTime, TimeSpan canonicalTime, MyDetectedEntityInfo target, bool validated = false, bool targetNeutral = false) { if (target.IsEmpty()) { return; } if (target.Type != MyDetectedEntityType.SmallGrid && target.Type != MyDetectedEntityType.LargeGrid && target.Type != MyDetectedEntityType.Unknown) { return; } if (target.Relationship != MyRelationsBetweenPlayerAndBlock.Enemies && target.Relationship != MyRelationsBetweenPlayerAndBlock.Neutral) { return; } if (target.Relationship != MyRelationsBetweenPlayerAndBlock.Enemies && !targetNeutral) { return; } var key = MyTuple.Create(IntelItemType.Enemy, target.EntityId); bool gotNewIntel = false; IFleetIntelligence TargetIntel; if (!intelDict.TryGetValue(key, out TargetIntel)) { gotNewIntel = true; TargetIntel = new EnemyShipIntel(); } EnemyShipIntel enemyIntel = (EnemyShipIntel)TargetIntel; enemyIntel.ID = target.EntityId; if (validated && (target.Type != MyDetectedEntityType.Unknown || !gotNewIntel)) { enemyIntel.DisplayName = target.Name; enemyIntel.FromDetectedInfo(target, canonicalTime); IntelProvider.ReportFleetIntelligence(enemyIntel, localTime); } else if (enemyIntel.LastValidatedCanonicalTime + TimeSpan.FromSeconds(0.5) < canonicalTime) { TryScanTarget(target.Position, localTime, enemyIntel); } }
void DrawMiddleHUD(TimeSpan localTime) { if (Host.ActiveLookingGlass.MiddleHUDs.Count == 0) { return; } SpriteScratchpad.Clear(); Host.GetDefaultSprites(SpriteScratchpad); float closestDistSqr = 200 * 200; long newClosestIntelID = -1; foreach (IFleetIntelligence intel in Host.IntelProvider.GetFleetIntelligences(localTime).Values) { if (intel.IntelItemType == IntelItemType.Friendly) { var fsi = (FriendlyShipIntel)intel; if ((fsi.AgentStatus & AgentStatus.DockedAtHome) != 0) { continue; } LookingGlass.IntelSpriteOptions options = LookingGlass.IntelSpriteOptions.Small; if (fsi.AgentClass == AgentClass.None) { options = LookingGlass.IntelSpriteOptions.ShowName; } Host.ActiveLookingGlass.FleetIntelItemToSprites(intel, localTime, Host.ActiveLookingGlass.kFriendlyBlue, ref SpriteScratchpad, options); } else if (intel.IntelItemType == IntelItemType.Enemy) { LookingGlass.IntelSpriteOptions options = LookingGlass.IntelSpriteOptions.None; if (HostProgram.ScannerSubsystem.WCHardlockTargets.ContainsKey(intel.ID)) { options |= LookingGlass.IntelSpriteOptions.EmphasizeWithDashes; } if (!EnemyShipIntel.PrioritizeTarget((EnemyShipIntel)intel) || Host.IntelProvider.GetPriority(intel.ID) < 2) { options = LookingGlass.IntelSpriteOptions.Small; Host.ActiveLookingGlass.FleetIntelItemToSprites(intel, localTime, Host.ActiveLookingGlass.kEnemyRed, ref SpriteScratchpad, options); } else { if (intel.ID == closestEnemyToCursorID) { options |= LookingGlass.IntelSpriteOptions.ShowDist | LookingGlass.IntelSpriteOptions.EmphasizeWithBrackets | LookingGlass.IntelSpriteOptions.NoCenter | LookingGlass.IntelSpriteOptions.ShowLastDetected; if (FeedbackOnTarget) { options |= LookingGlass.IntelSpriteOptions.EmphasizeWithCross; } options |= LookingGlass.IntelSpriteOptions.ShowTruncatedName; } var distToCenterSqr = Host.ActiveLookingGlass.FleetIntelItemToSprites(intel, localTime, Host.ActiveLookingGlass.kEnemyRed, ref SpriteScratchpad, options).LengthSquared(); if (distToCenterSqr < closestDistSqr) { closestDistSqr = distToCenterSqr; newClosestIntelID = intel.ID; } } } } closestEnemyToCursorID = newClosestIntelID; Builder.Clear(); if (CAPMode == 1) { FeedbackText = "CAP ON - AIM MODE - 3 FULL"; } else if (CAPMode == 3) { FeedbackText = "CAP ON - FULL MODE - 3 OFF"; } else { FeedbackText = string.Empty; } foreach (var screen in Host.ActiveLookingGlass.MiddleHUDs) { using (var frame = screen.DrawFrame()) { foreach (var spr in SpriteScratchpad) { frame.Add(spr); } if (FeedbackText != string.Empty) { var prompt = MySprite.CreateText(FeedbackText, "Debug", Color.HotPink, 0.9f); prompt.Position = new Vector2(0, -45) + screen.TextureSize / 2f; frame.Add(prompt); } var HUD = MySprite.CreateText(Builder.ToString(), "Monospace", Color.LightBlue, 0.3f); HUD.Position = new Vector2(0, -25) + screen.TextureSize / 2f; frame.Add(HUD); } } FeedbackOnTarget = false; }
public void Do(Dictionary <MyTuple <IntelItemType, long>, IFleetIntelligence> IntelItems, TimeSpan canonicalTime, Profiler profiler) { if (canonicalTime == TimeSpan.Zero) { return; } runs++; if (MonitorSubsystem != null && (MonitorSubsystem.GetPercentage(MonitorOptions.Hydrogen) < 0.2 || MonitorSubsystem.GetPercentage(MonitorOptions.Cargo) < 0.02 || MonitorSubsystem.GetPercentage(MonitorOptions.Power) < 0.1)) { GoHome(canonicalTime); return; } IMyShipController controller = Autopilot.Controller; Vector3D linearVelocity = controller.GetShipVelocities().LinearVelocity; var currentPosition = controller.WorldMatrix.Translation; LeadTask.Destination.MaxSpeed = Autopilot.CruiseSpeed; if (!TargetPositionSet) { if (IntelKey.Item1 == IntelItemType.Waypoint && IntelItems.ContainsKey(IntelKey)) { TargetPosition = IntelItems[IntelKey].GetPositionFromCanonicalTime(canonicalTime); PatrolMaxSpeed = ((Waypoint)IntelItems[IntelKey]).MaxSpeed; } TargetPositionSet = true; } EnemyShipIntel orbitIntel = null; EnemyShipIntel shootIntel = null; double closestIntelDist = CombatSystem.AlertDist; foreach (var intel in IntelItems) { if (intel.Key.Item1 != IntelItemType.Enemy) { continue; } var enemyIntel = (EnemyShipIntel)intel.Value; if (!EnemyShipIntel.PrioritizeTarget(enemyIntel)) { continue; } if (IntelProvider.GetPriority(enemyIntel.ID) < 2) { continue; } double dist = (enemyIntel.GetPositionFromCanonicalTime(canonicalTime) - controller.WorldMatrix.Translation).Length(); if (IntelKey.Item1 == IntelItemType.Enemy && enemyIntel.ID != IntelKey.Item2 && FocusedTarget) { continue; } if (enemyIntel.CubeSize == MyCubeSize.Small) { dist -= 300; } if (IntelProvider.GetPriority(enemyIntel.ID) == 3) { dist -= 600; } if (IntelProvider.GetPriority(enemyIntel.ID) == 4) { dist -= 1200; } if (dist < closestIntelDist) { closestIntelDist = dist; shootIntel = enemyIntel; if (enemyIntel.Radius > 30) { orbitIntel = enemyIntel; } } } if (shootIntel == null && CombatSystem.TargetIntel != null && IntelProvider.GetPriority(CombatSystem.TargetIntel.ID) >= 2) { shootIntel = CombatSystem.TargetIntel; } if (orbitIntel == null) { orbitIntel = shootIntel; } var gravdir = Autopilot.Controller.GetNaturalGravity(); if (gravdir != Vector3D.Zero) { gravdir.Normalize(); } // No Target if (orbitIntel == null) { // Plot Intercept if (IntelKey.Item1 == IntelItemType.Enemy && IntelItems.ContainsKey(IntelKey) && EnemyShipIntel.PrioritizeTarget((EnemyShipIntel)IntelItems[IntelKey]) && IntelProvider.GetPriority(IntelKey.Item2) >= 2) { var target = IntelItems[IntelKey]; LeadTask.Destination.Position = currentPosition + AttackHelpers.GetAttackPoint(target.GetVelocity(), target.GetPositionFromCanonicalTime(canonicalTime) + target.GetVelocity() * 0.08 - currentPosition, Autopilot.CruiseSpeed); } // Go to Position ( Scramble ) else if (TargetPosition != Vector3.Zero) { LeadTask.Destination.MaxSpeed = PatrolMaxSpeed; LeadTask.Destination.Position = TargetPosition; } else { GoHome(canonicalTime); return; } Vector3D toTarget = LeadTask.Destination.Position - Program.Me.WorldMatrix.Translation; if (toTarget.LengthSquared() > 400) { if (gravdir == Vector3D.Zero) { LeadTask.Destination.Direction = toTarget; } else { LeadTask.Destination.Direction = Vector3D.Zero; } } else { LeadTask.Destination.Direction = Vector3D.Zero; } LastAcceleration = Vector3D.Zero; LastReference = MatrixD.Zero; LastEnemyVelocity = Vector3D.Zero; LastEnemyPosition = Vector3D.Zero; LastRelativeAttackPoint = Vector3D.Zero; // targetLastPoweredRun = 0; } // Orbiting a Target else { CombatSystem.MarkEngaged(); LeadTask.Destination.MaxSpeed = Autopilot.CombatSpeed; Vector3D targetPosition = orbitIntel.GetPositionFromCanonicalTime(canonicalTime); var periodicFactor = runs * Math.PI * CombatSystem.EngageTheta / 4; Vector3D periodicDirection = Math.Sin(periodicFactor) * controller.WorldMatrix.Left + Math.Cos(periodicFactor) * controller.WorldMatrix.Up; var Acceleration = linearVelocity - LastLinearVelocity; if (LastAcceleration == Vector3D.Zero) { LastAcceleration = Acceleration; } if (LastReference == MatrixD.Zero) { LastReference = controller.WorldMatrix; } if (LastEnemyVelocity == Vector3D.Zero) { LastEnemyVelocity = shootIntel.GetVelocity(); } if (LastEnemyPosition == Vector3D.Zero) { LastEnemyPosition = shootIntel.GetPositionFromCanonicalTime(canonicalTime); } var enemyAcceleration = shootIntel.GetVelocity() - LastEnemyVelocity; var enemyVelocityAdjust = shootIntel.GetVelocity() * 2 - LastEnemyVelocity; var CurrentAccelerationPreviousFrame = Vector3D.TransformNormal(Acceleration, MatrixD.Transpose(LastReference)); var accelerationAdjust = Vector3D.TransformNormal(CurrentAccelerationPreviousFrame, controller.WorldMatrix); var velocityAdjust = linearVelocity + accelerationAdjust * 0.4; velocityAdjust *= CombatSystem.OwnSpeedMultiplier; Vector3D relativeAttackPoint = AttackHelpers.GetAttackPoint(enemyVelocityAdjust - velocityAdjust, shootIntel.GetPositionFromCanonicalTime(canonicalTime) + enemyVelocityAdjust * 0.25 - controller.WorldMatrix.Translation - velocityAdjust * 0.25, CombatSystem.ProjectileSpeed); relativeAttackPoint.Normalize(); if (LastRelativeAttackPoint == Vector3D.Zero) { LastRelativeAttackPoint = relativeAttackPoint; } LastAcceleration = linearVelocity - LastLinearVelocity; LeadTask.Destination.Direction = relativeAttackPoint; if ((controller.WorldMatrix.Translation - targetPosition).Length() < CombatSystem.FireDist && VectorHelpers.VectorAngleBetween(LeadTask.Destination.Direction, controller.WorldMatrix.Forward) < CombatSystem.FireTolerance) { CombatSystem.Fire(); } Vector3D dirTargetToMe = controller.WorldMatrix.Translation - targetPosition; var distTargetToMe = dirTargetToMe.Length(); dirTargetToMe.Normalize(); if (Mode == 0) { Vector3D dirTargetToOrbitTarget = Vector3D.Cross(dirTargetToMe, controller.WorldMatrix.Up); dirTargetToOrbitTarget.Normalize(); if (gravdir == Vector3D.Zero) { LeadTask.Destination.DirectionUp = Math.Sin(CombatSystem.EngageTheta) * controller.WorldMatrix.Right + Math.Cos(CombatSystem.EngageTheta) * controller.WorldMatrix.Up; LeadTask.Destination.Position = targetPosition + orbitIntel.GetVelocity() + dirTargetToMe * CombatSystem.EngageDist + dirTargetToOrbitTarget * 200; } else { var flatDirTargetToMe = dirTargetToMe - VectorHelpers.VectorProjection(dirTargetToMe, gravdir); flatDirTargetToMe.Normalize(); LeadTask.Destination.Position = targetPosition + orbitIntel.GetVelocity() + flatDirTargetToMe * CombatSystem.EngageDist * 0.9 - gravdir * 300 + periodicDirection * 100; } LeadTask.Destination.Velocity = orbitIntel.GetVelocity() * 0.5; } else if (Mode == 2) { LeadTask.Destination.Position = targetPosition + dirTargetToMe * (CombatSystem.EngageDist + (CombatSystem.EngageDist - distTargetToMe)); LeadTask.Destination.Velocity = orbitIntel.GetVelocity(); } LastReference = controller.WorldMatrix; LastEnemyVelocity = shootIntel.GetVelocity(); LastEnemyPosition = shootIntel.GetPositionFromCanonicalTime(canonicalTime); LastRelativeAttackPoint = relativeAttackPoint; //var n = VectorHelpers.VectorProjection(enemyAcceleration, gravdir).Length() / enemyAcceleration.Length(); // //if (targetLastPoweredRun == 0 || n < 0.6) // targetLastPoweredRun = runs; // //if (runs - targetLastPoweredRun > 20) // IntelProvider.SetPriority(shootIntel.ID, 1); } if (!Attack) { Vector3D toTarget = TargetPosition - Program.Me.WorldMatrix.Translation; if (toTarget.LengthSquared() > 100) { LeadTask.Destination.Position = TargetPosition; } else { LeadTask.Destination.Position = Vector3D.Zero; } LeadTask.Destination.Velocity = Vector3D.Zero; } if (Mode == 1) { //TODO: Add support for disabling dampeners in this mode - let pilot have full control aside from aiming LeadTask.Destination.Position = controller.GetPosition(); LeadTask.Destination.Velocity = Vector3D.Zero; if (shootIntel == null) { LeadTask.Destination.Direction = Vector3D.Zero; LeadTask.Destination.DirectionUp = Vector3D.Zero; } } LastLinearVelocity = linearVelocity; if (LeadTask.Status == TaskStatus.Incomplete) { LeadTask.Do(IntelItems, canonicalTime, profiler); } }
public void Main(string argument, UpdateType updateSource) { Context.UpdateTime(); if (argument == "combatautopilottoggle") { CombatAutopilot = !CombatAutopilot; // foreach (var welder in Welders) // { // welder.Enabled = true; // } if (!CombatAutopilot) { AgentSubsystem.AddTask(TaskType.None, MyTuple.Create(IntelItemType.NONE, (long)0), CommandType.Override, 0, TimeSpan.Zero); AutopilotSubsystem.Clear(); } UpdateName(); } else if (commandLine.TryParse(argument)) { subsystemManager.CommandV2(commandLine); } else { runs++; /* * if (Connector != null && runs % 5 == 0) * { * if (lastDocked) * { * if (Connector.Status == MyShipConnectorStatus.Connectable) * { * if (scriptDocked) * { * scriptDocked = false; * } * else * { * scriptDocked = true; * DockingSubsystem.Dock(); * } * } * } * else * { * if (Connector.Status == MyShipConnectorStatus.Connected) * { * DockingSubsystem.Dock(); * } * } * * if (scriptDocked && !CombatLoaderSubsystem.LoadingInventory && CombatLoaderSubsystem.QueueReload == 0) * { * DockingSubsystem.Undock(); * } * * lastDocked = Connector.Status == MyShipConnectorStatus.Connected; * scriptDocked = scriptDocked && lastDocked; * } */ if (runs % 30 == 0) { if (CombatAutopilot) { var hadTarget = PriorityTarget != null; var intelItems = IntelSubsystem.GetFleetIntelligences(Context.LocalTime); PriorityTarget = null; float HighestEnemyPriority = 0; foreach (var kvp in intelItems) { if (kvp.Key.Item1 == IntelItemType.Enemy) { var enemy = kvp.Value as EnemyShipIntel; var dist = (int)(enemy.GetPositionFromCanonicalTime(Context.CanonicalTime) - Me.GetPosition()).Length(); var size = enemy.Radius; if (dist > 2000 || size < 30) { continue; } var priority = 2000 - dist; if (priority > HighestEnemyPriority) { PriorityTarget = enemy; HighestEnemyPriority = priority; LargestTargetDist = dist; } } } if (PriorityTarget == null) { if (hadTarget) { AgentSubsystem.AddTask(TaskType.None, MyTuple.Create(IntelItemType.NONE, (long)0), CommandType.Override, 0, TimeSpan.Zero); AutopilotSubsystem.Clear(); } } else { AgentSubsystem.AddTask(TaskType.Attack, MyTuple.Create(IntelItemType.Enemy, PriorityTarget.ID), CommandType.Override, 0, Context.CanonicalTime); } } else { PriorityTarget = null; } UpdateName(); } subsystemManager.Update(updateSource); var status = subsystemManager.GetStatus(); if (status != string.Empty) { Echo(status); } } }
public ScannerNetworkSubsystem.TryScanResults TryScan(IIntelProvider intelProvider, Vector3D targetPosition, EnemyShipIntel enemy, TimeSpan localTime) { foreach (var camera in Cameras) { if (!camera.IsWorking) { continue; } var result = Host.CameraTryScan(intelProvider, camera, targetPosition, localTime, enemy); if (result == ScannerNetworkSubsystem.TryScanResults.Scanned) { return(result); } if (result == ScannerNetworkSubsystem.TryScanResults.DoNotRetry) { return(ScannerNetworkSubsystem.TryScanResults.Retry); // This array cannot scan } } return(ScannerNetworkSubsystem.TryScanResults.Retry); }
public TryScanResults CameraTryScan(IIntelProvider intelProvider, IMyCameraBlock camera, Vector3D targetPosition, TimeSpan localTime, EnemyShipIntel enemy) { var cameraToTarget = targetPosition - camera.WorldMatrix.Translation; var cameraDist = cameraToTarget.Length(); if (!camera.CanScan(cameraDist + this.ScanExtent)) { return(TryScanResults.Retry); } if (!camera.CanScan(targetPosition)) { return(TryScanResults.Retry); } cameraToTarget.Normalize(); var cameraFinalPosition = cameraToTarget * (cameraDist + this.ScanExtent) + camera.WorldMatrix.Translation; var info = camera.Raycast(cameraFinalPosition); if (info.IsEmpty()) { return(TryScanResults.Retry); } // if ((ProgramReference.CubeGrid.GetPosition() - info.HitPosition.Value).Length() < ProgramReference.CubeGrid.WorldAABB.Size.Length()) // return TryScanResults.Retry; if (info.Relationship == MyRelationsBetweenPlayerAndBlock.NoOwnership) { return(TryScanResults.DoNotRetry); } if (enemy.ID != 0 && info.EntityId != enemy.ID) { return(TryScanResults.Retry); } if (info.BoundingBox.Size.Length() * 0.5f < 4) { return(TryScanResults.Retry); //debugBuilder.AppendLine($"SUSP: {info.BoundingBox.Size.Length() * 0.5f}"); //debugBuilder.AppendLine($"{info.Name}"); //debugBuilder.AppendLine($"{info.EntityId}"); //debugBuilder.AppendLine($"{(int)info.Position.X}, {(int)info.Position.Y}, {(int)info.Position.Z}"); //debugBuilder.AppendLine($"{(int)info.Velocity.X}, {(int)info.Velocity.Y}, {(int)info.Velocity.Z}"); //debugBuilder.AppendLine($"========"); //debugBuilder.AppendLine($"{enemy.ID}"); //var enemyPos = enemy.GetPositionFromCanonicalTime(localTime + IntelProvider.CanonicalTimeDiff); //debugBuilder.AppendLine($"{(int)enemyPos.X}, {(int)enemyPos.Y}, {(int)enemyPos.Z}"); //debugBuilder.AppendLine($"{(int)enemy.CurrentVelocity.X}, {(int)enemy.CurrentVelocity.Y}, {(int)enemy.CurrentVelocity.Z}"); //debugBuilder.AppendLine($"{enemy.Radius}"); } enemy.FromDetectedInfo(info, localTime + intelProvider.CanonicalTimeDiff); intelProvider.ReportFleetIntelligence(enemy, localTime); return(TryScanResults.Scanned); }
public void TryScanTarget(Vector3D targetPosition, TimeSpan localTime, EnemyShipIntel enemy = null) { var scanned = false; double offsetDist = 0.0d; var random = Context.Random; if (enemy == null) { enemy = new EnemyShipIntel(); } else { offsetDist = enemy.Radius * ScanScatter; } Vector3D offset; for (int i = 0; i < ScannerGroups.Count; i++) { offset = new Vector3D(random.NextDouble() - 0.5, random.NextDouble() - 0.5, random.NextDouble() - 0.5) * offsetDist; if (ScannerGroups[i] != null) { var result = ScannerGroups[i].TryScan(IntelProvider, targetPosition + offset, enemy, localTime); if (result == TryScanResults.Scanned) { scanned = true; break; } } } if (scanned) { return; } int failures = 0; CameraRetrys.Clear(); CameraRetrys.AddRange(Cameras); while (CameraRetrys.Count > Cameras.Count * 0.6) { var index = random.Next(0, CameraRetrys.Count); var camera = CameraRetrys[index]; CameraRetrys.RemoveAt(index); if (!camera.IsWorking) { continue; } offset = new Vector3D(random.NextDouble() - 0.5, random.NextDouble() - 0.5, random.NextDouble() - 0.5) * offsetDist; var result = CameraTryScan(IntelProvider, camera, targetPosition + offset, localTime, enemy); bool terminate = true; switch (result) { case TryScanResults.Retry: failures++; terminate = false; break; case TryScanResults.DoNotRetry: // debugBuilder.AppendLine("CTS R=" + result.ToString()); break; case TryScanResults.Scanned: scanned = true; // debugBuilder.AppendLine("CTS R=" + result.ToString()); break; } if (terminate || failures > 5) { break; } } // debugBuilder.AppendLine("CTS F=" + failures.ToString() + " T=" + Cameras.Count); }
void TryScan(TimeSpan localTime) { // Go through each target var intelItems = IntelProvider.GetFleetIntelligences(localTime); var canonicalTime = localTime + IntelProvider.CanonicalTimeDiff; DetectedTargets.Clear(); // WC only... // Context.Log.Debug("A"); if (Context.WCAPI != null) { GetThreatsScratchpad.Clear(); Context.WCAPI.GetSortedThreats(Context.Reference, GetThreatsScratchpad); foreach (var target in GetThreatsScratchpad.Keys) { DetectedTargets[target.EntityId] = MyTuple.Create(target, true); } int priority = 0; while (true) { var selectedTarget = Context.WCAPI.GetAiFocus(Context.Reference.CubeGrid.EntityId, priority); if (selectedTarget == null) { break; } TryAddEnemyShipIntel(intelItems, localTime, canonicalTime, selectedTarget.Value, true, true); break; } } // Context.Log.Debug("B"); else { foreach (var turret in Turrets) { if (!turret.HasTarget) { continue; } var target = turret.GetTargetedEntity(); if (!target.IsEmpty() && !DetectedTargets.ContainsKey(target.EntityId)) { DetectedTargets[target.EntityId] = MyTuple.Create(target, false); } } } // Context.Log.Debug("C"); foreach (var target in DetectedTargets) { TryAddEnemyShipIntel(intelItems, localTime, canonicalTime, target.Value.Item1, target.Value.Item2); } // Context.Log.Debug("D"); foreach (var kvp in intelItems) { if (kvp.Key.Item1 != IntelItemType.Enemy) { continue; } EnemyShipIntel enemy = (EnemyShipIntel)kvp.Value; int priority = IntelProvider.GetPriority(kvp.Key.Item2); if (priority < 1) { continue; } if (!EnemyShipIntel.PrioritizeTarget(enemy)) { continue; } if (enemy.LastValidatedCanonicalTime + TimeSpan.FromSeconds(0.2) > canonicalTime) { continue; } if (enemy.LastValidatedCanonicalTime + TimeSpan.FromSeconds(0.4) > canonicalTime && priority < 4) { continue; } Vector3D targetPosition = kvp.Value.GetPositionFromCanonicalTime(canonicalTime); TryScanTarget(targetPosition, localTime, enemy); } }
public void Update(TimeSpan timestamp, UpdateFrequency updateFlags) { if (timestamp == TimeSpan.Zero) { return; } foreach (var bird in Hummingbirds) { if (bird.IsAlive()) { bird.Update(); } else { DeadBirds.Add(bird); } } foreach (var bird in DeadBirds) { DeregisterBird(bird); } runs++; if (runs % 20 == 0) { var intelItems = IntelProvider.GetFleetIntelligences(timestamp); // Get the top targets TopEnemies.Clear(); EnemyToScore.Clear(); foreach (var intelItem in intelItems) { if (intelItem.Key.Item1 == IntelItemType.Enemy) { var esi = (EnemyShipIntel)intelItem.Value; var dist = (esi.GetPositionFromCanonicalTime(timestamp + IntelProvider.CanonicalTimeDiff) - Context.Reference.WorldMatrix.Translation).Length(); if (dist > MaxEngagementDist) { continue; } var priority = IntelProvider.GetPriority(esi.ID); var size = esi.Radius; if (size < MinEngagementSize && priority < 3) { continue; } if (priority < 2) { continue; } int score = (int)(priority * 10000 + size); EnemyToScore[esi] = score; for (int i = 0; i <= TopEnemies.Count; i++) { if (i == TopEnemies.Count || score > EnemyToScore[TopEnemies[i]]) { TopEnemies.Insert(i, esi); break; } } } } // Determine how many birds should be assigned to each enemy EnemyToNumBirds.Clear(); int totalNeededBirds = 0; for (int i = 0; i < TopEnemies.Count && i < 4; i++) { EnemyToNumBirds[TopEnemies[i]] = EnemyCountToNumBirdsPerEnemy[TopEnemies.Count][i]; EnemyToAssignedBirds[TopEnemies[i]] = 0; totalNeededBirds += EnemyToNumBirds[TopEnemies[i]]; } // Remove excess birds from enemies foreach (var bird in Hummingbirds) { var birdTargetID = BirdToEnemy[bird]; if (birdTargetID == 0) { continue; } if (!bird.IsCombatCapable()) { BirdToEnemy[bird] = 0; continue; } var birdTargetKey = MyTuple.Create(IntelItemType.Enemy, birdTargetID); if (!intelItems.ContainsKey(birdTargetKey)) { BirdToEnemy[bird] = 0; continue; } var birdTarget = (EnemyShipIntel)intelItems[birdTargetKey]; if (!EnemyToNumBirds.ContainsKey(birdTarget) || EnemyToNumBirds[birdTarget] == 0) { BirdToEnemy[bird] = 0; continue; } EnemyToNumBirds[birdTarget]--; totalNeededBirds--; } // Assign birds to enemies foreach (var bird in Hummingbirds) { if (totalNeededBirds == 0) { break; } // Bird can't fight, keep looking if (!bird.IsCombatCapable()) { continue; } // Bird already has target, keep looking if (BirdToEnemy[bird] != 0) { continue; } EnemyShipIntel targetEnemy = null; foreach (var enemy in EnemyToNumBirds.Keys) { if (EnemyToNumBirds[enemy] > 0) { targetEnemy = enemy; break; } } BirdToEnemy[bird] = targetEnemy.ID; EnemyToNumBirds[targetEnemy]--; totalNeededBirds--; } NeedsMoreBirds = totalNeededBirds > 0; int birdIndex; // ASSUME birds are not far enough from main controller that gravity direction matters too much var gravDir = Controller.GetTotalGravity(); gravDir.Normalize(); // For each enemy, assign bird target and destination foreach (var enemy in TopEnemies) { birdIndex = 0; foreach (var bird in Hummingbirds) { if (BirdToEnemy[bird] != enemy.ID) { continue; } if (bird.Gats.Count == 0) { continue; } var birdAltitudeTheta = Math.PI * ((runs / (BirdSineConstantSeconds * 30) % 2) - 1); var birdSwayTheta = Math.PI * ((runs / (BirdPendulumConstantSeconds * 30) % 2) - 1); var targetPos = enemy.GetPositionFromCanonicalTime(timestamp + IntelProvider.CanonicalTimeDiff); bird.SetTarget(targetPos, enemy.GetVelocity() - gravDir * (float)TrigHelpers.FastCos(birdAltitudeTheta) * 2); var targetToBase = bird.Base.WorldMatrix.Translation - targetPos; targetToBase -= VectorHelpers.VectorProjection(targetToBase, gravDir); var targetToBaseDist = targetToBase.Length(); targetToBase.Normalize(); var engageLocationLocus = targetToBase * Math.Min(600, targetToBaseDist + 400) + targetPos; var engageLocationSwayDir = targetToBase.Cross(gravDir); var engageLocationSwayDist = (TrigHelpers.FastCos(birdSwayTheta) - EnemyToAssignedBirds[enemy] * 0.5 + birdIndex + 0.5) * 100; bird.SetDest(engageLocationLocus + engageLocationSwayDist * engageLocationSwayDir); var birdDir = bird.Controller.WorldMatrix.Translation - Controller.WorldMatrix.Translation; birdDir -= VectorHelpers.VectorProjection(birdDir, gravDir);; var birdDist = birdDir.Length(); bird.Drive.DesiredAltitude = birdDist < 100 ? Hummingbird.RecommendedServiceCeiling : (float)TrigHelpers.FastSin(birdAltitudeTheta + Math.PI * 0.5) * (Hummingbird.RecommendedServiceCeiling - Hummingbird.RecommendedServiceFloor) + Hummingbird.RecommendedServiceFloor; birdIndex++; } } // Assign orbit task for unassigned birds int numReserveBirds = 0; foreach (var bird in Hummingbirds) { if (BirdToEnemy[bird] == 0 && bird.IsCombatCapable()) { numReserveBirds++; } } birdIndex = 0; var randomPoint = new Vector3D(190, 2862, 809); randomPoint -= VectorHelpers.VectorProjection(randomPoint, gravDir); randomPoint.Normalize(); var randomPointCross = randomPoint.Cross(gravDir); foreach (var bird in Hummingbirds) { if (BirdToEnemy[bird] != 0) { continue; } bird.SetTarget(Vector3D.Zero, Vector3D.Zero); bird.Drive.DesiredAltitude = 30; if (bird.IsCombatCapable() && !bird.IsRetiring) { var birdOrbitTheta = Math.PI * (((2 * birdIndex / (float)numReserveBirds) + runs / (BirdOrbitSeconds * 30)) % 2 - 1); var birdOrbitDest = Controller.WorldMatrix.Translation + TrigHelpers.FastCos(birdOrbitTheta) * randomPoint * BirdOrbitDist + TrigHelpers.FastSin(birdOrbitTheta) * randomPointCross * BirdOrbitDist; bird.SetDest(birdOrbitDest); birdIndex++; } else if (!bird.IsRetiring) { RetireBird(bird); } else if (bird.IsRetiring) { if (!bird.IsLanding) { var birdDir = bird.Controller.WorldMatrix.Translation - bird.Destination; birdDir -= VectorHelpers.VectorProjection(birdDir, gravDir); var birdDist = birdDir.Length(); birdDir.Normalize(); if (birdDist < 50) { bird.SetDest(Vector3D.Zero); bird.Drive.Flush(); foreach (var engine in bird.Drive.HoverEngines) { engine.AltitudeMin = 0; } bird.IsLanding = true; } } else { double altitude; bird.Controller.TryGetPlanetElevation(MyPlanetElevation.Surface, out altitude); if (altitude < 6) { foreach (var engine in bird.Drive.HoverEngines) { engine.Block.Enabled = false; DeadBirds.Add(bird); } } } } } } foreach (var cradle in Cradles) { if (cradle == null) { continue; } cradle.Update(); } if (runs % 60 == 0) { BirdReleaseTimeout--; for (int i = 0; i < Cradles.Count(); i++) { if (Cradles[i] == null) { continue; } if (Cradles[i].Hummingbird == null) { Cradles[i].CheckHummingbird(); } else if (NeedsMoreBirds && BirdReleaseTimeout <= 0) { Hummingbird bird = Cradles[i].Release(); bird.Base = Context.Reference; RegisterBird(bird); BirdReleaseTimeout = 5; } } } DeadBirds.Clear(); }