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 Do(Dictionary <MyTuple <IntelItemType, long>, IFleetIntelligence> IntelItems, TimeSpan canonicalTime, Profiler profiler) { if (canonicalTime == TimeSpan.Zero) { return; } if (MiningSystem.Recalling > 0 || currentPosition > 120) { Recalling = true; } if (Recalling && state < 3) { state = 3; } if (state == 1) // Diving to surface of asteroid { MineTask.Do(IntelItems, canonicalTime, profiler); MineTask.Destination.MaxSpeed = Autopilot.GetMaxSpeedFromBrakingDistance(kFarSensorDist); if (MineTask.Status == TaskStatus.Complete || !MiningSystem.SensorsFarClear()) { EntryPoint = Autopilot.Reference.WorldMatrix.Translation + MineTask.Destination.Direction * (kFarSensorDist - 10); MineTask.Destination.MaxSpeed = 1f; state = 2; } } else if (state == 2) // Boring tunnel { bool sampleHome = false; double distToMiningEnd = (Autopilot.Reference.WorldMatrix.Translation - MiningEnd).Length(); if (MiningSystem.SensorsClear()) { MineTask.Destination.Position = MiningEnd; } else if (MiningSystem.SensorsBack()) { MineTask.Destination.Position = EntryPoint; } else { MineTask.Destination.Position = Vector3D.Zero; if (SampleCount <= 0) { SampleCount = kSampleFrequency; var cargoPercentage = MonitorSubsystem.GetPercentage(MonitorOptions.Cargo); if (LastSampleCargoPercentages.Count >= kMaxSampleCount) { LastSampleCargoPercentages.Enqueue(cargoPercentage); var sampleGreater = 0; var sampleLesser = 0; var comparePercentage = LastSampleCargoPercentages.Dequeue() + 0.00001; foreach (var percentage in LastSampleCargoPercentages) { if (percentage > comparePercentage) { sampleGreater++; } else { sampleLesser++; } } if (sampleGreater > sampleLesser) { if (!HitOre) { HitOre = true; var currentCoords = GetMiningPosition(currentPosition); miningMatrix[currentCoords.X + 5, currentCoords.Y + 5] = 1; } if (LowestExpectedOreDist == -1) { LowestExpectedOreDist = (float)distToMiningEnd - 5; } } else { if (HitOre || distToMiningEnd < LowestExpectedOreDist) { sampleHome = true; if (!HitOre) { var currentCoords = GetMiningPosition(currentPosition); miningMatrix[currentCoords.X + 5, currentCoords.Y + 5] = 2; } } } } else { LastSampleCargoPercentages.Enqueue(cargoPercentage); } } else { SampleCount--; } } MiningSystem.Drill(); MineTask.Do(IntelItems, canonicalTime, profiler); if (GoHomeCheck() || MiningSystem.SensorsFarClear() || distToMiningEnd < 4 || sampleHome) { if (MiningSystem.SensorsFarClear() || distToMiningEnd < 4 || sampleHome) { UpdateMiningMatrix(currentPosition); IncrementCurrentPosition(); HitOre = false; } state = 3; MineTask.Destination.MaxSpeed = 2; LastSampleCargoPercentages.Clear(); } } else if (state == 3) // Exiting tunnel { MiningSystem.StopDrill(); if (MineTask.Destination.Position != ExitPoint) { MineTask.Destination.Position = EntryPoint; } MineTask.Do(IntelItems, canonicalTime, profiler); if (MineTask.Status == TaskStatus.Complete) { if (MineTask.Destination.Position == EntryPoint) { MineTask.Destination.Position = ExitPoint; MineTask.Destination.MaxSpeed = 100; } else { state = 10; } } } else if (state == 10) // Resuming to approach point { if (GoHomeCheck() || Recalling) { state = 4; } else { LeadTask.Destination.Position = ApproachPoint; LeadTask.Do(IntelItems, canonicalTime, profiler); if (LeadTask.Status == TaskStatus.Complete) { var position = GetMiningPosition(currentPosition); LeadTask.Destination.Position = ApproachPoint + (Perpendicular * position.X * MiningSystem.OffsetDist + Perpendicular.Cross(MineTask.Destination.Direction) * position.Y * MiningSystem.OffsetDist); LeadTask.Destination.MaxSpeed = 10; ExitPoint = LeadTask.Destination.Position; state = 11; } } } else if (state == 11) // Search for the digging spot { if (GoHomeCheck() || Recalling) { state = 4; } else { LeadTask.Do(IntelItems, canonicalTime, profiler); if (LeadTask.Status == TaskStatus.Complete) { state = 1; MiningSystem.SensorsOn(); var position = GetMiningPosition(currentPosition); MineTask.Destination.Position = SurfacePoint + (Perpendicular * position.X * MiningSystem.OffsetDist + Perpendicular.Cross(MineTask.Destination.Direction) * position.Y * MiningSystem.OffsetDist) - MineTask.Destination.Direction * MiningSystem.CloseDist; MiningEnd = SurfacePoint + (Perpendicular * position.X * MiningSystem.OffsetDist + Perpendicular.Cross(MineTask.Destination.Direction) * position.Y * MiningSystem.OffsetDist) + MineTask.Destination.Direction * MiningDepth; } } } else if (state == 4) // Going home { if (DockingSubsystem == null || DockingSubsystem.HomeID == -1 || DockTaskGenerator == null || UndockTaskGenerator == null) { state = 9999; } else { if (HomeTask == null) { HomeTask = DockTaskGenerator.GenerateMoveToAndDockTask(MyTuple.Create(IntelItemType.NONE, (long)0), IntelItems, 40); } HomeTask.Do(IntelItems, canonicalTime, profiler); if (HomeTask.Status != TaskStatus.Incomplete) { HomeTask = null; homeCheck = false; state = 5; } } } else if (state == 5) // Waiting for refuel/unload { if (Recalling) { state = 9999; } if ((Program.Me.WorldMatrix.Translation - EntryPoint).LengthSquared() > MiningSystem.CancelDist * MiningSystem.CancelDist) { state = 9999; } if (LeaveHomeCheck()) { state = 6; } } else if (state == 6) // Undocking { if (DockingSubsystem != null && DockingSubsystem.Connector.Status == MyShipConnectorStatus.Connected) { if (UndockTask == null) { UndockTask = UndockTaskGenerator.GenerateUndockTask(canonicalTime); } } if (UndockTask != null) { UndockTask.Do(IntelItems, canonicalTime, profiler); if (UndockTask.Status != TaskStatus.Incomplete) { UndockTask = null; state = 10; } } else { state = 10; } } else if (state == 9999) { Status = TaskStatus.Complete; } }
public void Do(Dictionary <MyTuple <IntelItemType, long>, IFleetIntelligence> IntelItems, TimeSpan canonicalTime, Profiler profiler) { IMyShipController controller = Autopilot.Controller; var currentPosition = controller.WorldMatrix.Translation; Vector3D linearVelocity = controller.GetShipVelocities().LinearVelocity; if (!TargetPositionSet) { if (IntelKey.Item1 == IntelItemType.Waypoint && IntelItems.ContainsKey(IntelKey)) { TargetPosition = IntelItems[IntelKey].GetPositionFromCanonicalTime(canonicalTime); } TargetPositionSet = true; } Vector3D worldAttackPoint; if (TargetPositionSet && TargetPosition != Vector3D.Zero) { worldAttackPoint = TargetPosition; } else { if (IntelKey.Item1 != IntelItemType.Enemy || !IntelItems.ContainsKey(IntelKey)) { AgentSubsystem.AddTask(TaskType.Dock, MyTuple.Create(IntelItemType.NONE, (long)0), CommandType.Enqueue, 0, canonicalTime); Status = TaskStatus.Aborted; return; } var target = (EnemyShipIntel)IntelItems[IntelKey]; worldAttackPoint = currentPosition + AttackHelpers.GetAttackPoint(target.GetVelocity(), target.GetPositionFromCanonicalTime(canonicalTime) + target.GetVelocity() * 0.08 - currentPosition, 98); } Vector3D dirToTarget = worldAttackPoint - currentPosition; if (dirToTarget.Length() < LocustCombatSystem.kEngageRange && deployTime == TimeSpan.Zero) { CombatSystem.Deploy(); deployTime = canonicalTime; } dirToTarget.Normalize(); LeadTask.Destination.Direction = dirToTarget; LeadTask.Destination.Position = worldAttackPoint + dirToTarget * 400; if (deployTime != TimeSpan.Zero) { if (deployTime + TimeSpan.FromSeconds(2) < canonicalTime) { AgentSubsystem.AddTask(TaskType.Dock, MyTuple.Create(IntelItemType.NONE, (long)0), CommandType.Enqueue, 0, canonicalTime); Status = TaskStatus.Aborted; return; } else { LeadTask.Destination.DirectionUp = Math.Sin(kRotateTheta) * controller.WorldMatrix.Right + Math.Cos(kRotateTheta) * controller.WorldMatrix.Up; } } LeadTask.Do(IntelItems, canonicalTime, profiler); }