bool Control(object[] Params) { if (!Session.InSpace || Config.Mode == Mode.None) { return(false); } // If we're warping and drones are in space, recall them and stop the module if (MyShip.ToEntity.Mode == EntityMode.Warping && Drone.AllInSpace.Any()) { Drone.AllInSpace.ReturnToDroneBay(); return(true); } if (MyShip.DronesToReconnect && MyShip.DroneBay.UsedCapacity < MyShip.DroneBay.MaxCapacity && MyShip.ToEntity.GroupID != Group.Capsule && TryReconnect) { MyShip.ReconnectToDrones(); DislodgeWaitFor(2); TryReconnect = false; return(false); } if (!Rats.TargetList.Any() && !Entity.All.Any(a => PriorityTargets.Contains(a.Name)) && !Config.StayDeployedWithNoTargets) { List <Drone> Recall = Drone.AllInSpace.Where(a => DroneReady(a) && a.State != EntityState.Departing).ToList(); // Recall drones if (Recall.Any()) { Console.Log("|oRecalling drones"); Console.Log(" |-gNo rats available"); Recall.ReturnToDroneBay(); Recall.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(5))); return(false); } } if (Config.Mode == Mode.AFKHeavy && (Rats.TargetList.Any() || Entity.All.Any(a => PriorityTargets.Contains(a.Name)))) { int AvailableSlots = ((MyShip.ToEntity.TypeID == 17918 /* Rattlesnake */) ? 2 : Me.MaxActiveDrones) - Drone.AllInSpace.Count(); List <Drone> Deploy = Drone.AllInBay.Where(a => Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group == "Heavy Attack Drones")).Take(AvailableSlots).ToList(); // Launch drones if (Deploy.Any()) { Console.Log("|oLaunching drones"); Deploy.Launch(); Deploy.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(5))); } return(false); } foreach (Drone d in Drone.AllInBay) { if (DroneHealthCache.ContainsKey(d)) { DroneHealthCache.Remove(d); } } foreach (Drone d in Drone.AllInSpace) { double health = d.ToEntity.ShieldPct + d.ToEntity.ArmorPct + d.ToEntity.HullPct; if (!DroneHealthCache.ContainsKey(d)) { DroneHealthCache.Add(d, health); } if (health < DroneHealthCache[d]) { DroneCooldown.Add(d); } } List <Drone> RecallDamaged = Drone.AllInSpace.Where(a => DroneCooldown.Contains(a) && DroneReady(a) && a.State != EntityState.Departing).ToList(); if (RecallDamaged.Any()) { Console.Log("|oRecalling damaged drones"); RecallDamaged.ReturnToDroneBay(); RecallDamaged.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(5))); return(false); } Entity WarpScrambling = SecurityCore.ValidScramble; Entity Neuting = SecurityCore.ValidNeuter; #region ActiveTarget selection Double MaxRange = (Config.Mode == Mode.PointDefense) ? 20000 : Me.DroneControlDistance; if (WarpScrambling != null) { if (ActiveTarget != WarpScrambling && WarpScrambling.Distance < MaxRange) { Console.Log("|rEntity on grid is/was warp scrambling!"); Console.Log("|oOveriding current drone target"); Console.Log(" |-g{0}", WarpScrambling.Name); ActiveTarget = WarpScrambling; return(false); } } else if (Neuting != null) { if (ActiveTarget != Neuting && Neuting.Distance < MaxRange) { Console.Log("|rEntity on grid is/was neuting!"); Console.Log("|oOveriding current drone target"); Console.Log(" |-g{0}", Neuting.Name); ActiveTarget = Neuting; return(false); } } if (ActiveTarget == null || !ActiveTarget.Exists || ActiveTarget.Exploded || ActiveTarget.Released) { ActiveTarget = null; ActiveTarget = Entity.All.FirstOrDefault(a => PriorityTargets.Contains(a.Name) && !a.Exploded && !a.Released && (a.LockedTarget || a.LockingTarget) && !Triggers.Contains(a.Name) && a.Distance < MaxRange); if (Rats.LockedAndLockingTargetList.Any() && ActiveTarget == null) { if (Config.PrivateTargets) { if (Config.SharedTargets) { ActiveTarget = Rats.LockedAndLockingTargetList.FirstOrDefault(a => IPC.ActiveTargets.ContainsValue(a.ID) && a.Distance < MaxRange); } else { ActiveTarget = Rats.LockedAndLockingTargetList.FirstOrDefault(a => !IPC.ActiveTargets.ContainsValue(a.ID) && a.Distance < MaxRange); } } if (ActiveTarget == null && OutOfTargets) { ActiveTarget = Rats.LockedAndLockingTargetList.FirstOrDefault(a => a.Distance < MaxRange); } if (ActiveTarget != null) { IPC.Relay(Me.CharID, ActiveTarget.ID); } } } #endregion #region LockManagement TargetCooldown = TargetCooldown.Where(a => a.Value >= DateTime.Now).ToDictionary(a => a.Key, a => a.Value); Rats.LockedAndLockingTargetList.ForEach(a => { TargetCooldown.AddOrUpdate(a, DateTime.Now.AddSeconds(2)); }); if (WarpScrambling != null) { if (!WarpScrambling.LockedTarget && !WarpScrambling.LockingTarget) { if (Rats.LockedAndLockingTargetList.Count >= Me.TrueMaxTargetLocks) { if (Rats.LockedTargetList.Any()) { Rats.LockedTargetList.First().UnlockTarget(); } return(false); } WarpScrambling.LockTarget(); return(false); } } else if (Neuting != null) { if (!Neuting.LockedTarget && !Neuting.LockingTarget) { if (Rats.LockedAndLockingTargetList.Count >= Me.TrueMaxTargetLocks) { if (Rats.LockedTargetList.Any()) { Rats.LockedTargetList.First().UnlockTarget(); } return(false); } Neuting.LockTarget(); return(false); } } else { Entity NewTarget = Entity.All.FirstOrDefault(a => !a.LockedTarget && !a.LockingTarget && PriorityTargets.Contains(a.Name) && a.Distance < MyShip.MaxTargetRange && !TargetCooldown.ContainsKey(a) && !Triggers.Contains(a.Name)); if (NewTarget == null) { NewTarget = Rats.UnlockedTargetList.FirstOrDefault(a => !TargetCooldown.ContainsKey(a) && a.Distance < MyShip.MaxTargetRange); } if (Rats.LockedAndLockingTargetList.Count < Config.TargetSlots && NewTarget != null && Entity.All.FirstOrDefault(a => a.IsJamming && a.IsTargetingMe) == null) { Console.Log("|oLocking"); Console.Log(" |-g{0}", NewTarget.Name); TargetCooldown.AddOrUpdate(NewTarget, DateTime.Now.AddSeconds(2)); NewTarget.LockTarget(); OutOfTargets = false; return(false); } } OutOfTargets = true; #endregion // Make sure ActiveTarget is locked. If so, make sure it's the active target, if not, return. if (ActiveTarget != null && ActiveTarget.Exists && ActiveTarget.LockedTarget) { if (!ActiveTarget.IsActiveTarget) { ActiveTarget.MakeActive(); return(false); } } else { if (ActiveTarget == null) { List <Drone> Recall = Drone.AllInSpace.Where(a => !DroneCooldown.Contains(a) && DroneReady(a) && a.State != EntityState.Departing).ToList(); // Recall drones if in point defense and no frig/destroyers in range if (Recall.Any() && !Config.StayDeployedWithNoTargets) { Console.Log("|oRecalling drones"); Recall.ReturnToDroneBay(); Recall.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(5))); } } return(false); } // Handle Attacking small targets - this should work for PointDefense AND Sentry if (ActiveTarget.Distance < 20000 && (Config.Mode == Mode.PointDefense || Config.Mode == Mode.Sentry)) { // Is the target a small target? if (SmallTarget(ActiveTarget)) { // Recall sentries List <Drone> Recall = Drone.AllInSpace.Where(a => !DroneCooldown.Contains(a) && DroneReady(a) && Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group != "Light Scout Drones") && a.State != EntityState.Departing).ToList(); if (Recall.Any()) { Console.Log("|oRecalling non scout drones"); Recall.ReturnToDroneBay(); Recall.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(5))); return(false); } // Send drones to attack List <Drone> Attack = Drone.AllInSpace.Where(a => !DroneCooldown.Contains(a) && DroneReady(a) && Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group == "Light Scout Drones") && (a.State != EntityState.Combat || a.Target == null || a.Target != ActiveTarget)).ToList(); if (Attack.Any()) { Console.Log("|oSending scout drones to attack"); Attack.Attack(); Attack.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(3))); return(false); } int AvailableSlots = ((MyShip.ToEntity.TypeID == 17918 /* Rattlesnake */) ? 2 : Me.MaxActiveDrones) - Drone.AllInSpace.Count(); List <Drone> Deploy = Drone.AllInBay.Where(a => !DroneCooldown.Contains(a) && Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group == "Light Scout Drones")).Take(AvailableSlots).ToList(); List <Drone> DeployIgnoreCooldown = Drone.AllInBay.Where(a => Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group == "Light Scout Drones")).Take(AvailableSlots).ToList(); // Launch drones if (Deploy.Any()) { Console.Log("|oLaunching scout drones"); Deploy.Launch(); Deploy.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(3))); return(false); } else if (AvailableSlots > 0 && DeployIgnoreCooldown.Any()) { DroneCooldown.Clear(); } } else if (Config.Mode == Mode.PointDefense) { List <Drone> Recall = Drone.AllInSpace.Where(a => !DroneCooldown.Contains(a) && DroneReady(a) && a.State != EntityState.Departing).ToList(); // Recall drones if in point defense and no frig/destroyers in range if (Recall.Any()) { Console.Log("|oRecalling drones"); Recall.ReturnToDroneBay(); Recall.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(5))); return(false); } } } // Handle Attacking anything if in AgressiveScout mode if (Config.Mode == Mode.AgressiveScout) { // Recall sentries List <Drone> Recall = Drone.AllInSpace.Where(a => !DroneCooldown.Contains(a) && DroneReady(a) && Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group != "Light Scout Drones") && a.State != EntityState.Departing).ToList(); if (Recall.Any()) { Console.Log("|oRecalling non scout drones"); Recall.ReturnToDroneBay(); Recall.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(5))); return(false); } // Send drones to attack List <Drone> Attack = Drone.AllInSpace.Where(a => !DroneCooldown.Contains(a) && DroneReady(a) && Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group == "Light Scout Drones") && (a.State != EntityState.Combat || a.Target == null || a.Target != ActiveTarget)).ToList(); if (Attack.Any()) { Console.Log("|oSending scout drones to attack"); Attack.Attack(); Attack.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(3))); return(false); } int AvailableSlots = Me.MaxActiveDrones - Drone.AllInSpace.Count(); List <Drone> Deploy = Drone.AllInBay.Where(a => !DroneCooldown.Contains(a) && Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group == "Light Scout Drones")).Take(AvailableSlots).ToList(); List <Drone> DeployIgnoreCooldown = Drone.AllInBay.Where(a => Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group == "Light Scout Drones")).Take(AvailableSlots).ToList(); // Launch drones if (Deploy.Any()) { Console.Log("|oLaunching scout drones"); Deploy.Launch(); Deploy.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(3))); return(false); } else if (AvailableSlots > 0 && DeployIgnoreCooldown.Any()) { DroneCooldown.Clear(); } } // Handle Attacking anything if in AgressiveMedium mode if (Config.Mode == Mode.AgressiveMedium) { // Recall sentries List <Drone> Recall = Drone.AllInSpace.Where(a => !DroneCooldown.Contains(a) && DroneReady(a) && Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group != "Medium Scout Drones") && a.State != EntityState.Departing).ToList(); if (Recall.Any()) { Console.Log("|oRecalling non medium drones"); Recall.ReturnToDroneBay(); Recall.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(5))); return(false); } // Send drones to attack List <Drone> Attack = Drone.AllInSpace.Where(a => !DroneCooldown.Contains(a) && DroneReady(a) && Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group == "Medium Scout Drones") && (a.State != EntityState.Combat || a.Target == null || a.Target != ActiveTarget)).ToList(); if (Attack.Any()) { Console.Log("|oSending medium drones to attack"); Attack.Attack(); Attack.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(3))); return(false); } int AvailableSlots = ((MyShip.ToEntity.TypeID == 17715 /* Gila */) ? 2 : Me.MaxActiveDrones) - Drone.AllInSpace.Count(); List <Drone> Deploy = Drone.AllInBay.Where(a => !DroneCooldown.Contains(a) && Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group == "Medium Scout Drones")).Take(AvailableSlots).ToList(); List <Drone> DeployIgnoreCooldown = Drone.AllInBay.Where(a => Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group == "Medium Scout Drones")).Take(AvailableSlots).ToList(); // Launch drones if (Deploy.Any()) { Console.Log("|oLaunching medium drones"); Deploy.Launch(); Deploy.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(3))); return(false); } else if (AvailableSlots > 0 && DeployIgnoreCooldown.Any()) { DroneCooldown.Clear(); } } // Handle Attacking anything if in AgressiveHeavy mode if (Config.Mode == Mode.AgressiveHeavy) { // Recall non heavy List <Drone> Recall = Drone.AllInSpace.Where(a => !DroneCooldown.Contains(a) && DroneReady(a) && Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group != "Heavy Attack Drones") && a.State != EntityState.Departing).ToList(); if (Recall.Any()) { Console.Log("|oRecalling non heavy drones"); Recall.ReturnToDroneBay(); Recall.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(5))); return(false); } // Send drones to attack List <Drone> Attack = Drone.AllInSpace.Where(a => !DroneCooldown.Contains(a) && DroneReady(a) && Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group == "Heavy Attack Drones") && (a.State != EntityState.Combat || a.Target == null || a.Target != ActiveTarget)).ToList(); if (Attack.Any()) { Console.Log("|oSending heavy drones to attack"); Attack.Attack(); Attack.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(3))); return(false); } int AvailableSlots = ((MyShip.ToEntity.TypeID == 17918 /* Rattlesnake */) ? 2 : Me.MaxActiveDrones) - Drone.AllInSpace.Count(); List <Drone> Deploy = Drone.AllInBay.Where(a => !DroneCooldown.Contains(a) && Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group == "Heavy Attack Drones")).Take(AvailableSlots).ToList(); List <Drone> DeployIgnoreCooldown = Drone.AllInBay.Where(a => Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group == "Heavy Attack Drones")).Take(AvailableSlots).ToList(); // Launch drones if (Deploy.Any()) { Console.Log("|oLaunching heavy drones"); Deploy.Launch(); Deploy.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(3))); return(false); } else if (AvailableSlots > 0 && DeployIgnoreCooldown.Any()) { DroneCooldown.Clear(); } } // Handle Attacking anything if in AgressiveSentry mode if (Config.Mode == Mode.AgressiveSentry) { // Recall non heavy List <Drone> Recall = Drone.AllInSpace.Where(a => !DroneCooldown.Contains(a) && DroneReady(a) && Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group != "Sentry Drones") && a.State != EntityState.Departing).ToList(); if (Recall.Any()) { Console.Log("|oRecalling non sentry drones"); Recall.ReturnToDroneBay(); Recall.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(5))); return(false); } // Send drones to attack List <Drone> Attack = Drone.AllInSpace.Where(a => !DroneCooldown.Contains(a) && DroneReady(a) && Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group == "Sentry Drones") && (a.State != EntityState.Combat || a.Target == null || a.Target != ActiveTarget)).ToList(); if (Attack.Any()) { Console.Log("|oSending sentry drones to attack"); Attack.Attack(); Attack.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(3))); return(false); } int AvailableSlots = ((MyShip.ToEntity.TypeID == 17918 /* Rattlesnake */) ? 2 : Me.MaxActiveDrones) - Drone.AllInSpace.Count(); List <Drone> Deploy = Drone.AllInBay.Where(a => !DroneCooldown.Contains(a) && Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group == "Sentry Drones")).Take(AvailableSlots).ToList(); List <Drone> DeployIgnoreCooldown = Drone.AllInBay.Where(a => Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group == "Sentry Drones")).Take(AvailableSlots).ToList(); // Launch drones if (Deploy.Any()) { Console.Log("|oLaunching sentry drones"); Deploy.Launch(); Deploy.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(3))); return(false); } else if (AvailableSlots > 0 && DeployIgnoreCooldown.Any()) { DroneCooldown.Clear(); } } // Handle managing sentries if (ActiveTarget.Distance < MaxRange && Config.Mode == Mode.Sentry) { // Is the target a small target? if (!SmallTarget(ActiveTarget) || ActiveTarget.Distance > 20000) { List <Drone> Recall = Drone.AllInSpace.Where(a => !DroneCooldown.Contains(a) && DroneReady(a) && Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group != "Sentry Drones") && a.State != EntityState.Departing).ToList(); // Recall non sentries if (Recall.Any()) { Console.Log("|oRecalling drones"); Recall.ReturnToDroneBay(); Recall.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(5))); return(false); } List <Drone> Attack = Drone.AllInSpace.Where(a => !DroneCooldown.Contains(a) && DroneReady(a) && Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group == "Sentry Drones") && (a.State != EntityState.Combat || a.Target == null || a.Target != ActiveTarget)).ToList(); // Send drones to attack if (Attack.Any()) { Console.Log("|oOrdering sentry drones to attack"); Attack.Attack(); Attack.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(3))); return(false); } int AvailableSlots = ((MyShip.ToEntity.TypeID == 17918) ? 2 : Me.MaxActiveDrones) - Drone.AllInSpace.Count(); List <Drone> Deploy = Drone.AllInBay.Where(a => !DroneCooldown.Contains(a) && Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group == "Sentry Drones")).Take(AvailableSlots).ToList(); List <Drone> DeployIgnoreCooldown = Drone.AllInBay.Where(a => Data.DroneType.All.Any(b => b.ID == a.TypeID && b.Group == "Sentry Drones")).Take(AvailableSlots).ToList(); // Launch drones if (Deploy.Any()) { Console.Log("|oLaunching sentry drones"); Deploy.Launch(); Deploy.ForEach(a => NextDroneCommand.AddOrUpdate(a, DateTime.Now.AddSeconds(3))); return(false); } else if (AvailableSlots > 0 && DeployIgnoreCooldown.Any()) { DroneCooldown.Clear(); } } } return(false); }