private void KillOnceAction(Actions.Action action)
        {
            if (Cache.Instance.NormalApproach)
                Cache.Instance.NormalApproach = false;

            bool notTheClosest;
            if (!bool.TryParse(action.GetParameterValue("notclosest"), out notTheClosest))
                notTheClosest = false;

            int numberToIgnore;
            if (!int.TryParse(action.GetParameterValue("numbertoignore"), out numberToIgnore))
                numberToIgnore = 0;

            List<string> targetNames = action.GetParameterValues("target");
            // No parameter? Ignore kill action
            if (targetNames.Count == 0)
            {
                Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "No targets defined in kill action!", Logging.Orange);
                Nextaction();
                return;
            }

            IEnumerable<EntityCache> targets = Cache.Instance.Entities.Where(e => targetNames.Contains(e.Name)).ToList();
            if (targets.Count() == numberToIgnore)
            {
                Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "All targets killed " + targetNames.Aggregate((current, next) => current + "[" + next + "]"), Logging.Teal);

                // We killed it/them !?!?!? :)
                Nextaction();
                return;
            }

            EntityCache target = targets.OrderBy(t => t.Distance).First();

            if (target != null)
            {
                // Reset timeout
                _clearPocketTimeout = null;

                // Are we approaching the active (out of range) target?
                // Wait for it (or others) to get into range

                // Lock priority target if within weapons range

                if (notTheClosest)
                    target = targets.OrderByDescending(t => t.Distance).First();

                if (target.Distance < Cache.Instance.MaxRange)
                {
                    //panic handles adding any priority targets and combat will prefer to kill any priority targets
                    if (Cache.Instance.PriorityTargets.All(pt => pt.Id != target.Id))
                    {
                        //Adds the target we want to kill to the priority list so that combat.cs will kill it (especially if it is an LCO this is important)
                        Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "Adding [" + target.Name + "][ID: " + target.Id + "] as a priority target", Logging.Teal);
                        Cache.Instance.AddPriorityTargets(new[] { target }, Priority.PriorityKillTarget);
                    }
                    if (Cache.Instance.DirectEve.ActiveShip.MaxLockedTargets > 0)
                    {
                        if (!(target.IsTarget || target.IsTargeting)) //This target is not targeted and need to target it
                        {
                            Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "Targeting [" + target.Name + "][ID: " + target.Id + "][" + Math.Round(target.Distance / 1000, 0) + "k away]", Logging.Teal);
                            target.LockTarget();
                            // the target has been added to the priority targets list and has been targeted.
                            // this should ensure that the combat module (and/or the next action) kills the target.
                            Nextaction();
                            return;
                        }
                    }
                }
                NavigateOnGrid.NavigateIntoRange(target, "CombatMissionCtrl." + _pocketActions[_currentAction]);
                return;
            }
        }
        private void LootItemAction(Actions.Action action)
        {
            Cache.Instance.MissionLoot = true;
            List<string> items = action.GetParameterValues("item");
            List<string> targetNames = action.GetParameterValues("target");
            // if we are not generally looting we need to re-enable the opening of wrecks to
            // find this LootItems we are looking for
            Cache.Instance.OpenWrecks = true;

            int quantity;
            if (!int.TryParse(action.GetParameterValue("quantity"), out quantity))
                quantity = 1;

            bool done = items.Count == 0;
            if (!done)
            {
                DirectContainer cargo = Cache.Instance.DirectEve.GetShipsCargo();
                // We assume that the ship's cargo will be opened somewhere else
                if (cargo.Window.IsReady)
                    done |= cargo.Items.Any(i => (items.Contains(i.TypeName) && (i.Quantity >= quantity)));
            }
            if (done)
            {
                Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "We are done looting", Logging.Teal);
                // now that we have completed this action revert OpenWrecks to false
                Cache.Instance.OpenWrecks = false;
                Cache.Instance.MissionLoot = false;
                _currentAction++;
                return;
            }

            IOrderedEnumerable<EntityCache> containers = Cache.Instance.Containers.Where(e => !Cache.Instance.LootedContainers.Contains(e.Id)).OrderBy(e => e.Distance);
            //IOrderedEnumerable<EntityCache> containers = Cache.Instance.Containers.Where(e => !Cache.Instance.LootedContainers.Contains(e.Id)).OrderBy(e => e.Id);
            //IOrderedEnumerable<EntityCache> containers = Cache.Instance.Containers.Where(e => !Cache.Instance.LootedContainers.Contains(e.Id)).OrderByDescending(e => e.Id);
            if (!containers.Any())
            {
                Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "We are done looting", Logging.Teal);

                _currentAction++;
                return;
            }

            EntityCache container = containers.FirstOrDefault(c => targetNames.Contains(c.Name)) ?? containers.FirstOrDefault();
            if (container != null && (container.Distance > (int)Distance.SafeScoopRange && (Cache.Instance.Approaching == null || Cache.Instance.Approaching.Id != container.Id)))
            {
                if (DateTime.Now > Cache.Instance.NextApproachAction && (Cache.Instance.Approaching == null || Cache.Instance.Approaching.Id != container.Id))
                {
                    Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "Approaching target [" + container.Name + "][ID: " + container.Id + "] which is at [" + Math.Round(container.Distance / 1000, 0) + "k away]", Logging.Teal);
                    container.Approach();
                }
            }
        }
        private void DropItemAction(Actions.Action action)
        {
            try
            {
                Cache.Instance.DropMode = true;
                List<string> items = action.GetParameterValues("item");
                string targetName = action.GetParameterValue("target");

                int quantity;
                if (!int.TryParse(action.GetParameterValue("quantity"), out quantity))
                {
                    quantity = 1;
                }

                if (!CargoHoldHasBeenStacked)
                {
                    Logging.Log("MissionController.DropItem", "Stack CargoHold", Logging.Orange);
                    if (!Cache.Instance.StackCargoHold("DropItem")) return;
                    CargoHoldHasBeenStacked = true;
                    return;
                }

                IEnumerable<EntityCache> targetEntities = Cache.Instance.EntitiesByName(targetName, Cache.Instance.EntitiesOnGrid.ToList());
                if (targetEntities.Any())
                {
                    Logging.Log("MissionController.DropItem", "We have [" + targetEntities.Count() + "] entities on grid that match our target by name: [" + targetName.FirstOrDefault() + "]", Logging.Orange);
                    targetEntities = targetEntities.Where(i => i.IsContainer || i.GroupId == (int)Group.LargeColidableObject); //some missions (like: Onslaught - lvl1) have LCOs that can hold and take cargo, note that same mission has a LCS with the same name!

                    if (!targetEntities.Any())
                    {
                        Logging.Log("MissionController.DropItem", "No entity on grid named: [" + targetEntities.FirstOrDefault() + "] that is also a container", Logging.Orange);

                        // now that we have completed this action revert OpenWrecks to false
                        Cache.Instance.DropMode = false;
                        Nextaction();
                        return;
                    }

                    EntityCache closest = targetEntities.OrderBy(t => t.Distance).FirstOrDefault();

                    if (closest == null)
                    {
                        Logging.Log("MissionController.DropItem", "closest: target named [" + targetName.FirstOrDefault() + "] was null" + targetEntities, Logging.Orange);

                        // now that we have completed this action revert OpenWrecks to false
                        Cache.Instance.DropMode = false;
                        Nextaction();
                        return;
                    }

                    if (closest.Distance > (int)Distances.SafeScoopRange)
                    {
                        if (Cache.Instance.Approaching == null || Cache.Instance.Approaching.Id != closest.Id)
                        {
                            if (DateTime.UtcNow > Cache.Instance.NextApproachAction)
                            {
                                Logging.Log("MissionController.DropItem", "Approaching target [" + closest.Name + "][" + Cache.Instance.MaskedID(closest.Id) + "] which is at [" + Math.Round(closest.Distance / 1000, 0) + "k away]", Logging.White);
                                closest.Approach(1000);
                            }
                        }
                    }
                    else if (Cache.Instance.MyShipEntity.Velocity < 50) //nearly stopped
                    {
                        if (DateTime.UtcNow > Cache.Instance.NextOpenContainerInSpaceAction)
                        {
                            Cache.Instance.NextOpenContainerInSpaceAction = DateTime.UtcNow.AddSeconds(Cache.Instance.RandomNumber(6, 10));

                            DirectContainer container = null;

                            container = Cache.Instance.DirectEve.GetContainer(closest.Id);

                            if (container == null)
                            {
                                Logging.Log("MissionController.DropItem", "if (container == null)", Logging.White);
                                return;
                            }

                            if (ItemsHaveBeenMoved)
                            {
                                Logging.Log("MissionController.DropItem", "We have Dropped the items: ItemsHaveBeenMoved [" + ItemsHaveBeenMoved + "]", Logging.White);
                                // now that we have completed this action revert OpenWrecks to false
                                Cache.Instance.DropMode = false;
                                Nextaction();
                                return;
                            }

                            if (Cache.Instance.CurrentShipsCargo.Items.Any())
                            {
                                int CurrentShipsCargoItemCount = 0;
                                CurrentShipsCargoItemCount = Cache.Instance.CurrentShipsCargo.Items.Count();

                                //DirectItem itemsToMove = null;
                                //itemsToMove = Cache.Instance.CurrentShipsCargo.Items.FirstOrDefault(i => i.TypeName.ToLower() == items.FirstOrDefault().ToLower());
                                //if (itemsToMove == null)
                                //{
                                //    Logging.Log("MissionController.DropItem", "CurrentShipsCargo has [" + CurrentShipsCargoItemCount + "] items. Item We are supposed to move is: [" + items.FirstOrDefault() + "]", Logging.White);
                                //    return;
                                //}

                                int ItemNumber = 0;
                                foreach (DirectItem CurrentShipsCargoItem in Cache.Instance.CurrentShipsCargo.Items)
                                {
                                    ItemNumber++;
                                    Logging.Log("MissionController.DropItem", "[" + ItemNumber + "] Found [" + CurrentShipsCargoItem.Quantity + "][" + CurrentShipsCargoItem.TypeName + "] in Current Ships Cargo: StackSize: [" + CurrentShipsCargoItem.Stacksize + "] We are looking for: [" + items.FirstOrDefault() + "]", Logging.Debug);
                                    if (CurrentShipsCargoItem.TypeName.ToLower() == items.FirstOrDefault().ToLower())
                                    {
                                        Logging.Log("MissionController.DropItem", "[" + ItemNumber + "] container.Capacity [" + container.Capacity + "] ItemsHaveBeenMoved [" + ItemsHaveBeenMoved + "]", Logging.Debug);
                                        if (!ItemsHaveBeenMoved)
                                        {
                                            Logging.Log("MissionController.DropItem", "Moving Items: " + items.FirstOrDefault() + " from cargo ship to " + container.TypeName, Logging.White);
                                            //
                                            // THIS IS NOT WORKING - EXCEPTION/ERROR IN CLIENT...
                                            //
                                            //container.Add(CurrentShipsCargoItem, quantity);
                                            Cache.Instance.NextOpenContainerInSpaceAction = DateTime.UtcNow.AddSeconds(Cache.Instance.RandomNumber(4, 6));
                                            ItemsHaveBeenMoved = true;
                                            return;
                                        }

                                        return;
                                    }
                                }
                            }
                            else
                            {
                                Logging.Log("MissionController.DropItem", "No Items: Cache.Instance.CurrentShipsCargo.Items.Any()", Logging.Debug);
                            }
                        }
                    }

                    return;
                }

                Logging.Log("MissionController.DropItem", "No entity on grid named: [" + targetEntities.FirstOrDefault() + "]", Logging.Orange);
                // now that we have completed this action revert OpenWrecks to false
                Cache.Instance.DropMode = false;
                Nextaction();
                return;
            }
            catch (Exception exception)
            {
                Logging.Log("DropItemAction", "Exception: [" + exception + "]", Logging.Debug);
            }

            return;
        }
        private void KillClosestByNameAction(Actions.Action action)
        {
            bool notTheClosest;
            if (!bool.TryParse(action.GetParameterValue("notclosest"), out notTheClosest))
                notTheClosest = false;

            if (Cache.Instance.NormalApproach)
                Cache.Instance.NormalApproach = false;

            List<string> targetNames = action.GetParameterValues("target");
            // No parameter? Ignore kill action
            if (targetNames.Count == 0)
            {
                Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "No targets defined!", Logging.Teal);
                Nextaction();
                return;
            }

            //IEnumerable<EntityCache> targets = Cache.Instance.Entities.Where(e => targetNames.Contains(e.Name));
            EntityCache target = Cache.Instance.Entities.Where(e => targetNames.Contains(e.Name)).OrderBy(t => t.Distance).First();
            if (notTheClosest)
                target = Cache.Instance.Entities.Where(e => targetNames.Contains(e.Name)).OrderByDescending(t => t.Distance).First();

            if (target != null)
            {
                if (target.Distance < Cache.Instance.MaxRange)
                {
                    if (Cache.Instance.PriorityTargets.All(pt => pt.Id != target.Id))
                    {
                        Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "Adding [" + target.Name + "][ID: " + target.Id + "] as a priority target", Logging.Teal);
                        Cache.Instance.AddPriorityTargets(new[] { target }, Priority.PriorityKillTarget);
                    }

                    if (Cache.Instance.DirectEve.ActiveShip.MaxLockedTargets > 0)
                    {
                        if (!(target.IsTarget || target.IsTargeting))
                        //This target is not targeted and need to target it
                        {
                            Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "Targeting [" + target.Name + "][ID: " + target.Id + "][" + Math.Round(target.Distance / 1000, 0) + "k away]", Logging.Teal);
                            target.LockTarget();
                            // the target has been added to the priority targets list and has been targeted.
                            // this should ensure that the combat module (and/or the next action) kills the target.
                            Nextaction();
                            return;
                        }
                    }
                }
                NavigateOnGrid.NavigateIntoRange(target, "CombatMissionCtrl." + _pocketActions[_currentAction]);
            }
            else
            {
                Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "All targets killed, not valid anymore ", Logging.Teal);

                // We killed it/them !?!?!? :)
                Nextaction();
                return;
            }
        }
        private void KillOnceAction(Actions.Action action)
        {
            if (Cache.Instance.NormalApproach) Cache.Instance.NormalApproach = false;

            bool notTheClosest;
            if (!bool.TryParse(action.GetParameterValue("notclosest"), out notTheClosest))
            {
                notTheClosest = false;
            }

            int numberToIgnore;
            if (!int.TryParse(action.GetParameterValue("numbertoignore"), out numberToIgnore))
            {
                numberToIgnore = 0;
            }

            List<string> targetNames = action.GetParameterValues("target");

            // No parameter? Ignore kill action
            if (targetNames.Count == 0)
            {
                Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "No targets defined in kill action!", Logging.Orange);
                Nextaction();
                return;
            }

            IEnumerable<EntityCache> targets = Cache.Instance.Entities.Where(e => targetNames.Contains(e.Name)).ToList();
            if (targets.Count() == numberToIgnore)
            {
                Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "All targets killed " + targetNames.Aggregate((current, next) => current + "[" + next + "]"), Logging.Teal);

                // We killed it/them !?!?!? :)
                Nextaction();
                return;
            }

            EntityCache target = targets.OrderBy(t => t.Distance).FirstOrDefault();

            if (notTheClosest) target = targets.OrderByDescending(t => t.Distance).FirstOrDefault();

            if (target != null)
            {
                // Reset timeout
                _clearPocketTimeout = null;

                // Are we approaching the active (out of range) target?
                // Wait for it (or others) to get into range

                // Lock priority target if within weapons range

                if (target.Distance < Cache.Instance.MaxRange)
                {
                    //Adds the target we want to kill to the priority list so that combat.cs will kill it (especially if it is an LCO this is important)
                    Cache.Instance.AddPrimaryWeaponPriorityTargets(new[] { target }, PrimaryWeaponPriority.PriorityKillTarget, "CombatMissionCtrl." + _pocketActions[_currentAction]);

                    if (target.IsFrigate || Settings.Instance.DronesKillHighValueTargets || Cache.Instance.EntitiesNotSelf.All(i => !i.IsNPCFrigate))
                    {
                        Cache.Instance.AddDronePriorityTargets(new[] { target }, DronePriority.LowPriorityTarget, "CombatMissionCtrl." + _pocketActions[_currentAction]);
                    }
                }

                NavigateOnGrid.NavigateIntoRange(target, "CombatMissionCtrl." + _pocketActions[_currentAction]);
                return;
            }

            return;
        }
        private void AddWebifierByNameAction(Actions.Action action)
        {
            bool notTheClosest;
            if (!bool.TryParse(action.GetParameterValue("notclosest"), out notTheClosest))
            {
                notTheClosest = false;
            }

            int numberToIgnore;
            if (!int.TryParse(action.GetParameterValue("numbertoignore"), out numberToIgnore))
            {
                numberToIgnore = 0;
            }

            List<string> targetNames = action.GetParameterValues("target");

            // No parameter? Ignore kill action
            if (!targetNames.Any())
            {
                Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "No targets defined in AddWebifierByName action!", Logging.Teal);
                Nextaction();
                return;
            }

            Cache.Instance.AddWebifierByName(targetNames.FirstOrDefault(), numberToIgnore, notTheClosest);

            //
            // this action is passive and only adds things to the WarpScramblers list )before they have a chance to scramble you, so you can target them early
            //
            Nextaction();
            return;
        }
        private void KillClosestByNameAction(Actions.Action action)
        {
            bool notTheClosest;
            if (!bool.TryParse(action.GetParameterValue("notclosest"), out notTheClosest))
            {
                notTheClosest = false;
            }

            if (Cache.Instance.NormalApproach) Cache.Instance.NormalApproach = false;

            List<string> targetNames = action.GetParameterValues("target");

            // No parameter? Ignore kill action
            if (targetNames.Count == 0)
            {
                Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "No targets defined!", Logging.Teal);
                Nextaction();
                return;
            }

            //
            // the way this is currently written is will NOT stop after killing the first target as intended, it will clear all targets with the Name given
            //

            Cache.Instance.AddPrimaryWeaponPriorityTarget(Cache.Instance.PotentialCombatTargets.Where(t => targetNames.Contains(t.Name)).OrderBy(t => t.Distance).Take(1).FirstOrDefault(),PrimaryWeaponPriority.PriorityKillTarget, "CombatMissionCtrl.KillClosestByName");

            //if (Settings.Instance.TargetSelectionMethod == "isdp")
            //{
                if (Cache.Instance.GetBestPrimaryWeaponTarget((double)Distances.OnGridWithMe, false, "combat", Cache.Instance.PotentialCombatTargets.OrderBy(t => t.Distance).Take(1).ToList()))
                    _clearPocketTimeout = null;
            //}
            //else //use new target selection method
            //{
            //    if (Cache.Instance.__GetBestWeaponTargets((double)Distances.OnGridWithMe, Cache.Instance.PotentialCombatTargets.Where(e => !e.IsSentry || (e.IsSentry && Settings.Instance.KillSentries)).OrderBy(t => t.Distance).Take(1).ToList()).Any())
            //        _clearPocketTimeout = null;
            //}

            // Do we have a timeout?  No, set it to now + 5 seconds
            if (!_clearPocketTimeout.HasValue) _clearPocketTimeout = DateTime.UtcNow.AddSeconds(5);

            // Are we in timeout?
            if (DateTime.UtcNow < _clearPocketTimeout.Value) return;

            // We have cleared the Pocket, perform the next action \o/ - reset the timers that we had set for actions...
            Nextaction();

            // Reset timeout
            _clearPocketTimeout = null;
            return;
        }
        private void IgnoreAction(Actions.Action action)
        {
            bool clear;
            if (!bool.TryParse(action.GetParameterValue("clear"), out clear))
                clear = false;

            //List<string> removehighestbty = action.GetParameterValues("RemoveHighestBty");
            //List<string> addhighestbty = action.GetParameterValues("AddHighestBty");

            List<string> add = action.GetParameterValues("add");
            List<string> remove = action.GetParameterValues("remove");

            //string targetNames = action.GetParameterValue("target");

            //int distancetoapp;
            //if (!int.TryParse(action.GetParameterValue("distance"), out distancetoapp))
            //    distancetoapp = 1000;

            //IEnumerable<EntityCache> targets = Cache.Instance.Entities.Where(e => targetNames.Contains(e.Name));
            // EntityCache target = targets.OrderBy(t => t.Distance).First();

            //IEnumerable<EntityCache> targetsinrange = Cache.Instance.Entities.Where(b => Cache.Instance.DistanceFromEntity(b.X ?? 0, b.Y ?? 0, b.Z ?? 0,target) < distancetoapp);
            //IEnumerable<EntityCache> targetsoutofrange = Cache.Instance.Entities.Where(b => Cache.Instance.DistanceFromEntity(b.X ?? 0, b.Y ?? 0, b.Z ?? 0, target) < distancetoapp);

            if (clear)
                Cache.Instance.IgnoreTargets.Clear();
            else
            {
                add.ForEach(a => Cache.Instance.IgnoreTargets.Add(a.Trim()));
                remove.ForEach(a => Cache.Instance.IgnoreTargets.Remove(a.Trim()));
            }
            Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "Updated ignore list", Logging.Teal);
            if (Cache.Instance.IgnoreTargets.Any())
                Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "Currently ignoring: " + Cache.Instance.IgnoreTargets.Aggregate((current, next) => current + "[" + next + "]"), Logging.Teal);
            else
                Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "Your ignore list is empty", Logging.Teal);
            _currentAction++;
        }
        private void SalvageAction(Actions.Action action)
        {
            List<string> itemsToLoot = null;
            if (action.GetParameterValues("item") != null)
            {
                itemsToLoot = action.GetParameterValues("item");
            }

            int quantity;
            if (!int.TryParse(action.GetParameterValue("quantity"), out quantity))
            {
                quantity = 1;
            }

            if (QuestorCache.Instance.NormalApproach) QuestorCache.Instance.NormalApproach = false;

            List<string> targetNames = action.GetParameterValues("target");

            // No parameter? Ignore salvage action
            if (targetNames.Count == 0)
            {
                Logging.Log("CombatMissionCtrl[" + PocketNumber + "]." + _pocketActions[_currentAction], "No targets defined!", Logging.Teal);
                Nextaction();
                return;
            }

            if (itemsToLoot == null)
            {
                Logging.Log("CombatMissionCtrl[" + PocketNumber + "]." + _pocketActions[_currentAction], " *** No Item Was Specified In the Salvage Action! ***", Logging.Debug);
                Nextaction();
            }
            else if (QuestorCache.Instance.CurrentShipsCargo != null && QuestorCache.Instance.CurrentShipsCargo.IsPrimed)
            {
                if (QuestorCache.Instance.CurrentShipsCargo.Items.Any(i => (itemsToLoot.Contains(i.Type) && (i.Quantity >= quantity))))
                {
                    Logging.Log("CombatMissionCtrl[" + PocketNumber + "]." + _pocketActions[_currentAction], "We are done - we have the item(s)", Logging.Teal);

                    // now that we have completed this action revert OpenWrecks to false
                    if (NavigateOnGrid.SpeedTank) Salvage.OpenWrecks = false;
                    Salvage.MissionLoot = false;
                    Salvage.CurrentlyShouldBeSalvaging = false;
                    Nextaction();
                    return;
                }
            }

            IEnumerable<EntityCache> targets = QuestorCache.Instance.EntitiesByName(targetNames.FirstOrDefault(), QuestorCache.Instance.EntitiesOnGrid.ToList()).ToList();
            if (!targets.Any())
            {
                Logging.Log("CombatMissionCtrl[" + PocketNumber + "]." + _pocketActions[_currentAction], "no entities found named [" + targets.FirstOrDefault() + "] proceeding to next action", Logging.Teal);
                Nextaction();
                return;
            }

            if (Combat.GetBestPrimaryWeaponTarget((double)Distances.OnGridWithMe, false, "combat", Combat.PotentialCombatTargets.OrderBy(t => t.Distance).Take(1).ToList()))
                _clearPocketTimeout = null;

            // Do we have a timeout?  No, set it to now + 5 seconds
            if (!_clearPocketTimeout.HasValue) _clearPocketTimeout = DateTime.UtcNow.AddSeconds(5);

            //
            // how do we determine success here? we assume the 'reward' for salvaging will appear in your cargo, we also assume the mission action will know what that item is called!
            //

            EntityCache closest = targets.OrderBy(t => t.Distance).FirstOrDefault();
            if (closest != null)
            {
                if (!NavigateOnGrid.NavigateToTarget(targets.FirstOrDefault(), "", true, 500)) return;

                if (Salvage.Salvagers == null || !Salvage.Salvagers.Any())
                {
                    Logging.Log("CombatMissionCtrl[" + PocketNumber + "]." + _pocketActions[_currentAction], "this action REQUIRES at least 1 salvager! - you may need to use Mission specific fittings to accomplish this", Logging.Teal);
                    Logging.Log("CombatMissionCtrl[" + PocketNumber + "]." + _pocketActions[_currentAction], "this action REQUIRES at least 1 salvager! - disabling autostart", Logging.Teal);
                    Logging.Log("CombatMissionCtrl[" + PocketNumber + "]." + _pocketActions[_currentAction], "this action REQUIRES at least 1 salvager! - setting CombatMissionsBehaviorState to GotoBase", Logging.Teal);
                    _States.CurrentCombatMissionBehaviorState = CombatMissionsBehaviorState.GotoBase;
                    QuestorSettings.Instance.AutoStart = false;
                }
                else if (closest.Distance < Salvage.Salvagers.Min(s => s.OptimalRange))
                {
                    if (NavigateOnGrid.SpeedTank) Salvage.OpenWrecks = true;
                    Salvage.CurrentlyShouldBeSalvaging = true;
                    Salvage.TargetWrecks(targets);
                    Salvage.ActivateSalvagers(targets);
                }

                return;
            }

            // Are we in timeout?
            if (DateTime.UtcNow < _clearPocketTimeout.Value) return;

            // We have cleared the Pocket, perform the next action \o/ - reset the timers that we had set for actions...
            Nextaction();

            // Reset timeout
            _clearPocketTimeout = null;
            return;
        }
        private void KillAction(Actions.Action action)
        {
            if (Cache.Instance.NormalApproach) Cache.Instance.NormalApproach = false;

            bool ignoreAttackers;
            if (!bool.TryParse(action.GetParameterValue("ignoreattackers"), out ignoreAttackers))
            {
                ignoreAttackers = false;
            }

            bool breakOnAttackers;
            if (!bool.TryParse(action.GetParameterValue("breakonattackers"), out breakOnAttackers))
            {
                breakOnAttackers = false;
            }

            bool notTheClosest;
            if (!bool.TryParse(action.GetParameterValue("notclosest"), out notTheClosest))
            {
                notTheClosest = false;
            }

            int numberToIgnore;
            if (!int.TryParse(action.GetParameterValue("numbertoignore"), out numberToIgnore))
            {
                numberToIgnore = 0;
            }

            List<string> targetNames = action.GetParameterValues("target");

            // No parameter? Ignore kill action
            if (!targetNames.Any())
            {
                Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "No targets defined in kill action!", Logging.Teal);
                Nextaction();
                return;
            }

            if (Settings.Instance.DebugKillAction)
            {
                int targetNameCount = 0;
                foreach (string targetName in targetNames)
                {
                    targetNameCount++;
                    Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "targetNames [" + targetNameCount + "][" + targetName + "]", Logging.Debug);
                }
            }

            List<EntityCache> killTargets = Cache.Instance.EntitiesOnGrid.Where(e => targetNames.Contains(e.Name)).OrderBy(t => t.Nearest5kDistance).ToList();

            if (notTheClosest) killTargets = Cache.Instance.EntitiesOnGrid.Where(e => targetNames.Contains(e.Name)).OrderByDescending(t => t.Nearest5kDistance).ToList();

            if (!killTargets.Any() || killTargets.Count() <= numberToIgnore)
            {
                Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "All targets killed " + targetNames.Aggregate((current, next) => current + "[" + next + "] NumToIgnore [" + numberToIgnore + "]"), Logging.Teal);

                // We killed it/them !?!?!? :)
                Cache.Instance.IgnoreTargets.RemoveWhere(targetNames.Contains);
                if (ignoreAttackers)
                {
                    //
                    // UNIgnore attackers when kill is done.
                    //
                    foreach (EntityCache target in Cache.Instance.PotentialCombatTargets.Where(e => !targetNames.Contains(e.Name)))
                    {
                        if (target.IsTargetedBy && target.IsAttacking)
                        {
                            Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "UN-Ignoring [" + target.Name + "][" + Cache.Instance.MaskedID(target.Id) + "][" + Math.Round(target.Distance / 1000, 0) + "k away] due to ignoreAttackers parameter (and kill action being complete)", Logging.Teal);
                            Cache.Instance.IgnoreTargets.Remove(target.Name.Trim());
                        }
                    }
                }
                Nextaction();
                return;
            }

            if (ignoreAttackers)
            {
                foreach (EntityCache target in Cache.Instance.PotentialCombatTargets.Where(e => !targetNames.Contains(e.Name)))
                {
                    if (target.IsTargetedBy && target.IsAttacking)
                    {
                        Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "Ignoring [" + target.Name + "][" + Cache.Instance.MaskedID(target.Id) + "][" + Math.Round(target.Distance / 1000, 0) + "k away] due to ignoreAttackers parameter", Logging.Teal);
                        Cache.Instance.IgnoreTargets.Add(target.Name.Trim());
                    }
                }
            }

            if (breakOnAttackers && Cache.Instance.TargetedBy.Count(t => (!t.IsSentry || (t.IsSentry && Settings.Instance.KillSentries) || (t.IsSentry && t.IsEwarTarget)) && !t.IsIgnored) > killTargets.Count(e => e.IsTargetedBy))
            {
                //
                // We are being attacked, break the kill order
                // which involves removing the named targets as PrimaryWeaponPriorityTargets, PreferredPrimaryWeaponTarget, DronePriorityTargets, and PreferredDroneTarget
                //
                if (Cache.Instance.RemovePrimaryWeaponPriorityTargets(killTargets)) Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "Breaking off kill order, new spawn has arrived!", Logging.Teal);
                targetNames.ForEach(t => Cache.Instance.IgnoreTargets.Add(t));

                if (killTargets.Any())
                {
                    Cache.Instance.RemovePrimaryWeaponPriorityTargets(killTargets.Where(i => i.Name == Cache.Instance.PreferredPrimaryWeaponTarget.Name));
                    Cache.Instance.RemoveDronePriorityTargets(killTargets.Where(i => i.Name == Cache.Instance.PreferredPrimaryWeaponTarget.Name));

                    if (Cache.Instance.PreferredPrimaryWeaponTargetID != null)
                    {
                        foreach (EntityCache killTarget in killTargets.Where(e => e.Id == Cache.Instance.PreferredPrimaryWeaponTargetID))
                        {
                            if (Cache.Instance.PreferredPrimaryWeaponTargetID == null) continue;
                            Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "Breaking Kill Order in: [" + killTarget.Name + "][" + Math.Round(killTarget.Distance/1000,0) + "k][" + Cache.Instance.MaskedID((long)Cache.Instance.PreferredPrimaryWeaponTargetID) + "]", Logging.Red);
                            Cache.Instance.PreferredPrimaryWeaponTarget = null;
                        }
                    }
                    if (Cache.Instance.PreferredDroneTargetID != null)
                    {
                        foreach (EntityCache killTarget in killTargets.Where(e => e.Id == Cache.Instance.PreferredDroneTargetID))
                        {
                            if (Cache.Instance.PreferredDroneTargetID == null) continue;
                            Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "Breaking Kill Order in: [" + killTarget.Name + "][" + Math.Round(killTarget.Distance / 1000, 0) + "k][" + Cache.Instance.MaskedID((long)Cache.Instance.PreferredDroneTargetID) + "]", Logging.Red);
                            Cache.Instance.PreferredDroneTarget = null;
                        }
                    }
                }

                foreach (EntityCache KillTargetEntity in Cache.Instance.Targets.Where(e => targetNames.Contains(e.Name) && (e.IsTarget || e.IsTargeting)))
                {
                    if (Cache.Instance.PreferredPrimaryWeaponTarget != null)
                    {
                        if (KillTargetEntity.Id == Cache.Instance.PreferredPrimaryWeaponTarget.Id)
                        {
                            continue;
                        }
                    }

                    Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "Unlocking [" + KillTargetEntity.Name + "][" + Cache.Instance.MaskedID(KillTargetEntity.Id) + "][" + Math.Round(KillTargetEntity.Distance / 1000, 0) + "k away] due to kill order being put on hold", Logging.Teal);
                    KillTargetEntity.UnlockTarget("CombatMissionCtrl");
                }
            }
            else //Do not break aggression on attackers (attack normally)
            {

                //
                // check to see if we have priority targets (ECM, warp scramblers, etc, and let combat process those first)
                //
                EntityCache primaryWeaponPriorityTarget = null;
                if (Cache.Instance.PrimaryWeaponPriorityEntities.Any())
                {
                    try
                    {
                        primaryWeaponPriorityTarget = Cache.Instance.PrimaryWeaponPriorityEntities.Where(p => p.Distance < Cache.Instance.MaxRange
                                                                                    && p.IsReadyToShoot
                                                                                    && p.IsOnGridWithMe
                                                                                    && ((!p.IsNPCFrigate && !p.IsFrigate) || (!Cache.Instance.UseDrones && !p.IsTooCloseTooFastTooSmallToHit)))
                                                                                   .OrderByDescending(pt => pt.IsTargetedBy)
                                                                                   .ThenByDescending(pt => pt.IsInOptimalRange)
                                                                                   .ThenByDescending(pt => pt.IsEwarTarget)
                                                                                   .ThenBy(pt => pt.PrimaryWeaponPriorityLevel)
                                                                                   .ThenBy(pt => pt.Distance)
                                                                                   .FirstOrDefault();
                    }
                    catch (Exception ex)
                    {
                        Logging.Log("CombatMissionCtrl.Kill","Exception [" + ex + "]",Logging.Debug);
                    }
                }

                if (primaryWeaponPriorityTarget != null && primaryWeaponPriorityTarget.IsOnGridWithMe)
                {
                    if (Settings.Instance.DebugKillAction)
                    {
                        if (Cache.Instance.PrimaryWeaponPriorityTargets.Any())
                        {
                            int icount = 0;
                            foreach (EntityCache primaryWeaponPriorityEntity in Cache.Instance.PrimaryWeaponPriorityEntities.Where(i => i.IsOnGridWithMe))
                            {
                                icount++;
                                if (Settings.Instance.DebugKillAction) Logging.Log("Combat", "[" + icount + "] PrimaryWeaponPriorityTarget Named [" + primaryWeaponPriorityEntity.Name + "][" + Cache.Instance.MaskedID(primaryWeaponPriorityEntity.Id) + "][" + Math.Round(primaryWeaponPriorityEntity.Distance / 1000, 0) + "k away]", Logging.Teal);
                                continue;
                            }
                        }
                    }
                    //
                    // GetBestTarget below will choose to assign PriorityTargets over preferred targets, so we might as well wait... (and not approach the wrong target)
                    //
                }
                else
                {
                    //
                    // then proceed to kill the target
                    //
                    Cache.Instance.IgnoreTargets.RemoveWhere(targetNames.Contains);

                    if (killTargets.FirstOrDefault() != null) //if it is not null is HAS to be OnGridWithMe as all killTargets are verified OnGridWithMe
                    {
                        if (Settings.Instance.DebugKillAction) Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], " proceeding to kill the target (this is spammy, but useful debug info)", Logging.White);
                        //if (Cache.Instance.PreferredPrimaryWeaponTarget == null || String.IsNullOrEmpty(Cache.Instance.PreferredDroneTarget.Name) || Cache.Instance.PreferredPrimaryWeaponTarget.IsOnGridWithMe && Cache.Instance.PreferredPrimaryWeaponTarget != currentKillTarget)
                        //{
                            //Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "Adding [" + currentKillTarget.Name + "][" + Math.Round(currentKillTarget.Distance / 1000, 0) + "][" + Cache.Instance.MaskedID(currentKillTarget.Id) + "] groupID [" + currentKillTarget.GroupId + "] TypeID[" + currentKillTarget.TypeId + "] as PreferredPrimaryWeaponTarget", Logging.Teal);
                            Cache.Instance.AddPrimaryWeaponPriorityTarget(killTargets.FirstOrDefault(), PrimaryWeaponPriority.PriorityKillTarget, "CombatMissionCtrl.Kill[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], true);
                            Cache.Instance.PreferredPrimaryWeaponTarget = killTargets.FirstOrDefault();
                        //}
                        //else
                        if (Settings.Instance.DebugKillAction)
                        {
                            if (Settings.Instance.DebugKillAction) Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "Cache.Instance.PreferredPrimaryWeaponTarget =[ " + Cache.Instance.PreferredPrimaryWeaponTarget.Name + " ][" + Cache.Instance.MaskedID(Cache.Instance.PreferredPrimaryWeaponTarget.Id) + "]", Logging.Debug);

                            if (Cache.Instance.PrimaryWeaponPriorityTargets.Any())
                            {
                                if (Settings.Instance.DebugKillAction) Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "PrimaryWeaponPriorityTargets Below (if any)", Logging.Debug);
                                int icount = 0;
                                foreach (EntityCache PT in Cache.Instance.PrimaryWeaponPriorityEntities)
                                {
                                    icount++;
                                    if (Settings.Instance.DebugKillAction) Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "PriorityTarget [" + icount + "] [ " + PT.Name + " ][" + Cache.Instance.MaskedID(PT.Id) + "] IsOnGridWithMe [" + PT.IsOnGridWithMe + "]", Logging.Debug);
                                }
                                if (Settings.Instance.DebugKillAction) Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "PrimaryWeaponPriorityTargets Above (if any)", Logging.Debug);
                            }
                        }

                        EntityCache NavigateTowardThisTarget = null;
                        if (Cache.Instance.PreferredPrimaryWeaponTarget != null)
                        {
                            NavigateTowardThisTarget = Cache.Instance.PreferredPrimaryWeaponTarget;
                        }
                        if (Cache.Instance.PreferredPrimaryWeaponTarget != null)
                        {
                            NavigateTowardThisTarget = killTargets.FirstOrDefault();
                        }
                        //we may need to get closer so combat will take over
                        if (NavigateTowardThisTarget.Distance > Cache.Instance.MaxRange || !NavigateTowardThisTarget.IsInOptimalRange)
                        {
                            if (Settings.Instance.DebugKillAction) Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "if (Cache.Instance.PreferredPrimaryWeaponTarget.Distance > Cache.Instance.MaxRange)", Logging.Debug);
                            //if (!Cache.Instance.IsApproachingOrOrbiting(Cache.Instance.PreferredPrimaryWeaponTarget.Id))
                            //{
                            //    if (Settings.Instance.DebugKillAction) Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "if (!Cache.Instance.IsApproachingOrOrbiting(Cache.Instance.PreferredPrimaryWeaponTarget.Id))", Logging.Debug);
                                  NavigateOnGrid.NavigateIntoRange(NavigateTowardThisTarget, "combatMissionControl", true);
                            //}
                        }
                    }
                }

                if (Cache.Instance.PreferredPrimaryWeaponTarget != killTargets.FirstOrDefault())
                {
                    // GetTargets
                    //if (Settings.Instance.TargetSelectionMethod == "isdp")
                    //{
                        Cache.Instance.GetBestPrimaryWeaponTarget(Cache.Instance.MaxRange, false, "Combat");
                    //}
                    //else //use new target selection method
                    //{
                    //    Cache.Instance.__GetBestWeaponTargets(Cache.Instance.MaxRange);
                    //}
                }
            }

            // Don't use NextAction here, only if target is killed (checked further up)
            return;
        }
        private void LootItemAction(Actions.Action action)
        {
            try
            {
                Salvage.CurrentlyShouldBeSalvaging = true;
                Salvage.MissionLoot = true;
                List<string> targetContainerNames = null;
                if (action.GetParameterValues("target") != null)
                {
                    targetContainerNames = action.GetParameterValues("target");
                }

                if ((targetContainerNames == null || !targetContainerNames.Any()) && Salvage.LootItemRequiresTarget)
                {
                    Logging.Log("CombatMissionCtrl[" + PocketNumber + "]." + _pocketActions[_currentAction], " *** No Target Was Specified In the LootItem Action! ***", Logging.Debug);
                }

                List<string> itemsToLoot = null;
                if (action.GetParameterValues("item") != null)
                {
                    itemsToLoot = action.GetParameterValues("item");
                }

                if (itemsToLoot == null)
                {
                    Logging.Log("CombatMissionCtrl[" + PocketNumber + "]." + _pocketActions[_currentAction], " *** No Item Was Specified In the LootItem Action! ***", Logging.Debug);
                    Nextaction();
                }

                // if we are not generally looting we need to re-enable the opening of wrecks to
                // find this LootItems we are looking for
                if (NavigateOnGrid.SpeedTank || !NavigateOnGrid.SpeedTank) Salvage.OpenWrecks = true;

                int quantity;
                if (!int.TryParse(action.GetParameterValue("quantity"), out quantity))
                {
                    quantity = 1;
                }

                if (QuestorCache.Instance.CurrentShipsCargo != null && QuestorCache.Instance.CurrentShipsCargo.Items.Any(i => itemsToLoot != null && (itemsToLoot.Contains(i.Type) && (i.Quantity >= quantity))))
                {
                    Logging.Log("CombatMissionCtrl[" + PocketNumber + "]." + _pocketActions[_currentAction], "We are done - we have the item(s)", Logging.Teal);

                    // now that we have completed this action revert OpenWrecks to false
                    if (NavigateOnGrid.SpeedTank) Salvage.OpenWrecks = false;
                    Salvage.MissionLoot = false;
                    Salvage.CurrentlyShouldBeSalvaging = false;
                    Nextaction();
                    return;
                }

                //
                // we re-sot by distance on every pulse. The order will be potentially different on each pulse as we move around the field. this is ok and desirable.
                //
                IOrderedEnumerable<EntityCache> containers = QuestorCache.Instance.Containers.Where(e => !QuestorCache.Instance.LootedContainers.Contains(e.Id)).OrderByDescending(e => e.GroupId == (int)Group.CargoContainer).ThenBy(e => e.Distance);

                if (!containers.Any())
                {
                    Logging.Log("CombatMissionCtrl[" + PocketNumber + "]." + _pocketActions[_currentAction], "no containers left to loot, next action", Logging.Teal);
                    if (NavigateOnGrid.SpeedTank) Salvage.OpenWrecks = false;
                    Salvage.MissionLoot = false;
                    Salvage.CurrentlyShouldBeSalvaging = false;
                    Nextaction();
                    return;
                }

                //
                // add containers that we were told to loot into the ListofContainersToLoot so that they are prioritized by the background salvage routine
                //
                if (targetContainerNames != null && targetContainerNames.Any())
                {
                    foreach (EntityCache continerToLoot in containers)
                    {
                        if (targetContainerNames.Any())
                        {
                            foreach (string targetContainerName in targetContainerNames)
                            {
                                if (continerToLoot.Name == targetContainerName)
                                {
                                    if (!QuestorCache.Instance.ListofContainersToLoot.Contains(continerToLoot.Id))
                                    {
                                        QuestorCache.Instance.ListofContainersToLoot.Add(continerToLoot.Id);
                                    }
                                }

                                continue;
                            }
                        }
                        else
                        {
                            foreach (EntityCache _unlootedcontainer in QuestorCache.Instance.UnlootedContainers)
                            {
                                if (continerToLoot.Name == _unlootedcontainer.Name)
                                {
                                    if (!QuestorCache.Instance.ListofContainersToLoot.Contains(continerToLoot.Id))
                                    {
                                        QuestorCache.Instance.ListofContainersToLoot.Add(continerToLoot.Id);
                                    }
                                }

                                continue;
                            }
                        }

                        continue;
                    }
                }

                if (itemsToLoot !=null && itemsToLoot.Any())
                {
                    foreach (string itemToLoot in itemsToLoot)
                    {
                        if (!QuestorCache.Instance.ListofMissionCompletionItemsToLoot.Contains(itemToLoot))
                        {
                            QuestorCache.Instance.ListofMissionCompletionItemsToLoot.Add(itemToLoot);
                        }
                    }
                }

                EntityCache container;
                if (targetContainerNames != null && targetContainerNames.Any())
                {
                    container = containers.FirstOrDefault(c => targetContainerNames.Contains(c.Name));
                }
                else
                {
                    container = containers.FirstOrDefault();
                }

                if (container != null)
                {
                    if (container.Distance > (int)Distances.SafeScoopRange)
                    {
                        if (QuestorCache.Instance.Approaching == null || QuestorCache.Instance.Approaching.Id != container.Id || QuestorCache.Instance.MyShipEntity.Velocity < 50)
                        {
                            if (container.Approach())
                            {
                                Logging.Log("CombatMissionCtrl[" + PocketNumber + "]." + _pocketActions[_currentAction], "Approaching target [" + container.Name + "][" + container.MaskedId + "] which is at [" + Math.Round(container.Distance / 1000, 0) + "k away]", Logging.Teal);
                                return;
                            }
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                Logging.Log("CombatMissionCtrl.LootItemAction","Exception logged was [" + exception +  "]",Logging.Teal);
                return;
            }
        }
        private void LootAction(Actions.Action action)
        {
            try
            {
                List<string> items = action.GetParameterValues("item");
                List<string> targetNames = action.GetParameterValues("target");

                // if we are not generally looting we need to re-enable the opening of wrecks to
                // find this LootItems we are looking for
                if (NavigateOnGrid.SpeedTank || !NavigateOnGrid.SpeedTank) Salvage.OpenWrecks = true;
                Salvage.CurrentlyShouldBeSalvaging = true;

                if (!Salvage.LootEverything)
                {
                    if (QuestorCache.Instance.CurrentShipsCargo != null && QuestorCache.Instance.CurrentShipsCargo.Items.Any(i => items.Contains(i.Type)))
                    {
                        Logging.Log("CombatMissionCtrl[" + PocketNumber + "]." + _pocketActions[_currentAction], "LootEverything:  We are done looting", Logging.Teal);

                        // now that we are done with this action revert OpenWrecks to false
                        if (NavigateOnGrid.SpeedTank) Salvage.OpenWrecks = false;
                        Salvage.MissionLoot = false;
                        Salvage.CurrentlyShouldBeSalvaging = false;
                        Nextaction();
                        return;
                    }
                }

                // unlock targets count
                Salvage.MissionLoot = true;

                //
                // sorting by distance is bad if we are moving (we'd change targets unpredictably)... sorting by ID should be better and be nearly the same(?!)
                //
                IOrderedEnumerable<EntityCache> containers = QuestorCache.Instance.Containers.Where(e => !QuestorCache.Instance.LootedContainers.Contains(e.Id)).OrderBy(e => e.Distance);

                if (Logging.DebugLootWrecks)
                {
                    int i = 0;
                    foreach (EntityCache _container in containers)
                    {
                        i++;
                        Logging.Log("CombatMissionCtrl[" + PocketNumber + "]." + _pocketActions[_currentAction], "[" + i + "] " + _container.Name + "[" + Math.Round(_container.Distance / 1000, 0) + "k] isWreckEmpty [" + _container.IsWreckEmpty + "] IsTarget [" + _container.IsLockedTarget + "]", Logging.Debug);
                    }
                }

                if (!containers.Any())
                {
                    // lock targets count
                    Logging.Log("CombatMissionCtrl[" + PocketNumber + "]." + _pocketActions[_currentAction], "We are done looting", Logging.Teal);

                    // now that we are done with this action revert OpenWrecks to false
                    if (NavigateOnGrid.SpeedTank) Salvage.OpenWrecks = false;
                    Salvage.MissionLoot = false;
                    Salvage.CurrentlyShouldBeSalvaging = false;
                    Nextaction();
                    return;
                }

                //
                // add containers that we were told to loot into the ListofContainersToLoot so that they are prioritized by the background salvage routine
                //
                if (targetNames != null && targetNames.Any())
                {
                    foreach (EntityCache continerToLoot in containers)
                    {
                        if (continerToLoot.Name == targetNames.FirstOrDefault())
                        {
                            if (!QuestorCache.Instance.ListofContainersToLoot.Contains(continerToLoot.Id))
                            {
                                QuestorCache.Instance.ListofContainersToLoot.Add(continerToLoot.Id);
                            }
                        }
                    }
                }

                EntityCache container = containers.FirstOrDefault(c => targetNames != null && targetNames.Contains(c.Name)) ?? containers.FirstOrDefault();
                if (container != null)
                {
                    if (container.Distance > (int)Distances.SafeScoopRange)
                    {
                        if (QuestorCache.Instance.Approaching == null || QuestorCache.Instance.Approaching.Id != container.Id || QuestorCache.Instance.MyShipEntity.Velocity < 50)
                        {
                            if (container.Approach())
                            {
                                Logging.Log("CombatMissionCtrl[" + PocketNumber + "]." + _pocketActions[_currentAction], "Approaching target [" + container.Name + "][" + container.MaskedId + "][" + Math.Round(container.Distance / 1000, 0) + "k away]", Logging.Teal);
                                return;
                            }

                            return;
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                Logging.Log("CombatMissionCtrl.LootAction", "Exception logged was [" + exception + "]", Logging.Teal);
                return;
            }
        }
Exemple #13
0
        //
        // this action still needs some TLC - currently broken (unimplemented)
        //
        /*
                private void SalvageAction(Actions.Action action)
                {
                    Cache.Instance.MissionLoot = true;
                    List<string> items = action.GetParameterValues("item");
                    List<string> targetNames = action.GetParameterValues("target");

                    // if we are not generally looting we need to re-enable the opening of wrecks to
                    // find this LootItems we are looking for
                    Cache.Instance.OpenWrecks = true;

                    //
                    // when the salvage action is 'done' we will be able to open the "target"
                    //
                    bool done = items.Count == 0;
                    if (!done)
                    {
                        DirectContainer cargo = Cache.Instance.DirectEve.GetShipsCargo();

                        // We assume that the ship's cargo will be opened somewhere else
                        if (cargo.Window.IsReady)
                            done |= cargo.Items.Any(i => (items.Contains(i.TypeName)));
                    }
                    if (done)
                    {
                        Logging.Log("CombatMission." + _pocketActions[_currentAction], "We are done looting", Logging.Teal);

                        // now that we have completed this action revert OpenWrecks to false
                        Cache.Instance.OpenWrecks = false;
                        Cache.Instance.MissionLoot = false;
                        _currentAction++;
                        return;
                    }

                    IOrderedEnumerable<EntityCache> containers = Cache.Instance.Containers.Where(e => !Cache.Instance.LootedContainers.Contains(e.Id)).OrderBy(e => e.Distance);
                    if (!containers.Any())
                    {
                        Logging.Log("CombatMission." + _pocketActions[_currentAction], "We are done looting", Logging.Teal);

                        _currentAction++;
                        return;
                    }

                    EntityCache closest = containers.LastOrDefault(c => targetNames.Contains(c.Name)) ?? containers.LastOrDefault();
                    if (closest != null && (closest.Distance > (int)Distance.SafeScoopRange && (Cache.Instance.Approaching == null || Cache.Instance.Approaching.Id != closest.Id)))
                    {
                        if (DateTime.UtcNow > Cache.Instance.NextApproachAction && (Cache.Instance.Approaching == null || Cache.Instance.Approaching.Id != closest.Id))
                        {
                            Logging.Log("CombatMission." + _pocketActions[_currentAction], "Approaching target [" + closest.Name + "][ID: " + closest.Id + "] which is at [" + Math.Round(closest.Distance / 1000, 0) + "k away]", Logging.Teal);
                            closest.Approach();
                        }
                    }
                }
        */
        private void LootAction(Actions.Action action)
        {
            List<string> items = action.GetParameterValues("item");
            List<string> targetNames = action.GetParameterValues("target");

            // if we are not generally looting we need to re-enable the opening of wrecks to
            // find this LootItems we are looking for
            Cache.Instance.OpenWrecks = true;
            Cache.Instance.CurrentlyShouldBeSalvaging = true;

            if (!Settings.Instance.LootEverything)
            {
                bool done = items.Count == 0;
                if (!done)
                {
                    DirectContainer cargo = Cache.Instance.DirectEve.GetShipsCargo();

                    // We assume that the ship's cargo will be opened somewhere else
                    if (cargo.Window.IsReady)
                        done |= cargo.Items.Any(i => items.Contains(i.TypeName));
                }

                if (done)
                {
                    Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "LootEverything:  We are done looting", Logging.Teal);

                    // now that we are done with this action revert OpenWrecks to false
                    Cache.Instance.OpenWrecks = false;
                    Cache.Instance.MissionLoot = false;
                    Cache.Instance.CurrentlyShouldBeSalvaging = false;

                    _currentAction++;
                    return;
                }
            }

            // unlock targets count
            Cache.Instance.MissionLoot = true;

            IOrderedEnumerable<EntityCache> containers = Cache.Instance.Containers.Where(e => !Cache.Instance.LootedContainers.Contains(e.Id)).OrderByDescending(e => e.Id);
            if (!containers.Any())
            {
                // lock targets count
                Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "We are done looting", Logging.Teal);

                // now that we are done with this action revert OpenWrecks to false
                Cache.Instance.OpenWrecks = false;
                Cache.Instance.MissionLoot = false;
                Cache.Instance.CurrentlyShouldBeSalvaging = false;

                _currentAction++;
                return;
            }

            EntityCache container = containers.FirstOrDefault(c => targetNames.Contains(c.Name)) ?? containers.LastOrDefault();
            if (container != null && (container.Distance > (int)Distance.SafeScoopRange && (Cache.Instance.Approaching == null || Cache.Instance.Approaching.Id != container.Id)))
            {
                if (DateTime.UtcNow > Cache.Instance.NextApproachAction)
                {
                    Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "Approaching target [" + container.Name + "][ID: " + Cache.Instance.MaskedID(container.Id) + "][" + Math.Round(container.Distance / 1000, 0) + "k away]", Logging.Teal);
                    container.Approach();
                }
            }

            return;
        }
        private void AggroOnlyAction(Actions.Action action)
        {
            if (Cache.Instance.NormalApproach)
                Cache.Instance.NormalApproach = false;

            bool ignoreAttackers;
            if (!bool.TryParse(action.GetParameterValue("ignoreattackers"), out ignoreAttackers))
                ignoreAttackers = false;

            bool breakOnAttackers;
            if (!bool.TryParse(action.GetParameterValue("breakonattackers"), out breakOnAttackers))
                breakOnAttackers = false;

            bool notTheClosest;
            if (!bool.TryParse(action.GetParameterValue("notclosest"), out notTheClosest))
                notTheClosest = false;

            int numberToIgnore;
            if (!int.TryParse(action.GetParameterValue("numbertoignore"), out numberToIgnore))
                numberToIgnore = 0;

            List<string> targetNames = action.GetParameterValues("target");
            // No parameter? Ignore kill action
            if (targetNames.Count == 0)
            {
                Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "No targets defined!", Logging.Teal);
                Nextaction();
                return;
            }

            IEnumerable<EntityCache> targets = Cache.Instance.Entities.Where(e => targetNames.Contains(e.Name)).ToList();
            if (targets.Count() == numberToIgnore)
            {
                Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "All targets gone " + targetNames.Aggregate((current, next) => current + "[" + next + "]"), Logging.Teal);

                // We killed it/them !?!?!? :)
                Nextaction();
                return;
            }

            if (Cache.Instance.Aggressed.Any(t => !t.IsSentry && targetNames.Contains(t.Name)))
            {
                // We are being attacked, break the kill order
                if (Cache.Instance.RemovePriorityTargets(targets))
                    Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "Done with AggroOnly: We have aggro.", Logging.Teal);

                foreach (EntityCache target in Cache.Instance.Targets.Where(e => targets.Any(t => t.Id == e.Id)))
                {
                    Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "Unlocking [" + target.Name + "][ID: " + target.Id + "][" + Math.Round(target.Distance / 1000, 0) + "k away] due to aggro being obtained", Logging.Teal);
                    target.UnlockTarget();
                    return;
                }
                Nextaction();
                return;
            }

            if (!ignoreAttackers || breakOnAttackers)
            {
                // Apparently we are busy, wait for combat to clear attackers first
                IEnumerable<EntityCache> targetedBy = Cache.Instance.TargetedBy;
                if (targetedBy != null && targetedBy.Count(t => !t.IsSentry && t.Distance < Cache.Instance.WeaponRange) > 0)
                    return;
            }

            EntityCache closest = targets.OrderBy(t => t.Distance).First();

            if (notTheClosest)
                closest = targets.OrderByDescending(t => t.Distance).First();

            //panic handles adding any priority targets and combat will prefer to kill any priority targets
            if (Cache.Instance.PriorityTargets.All(pt => pt.Id != closest.Id))
            {
                //Adds the target we want to kill to the priority list so that combat.cs will kill it (especially if it is an LCO this is important)
                Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "Adding [" + closest.Name + "][ID: " + closest.Id + "] as a priority target", Logging.Teal);
                Cache.Instance.AddPriorityTargets(new[] { closest }, Priority.PriorityKillTarget);
            }
        }
        //
        // this action still needs some TLC - currently broken (unimplemented)
        //
        /*
                private void SalvageAction(Actions.Action action)
                {
                    Cache.Instance.MissionLoot = true;
                    List<string> items = action.GetParameterValues("item");
                    List<string> targetNames = action.GetParameterValues("target");

                    // if we are not generally looting we need to re-enable the opening of wrecks to
                    // find this LootItems we are looking for
                    Cache.Instance.OpenWrecks = true;

                    //
                    // when the salvage action is 'done' we will be able to open the "target"
                    //
                    bool done = items.Count == 0;
                    if (!done)
                    {
                        // We assume that the ship's cargo will be opened somewhere else
                        if (Cache.Instance.CurrentShipsCargo.Window.IsReady)
                            done |= Cache.Instance.CurrentShipsCargo.Items.Any(i => (items.Contains(i.TypeName)));
                    }
                    if (done)
                    {
                        Logging.Log("CombatMission." + _pocketActions[_currentAction], "We are done looting", Logging.Teal);

                        // now that we have completed this action revert OpenWrecks to false
                        Cache.Instance.OpenWrecks = false;
                        Cache.Instance.MissionLoot = false;
                        _currentAction++;
                        return;
                    }

                    IOrderedEnumerable<EntityCache> containers = Cache.Instance.Containers.Where(e => !Cache.Instance.LootedContainers.Contains(e.Id)).OrderBy(e => e.Distance);
                    if (!containers.Any())
                    {
                        Logging.Log("CombatMission." + _pocketActions[_currentAction], "We are done looting", Logging.Teal);

                        _currentAction++;
                        return;
                    }

                    EntityCache closest = containers.LastOrDefault(c => targetNames.Contains(c.Name)) ?? containers.LastOrDefault();
                    if (closest != null && (closest.Distance > (int)Distance.SafeScoopRange && (Cache.Instance.Approaching == null || Cache.Instance.Approaching.Id != closest.Id)))
                    {
                        if (DateTime.UtcNow > Cache.Instance.NextApproachAction && (Cache.Instance.Approaching == null || Cache.Instance.Approaching.Id != closest.Id))
                        {
                            Logging.Log("CombatMission." + _pocketActions[_currentAction], "Approaching target [" + closest.Name + "][ID: " + closest.Id + "] which is at [" + Math.Round(closest.Distance / 1000, 0) + "k away]", Logging.Teal);
                            closest.Approach();
                        }
                    }
                }
        */
        private void LootAction(Actions.Action action)
        {
            List<string> items = action.GetParameterValues("item");
            List<string> targetNames = action.GetParameterValues("target");

            // if we are not generally looting we need to re-enable the opening of wrecks to
            // find this LootItems we are looking for
            if (Settings.Instance.SpeedTank || !Settings.Instance.SpeedTank) Cache.Instance.OpenWrecks = true;
            Cache.Instance.CurrentlyShouldBeSalvaging = true;

            if (!Settings.Instance.LootEverything)
            {
                bool done = items.Count == 0;
                if (!done)
                {
                    // We assume that the ship's cargo will be opened somewhere else
                    if (Cache.Instance.CurrentShipsCargo.Window.IsReady)
                        done |= Cache.Instance.CurrentShipsCargo.Items.Any(i => items.Contains(i.TypeName));
                }

                if (done)
                {
                    Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "LootEverything:  We are done looting", Logging.Teal);

                    // now that we are done with this action revert OpenWrecks to false
                    if (Settings.Instance.SpeedTank) Cache.Instance.OpenWrecks = false;
                    Cache.Instance.MissionLoot = false;
                    Cache.Instance.CurrentlyShouldBeSalvaging = false;

                    _currentAction++;
                    return;
                }
            }

            // unlock targets count
            Cache.Instance.MissionLoot = true;

            //
            // sorting by distance is bad if we are moving (we'd change targets unpredictably)... sorting by ID should be better and be nearly the same(?!)
            //
            IOrderedEnumerable<EntityCache> containers = Cache.Instance.Containers.Where(e => !Cache.Instance.LootedContainers.Contains(e.Id)).OrderBy(e => e.Distance);

            if (Settings.Instance.DebugLootWrecks)
            {
                int i = 0;
                foreach (EntityCache _container in containers)
                {
                    i++;
                    Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "[" + i + "] " + _container.Name + "[" + Math.Round(_container.Distance/1000,0) + "k] isWreckEmpty [" + _container.IsWreckEmpty + "] IsTarget [" + _container.IsTarget + "]" , Logging.Debug);
                }
            }

            if (!containers.Any())
            {
                // lock targets count
                Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "We are done looting", Logging.Teal);

                // now that we are done with this action revert OpenWrecks to false
                if (Settings.Instance.SpeedTank) Cache.Instance.OpenWrecks = false;
                Cache.Instance.MissionLoot = false;
                Cache.Instance.CurrentlyShouldBeSalvaging = false;

                _currentAction++;
                return;
            }

            EntityCache container = containers.FirstOrDefault(c => targetNames.Contains(c.Name)) ?? containers.FirstOrDefault();
            if (container != null && (container.Distance > (int)Distances.SafeScoopRange && (Cache.Instance.Approaching == null || Cache.Instance.Approaching.Id != container.Id)))
            {
                if (DateTime.UtcNow > Cache.Instance.NextApproachAction)
                {
                    Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "Approaching target [" + container.Name + "][" + Cache.Instance.MaskedID(container.Id) + "][" + Math.Round(container.Distance / 1000, 0) + "k away]", Logging.Teal);
                    container.Approach();
                }
            }

            return;
        }
        private void DropItemAction(Actions.Action action)
        {
            Cache.Instance.DropMode = true;
            var items = action.GetParameterValues("item");
            var target = action.GetParameterValue("target");

            int quantity;
            if (!int.TryParse(action.GetParameterValue("quantity"), out quantity))
                quantity = 1;

            var done = items.Count == 0;

            IEnumerable<EntityCache> targets = Cache.Instance.EntitiesByName(target).ToList();
            if (!targets.Any())
            {
                Logging.Log("MissionController.DropItem", "No target name: " + targets, Logging.Orange);
                // now that we have completed this action revert OpenWrecks to false
                Cache.Instance.DropMode = false;
                Nextaction();
                return;
            }

            var closest = targets.OrderBy(t => t.Distance).First();
            if (closest.Distance > (int)Distance.SafeScoopRange)
            {
                if (Cache.Instance.Approaching == null || Cache.Instance.Approaching.Id != closest.Id)
                {
                    if (DateTime.Now > Cache.Instance.NextApproachAction)
                    {
                        Logging.Log("MissionController.DropItem", "Approaching target [" + closest.Name + "][ID: " + closest.Id + "] which is at [" + Math.Round(closest.Distance / 1000, 0) + "k away]", Logging.White);
                        closest.Approach(1000);
                    }
                }
            }
            else
            {
                if (!done)
                {
                    if (DateTime.Now > Cache.Instance.NextOpenContainerInSpaceAction)
                    {
                        var cargo = Cache.Instance.DirectEve.GetShipsCargo();

                        if (closest.CargoWindow == null)
                        {
                            Logging.Log("MissionController.DropItem", "Open Cargo", Logging.White);
                            closest.OpenCargo();
                            Cache.Instance.NextOpenContainerInSpaceAction = DateTime.Now.AddSeconds(Cache.Instance.RandomNumber(4, 6));
                            return;
                        }

                        // Get the container that is associated with the cargo container
                        var container = Cache.Instance.DirectEve.GetContainer(closest.Id);

                        var itemsToMove = cargo.Items.FirstOrDefault(i => i.TypeName.ToLower() == items.FirstOrDefault().ToLower());
                        if (itemsToMove != null)
                        {
                            Logging.Log("MissionController.DropItem", "Moving Items: " + items.FirstOrDefault() + " from cargo ship to " + container.TypeName, Logging.White);
                            container.Add(itemsToMove, quantity);

                            done = container.Items.Any(i => i.TypeName.ToLower() == items.FirstOrDefault().ToLower() && (i.Quantity >= quantity));
                            Cache.Instance.NextOpenContainerInSpaceAction = DateTime.Now.AddSeconds(Cache.Instance.RandomNumber(4, 6));
                        }
                        else
                        {
                            Logging.Log("MissionController.DropItem", "Error not found Items", Logging.White);
                            Cache.Instance.DropMode = false;
                            Nextaction();
                            return;
                        }
                    }
                }
                else
                {
                    Logging.Log("MissionController.DropItem", "We are done", Logging.White);
                    // now that we've completed this action revert OpenWrecks to false
                    Cache.Instance.DropMode = false;
                    Nextaction();
                    return;
                }
            }
        }
        private void LootItemAction(Actions.Action action)
        {
            try
            {
                Cache.Instance.CurrentlyShouldBeSalvaging = true;
                Cache.Instance.MissionLoot = true;
                List<string> items = action.GetParameterValues("item");
                List<string> targetNames = action.GetParameterValues("target");

                // if we are not generally looting we need to re-enable the opening of wrecks to
                // find this LootItems we are looking for
                if (Settings.Instance.SpeedTank || !Settings.Instance.SpeedTank) Cache.Instance.OpenWrecks = true;

                int quantity;
                if (!int.TryParse(action.GetParameterValue("quantity"), out quantity))
                {
                    quantity = 1;
                }

                bool done = items.Count == 0;
                if (!done)
                {
                    //if (!Cache.Instance.OpenCargoHold("CombatMissionCtrl.LootItemAction")) return;
                    if (Cache.Instance.CurrentShipsCargo.Window.IsReady)
                    {
                        if (Cache.Instance.CurrentShipsCargo.Items.Any(i => (items.Contains(i.TypeName) && (i.Quantity >= quantity))))
                        {
                            done = true;
                        }
                    }
                }

                if (done)
                {
                    Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "We are done looting - we have the item(s)", Logging.Teal);

                    // now that we have completed this action revert OpenWrecks to false
                    if (Settings.Instance.SpeedTank) Cache.Instance.OpenWrecks = false;
                    Cache.Instance.MissionLoot = false;
                    Cache.Instance.CurrentlyShouldBeSalvaging = false;
                    _currentAction++;
                    return;
                }

                //
                // sorting by distance is bad if we are moving (we'd change targets unpredictably)... sorting by ID should be better and be nearly the same(?!)
                //
                IOrderedEnumerable<EntityCache> containers = Cache.Instance.Containers.Where(e => !Cache.Instance.LootedContainers.Contains(e.Id)).OrderBy(e => e.Distance);

                if (!containers.Any())
                {
                    Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "We are done looting - no containers left to loot", Logging.Teal);
                    if (Settings.Instance.SpeedTank) Cache.Instance.OpenWrecks = false;
                    Cache.Instance.MissionLoot = false;
                    Cache.Instance.CurrentlyShouldBeSalvaging = false;
                    _currentAction++;
                    return;
                }

                EntityCache container = containers.FirstOrDefault(c => targetNames.Contains(c.Name)) ?? containers.FirstOrDefault();
                if (container != null && (container.Distance > (int)Distances.SafeScoopRange && (Cache.Instance.Approaching == null || Cache.Instance.Approaching.Id != container.Id)))
                {
                    if (DateTime.UtcNow > Cache.Instance.NextApproachAction && (Cache.Instance.Approaching == null || Cache.Instance.Approaching.Id != container.Id))
                    {
                        Logging.Log("CombatMissionCtrl[" + Cache.Instance.PocketNumber + "]." + _pocketActions[_currentAction], "Approaching target [" + container.Name + "][" + Cache.Instance.MaskedID(container.Id) + "] which is at [" + Math.Round(container.Distance / 1000, 0) + "k away]", Logging.Teal);
                        container.Approach();
                    }
                }
            }
            catch (Exception exception)
            {
                Logging.Log("CombatMissionCtrl.LootItemAction","Exception logged was [" + exception +  "]",Logging.Teal);
            }

            return;
        }
        private void KillAction(Actions.Action action)
        {
            if (Cache.Instance.NormalApproach)
                Cache.Instance.NormalApproach = false;

            bool ignoreAttackers;
            if (!bool.TryParse(action.GetParameterValue("ignoreattackers"), out ignoreAttackers))
                ignoreAttackers = false;

            bool breakOnAttackers;
            if (!bool.TryParse(action.GetParameterValue("breakonattackers"), out breakOnAttackers))
                breakOnAttackers = false;

            bool notTheClosest;
            if (!bool.TryParse(action.GetParameterValue("notclosest"), out notTheClosest))
                notTheClosest = false;

            int numberToIgnore;
            if (!int.TryParse(action.GetParameterValue("numbertoignore"), out numberToIgnore))
                numberToIgnore = 0;

            List<string> targetNames = action.GetParameterValues("target");
            // No parameter? Ignore kill action
            if (targetNames.Count == 0)
            {
                Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "No targets defined in kill action!", Logging.Teal);
                Nextaction();
                return;
            }

            IEnumerable<EntityCache> targets = Cache.Instance.Entities.Where(e => targetNames.Contains(e.Name)).ToList();
            if (targets.Count() == numberToIgnore)
            {
                Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "All targets killed " + targetNames.Aggregate((current, next) => current + "[" + next + "]"), Logging.Teal);

                // We killed it/them !?!?!? :)
                Nextaction();
                return;
            }

            if (breakOnAttackers && Cache.Instance.TargetedBy.Any(t => !t.IsSentry && t.Distance < Cache.Instance.WeaponRange))
            {
                // We are being attacked, break the kill order
                if (Cache.Instance.RemovePriorityTargets(targets))
                    Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "Breaking off kill order, new spawn has arrived!", Logging.Teal);

                foreach (EntityCache entity in Cache.Instance.Targets.Where(e => targets.Any(t => t.Id == e.Id)))
                {
                    Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "Unlocking [" + entity.Name + "][ID: " + entity.Id + "][" + Math.Round(entity.Distance / 1000, 0) + "k away] due to kill order being put on hold", Logging.Teal);
                    entity.UnlockTarget();
                }
            }

            if (!ignoreAttackers || breakOnAttackers)
            {
                // Apparently we are busy, wait for combat to clear attackers first
                IEnumerable<EntityCache> targetedBy = Cache.Instance.TargetedBy;
                if (targetedBy != null && targetedBy.Count(t => !t.IsSentry && t.Distance < Cache.Instance.WeaponRange) > 0)
                    return;
            }

            EntityCache target = targets.OrderBy(t => t.Distance).First();
            int targetedby = Cache.Instance.TargetedBy.Count(t => !t.IsSentry && !t.IsEntityIShouldLeaveAlone && !t.IsContainer && t.IsNpc && t.CategoryId == (int)CategoryID.Entity && t.GroupId != (int)Group.LargeCollidableStructure && !Cache.Instance.IgnoreTargets.Contains(t.Name.Trim()));
            if (target != null)
            {
                // Reset timeout
                _clearPocketTimeout = null;

                // Are we approaching the active (out of range) target?
                // Wait for it (or others) to get into range

                // Lock priority target if within weapons range

                if (notTheClosest)
                    target = targets.OrderByDescending(t => t.Distance).First();

                if (target.Distance < Cache.Instance.MaxRange)
                {
                    //panic handles adding any priority targets and combat will prefer to kill any priority targets
                    if (Cache.Instance.PriorityTargets.All(pt => pt.Id != target.Id))
                    {
                        //Adds the target we want to kill to the priority list so that combat.cs will kill it (especially if it is an LCO this is important)
                        Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "Adding [" + target.Name + "][ID: " + target.Id + "] as a priority target", Logging.Teal);
                        Cache.Instance.AddPriorityTargets(new[] { target }, Priority.PriorityKillTarget);
                    }
                    if (_targetNull && targetedby == 0 && DateTime.Now > Cache.Instance.NextReload)
                    {
                        //Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction] ,"Reload if [" + _targetNull + "] && [" + targetedby + "] == 0 AND [" + Math.Round(target.Distance, 0) + "] < [" + Cache.Instance.MaxRange + "]", Logging.teal);
                        if (!Combat.ReloadAll(target)) return;
                    }

                    if (Cache.Instance.DirectEve.ActiveShip.MaxLockedTargets > 0)
                    {
                        if (!(target.IsTarget || target.IsTargeting)) //This target is not targeted and need to target it
                        {
                            Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "Targeting [" + target.Name + "][ID: " + target.Id + "][" + Math.Round(target.Distance / 1000, 0) + "k away]", Logging.Teal);
                            target.LockTarget();
                        }
                    }
                }
                NavigateOnGrid.NavigateIntoRange(target, "CombatMissionCtrl." + _pocketActions[_currentAction]);
                if (target.Distance > Cache.Instance.MaxRange)
                {
                    if (DateTime.Now > Cache.Instance.NextReload)
                    {
                        //Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction] ,"ReloadAll: Reload weapons", Logging.teal);
                        if (!Combat.ReloadAll(target)) return;
                    }
                }
                return;
            }
        }
Exemple #19
0
        private void KillClosestByNameAction(Actions.Action action)
        {
            bool notTheClosest;
            if (!bool.TryParse(action.GetParameterValue("notclosest"), out notTheClosest))
            {
                notTheClosest = false;
            }

            if (Cache.Instance.NormalApproach) Cache.Instance.NormalApproach = false;

            List<string> targetNames = action.GetParameterValues("target");

            // No parameter? Ignore kill action
            if (targetNames.Count == 0)
            {
                Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "No targets defined!", Logging.Teal);
                Nextaction();
                return;
            }

            //IEnumerable<EntityCache> targets = Cache.Instance.Entities.Where(e => targetNames.Contains(e.Name));
            EntityCache target = Cache.Instance.Entities.Where(e => targetNames.Contains(e.Name)).OrderBy(t => t.Distance).FirstOrDefault();
            if (notTheClosest) target = Cache.Instance.Entities.Where(e => targetNames.Contains(e.Name)).OrderByDescending(t => t.Distance).FirstOrDefault();

            if (target != null)
            {
                if (target.Distance < Cache.Instance.MaxRange)
                {
                    //Adds the target we want to kill to the priority list so that combat.cs will kill it (especially if it is an LCO this is important)
                    Cache.Instance.AddPrimaryWeaponPriorityTargets(new[] { target }, PrimaryWeaponPriority.PriorityKillTarget, "CombatMissionCtrl." + _pocketActions[_currentAction]);

                    if (target.IsFrigate || Settings.Instance.DronesKillHighValueTargets || Cache.Instance.EntitiesNotSelf.All(i => !i.IsNPCFrigate))
                    {
                        Cache.Instance.AddDronePriorityTargets(new[] { target }, DronePriority.LowPriorityTarget, "CombatMissionCtrl." + _pocketActions[_currentAction]);
                    }
                }

                NavigateOnGrid.NavigateIntoRange(target, "CombatMissionCtrl." + _pocketActions[_currentAction]);
                return;
            }

            Logging.Log("CombatMissionCtrl." + _pocketActions[_currentAction], "All targets killed, not valid anymore ", Logging.Teal);

            // We killed it/them !?!?!? :)
            Nextaction();
            return;
        }