private void GetEntities() { var methodName = "GetEntities"; LogTrace(methodName); ClearEntities(); _ratNpcEntities.AddRange( Core.StealthBot.EntityProvider.EntityWrappers.Where( entity => entity.IsNPC && entity.CategoryID == (int)CategoryIDs.Entity && !_attackers.IsConcordTarget(entity.GroupID) && _attackers.IsRatTarget(entity) && entity.Distance < (int)Ranges.Warp)); _ratPcEntities.AddRange( Core.StealthBot.EntityProvider.EntityWrappers.Where( entity => entity.IsPC && entity.CategoryID == (int)CategoryIDs.Ship)); }
private bool ProcessClearRoom(Action action) { var methodName = "ProcessClearRoom"; LogTrace(methodName); //So, I'm in a mission room, how do I decide what gets shot? //If I have non-triggers... //and any are shooting me, queue 'em all and prepare for RAEP. //otherwise, queue only the first one. //otherwise, queue only the first non-trigger. //This way, I take down any aggro, and when out of aggro will only shoot things one by one, //so I only end up pulling one group at a time instead of a rat from group A and a rat from group B, //thus pulling the whole goddamn room. var validEntities = _entityProvider.EntityWrappers .Where(entity => !StealthBot.Attackers.IsConcordTarget(entity.GroupID) && _attackers.IsRatTarget(entity) && !action.DoNotKillNames.Any(doNotKillName => entity.Name.Contains(doNotKillName, StringComparison.InvariantCultureIgnoreCase))); //Get the list of entities which are possible triggers var possibleTriggerNpcEntities = validEntities .Where(entity => action.PossibleTriggerNames.Any(possibleTriggerName => entity.Name.Contains(possibleTriggerName, StringComparison.InvariantCultureIgnoreCase))); var npcCountsByName = possibleTriggerNpcEntities .GroupBy(entity => entity.Name) .Select(list => new { Name = list.Key, Count = list.Count() }) .ToDictionary(entry => entry.Name, entry => entry.Count); possibleTriggerNpcEntities = possibleTriggerNpcEntities.OrderByDescending( entity => npcCountsByName[entity.Name]); //Get the list of entities which are not possible triggers var nonTriggerNpcEntities = validEntities .Where(entity => !action.PossibleTriggerNames.Any(possibleTriggerName => entity.Name.Contains(possibleTriggerName, StringComparison.InvariantCultureIgnoreCase))) .OrderBy(entity => entity.Distance).ThenBy(entity => entity.Bounty); var npcEntitiesToKill = new List <IEntityWrapper>(); //if I have non-triggers... if (nonTriggerNpcEntities.Any()) { //See how many are shooting me! var nonTriggerNpcEntitiesShootingMe = nonTriggerNpcEntities .Where(entity => _attackers.ThreatEntities.Any(threatEntity => threatEntity.ID == entity.ID)); //If I have some shooting me, kill 'em all! if (nonTriggerNpcEntitiesShootingMe.Any()) { npcEntitiesToKill.AddRange(nonTriggerNpcEntitiesShootingMe); } //otherwise, kill only the FIRST entity not shooting us so we don't get aggroraepd! else { npcEntitiesToKill.Add(nonTriggerNpcEntities.First()); } } //no non-triggers? Kill oly the FIRST trigger so we don't get aggro raepd! else if (possibleTriggerNpcEntities.Any()) { //Don't add another thing to kill unless we're out of things to kill if (StealthBot.TargetQueue.Targets.Count == 0) { npcEntitiesToKill.Add(possibleTriggerNpcEntities.First()); } } //If I got anything to kill, do so. if (npcEntitiesToKill.Count > 0) { //We're killing something; we should salvage _shouldSalvageRoom = true; //Approach if I need to, otherwise kill shit. var targetEntity = npcEntitiesToKill.First(); if (!StealthBot.Movement.IsMoving && NeedToApproachEntity(targetEntity)) { var distance = StealthBot.Ship.GetMaximumWeaponRange(); if (distance > StealthBot.Ship.MaxTargetRange) { distance = StealthBot.Ship.MaxTargetRange; } var entityDestination = new Destination(DestinationTypes.Entity, targetEntity.ID) { Distance = distance * 0.95 }; LogMessage(methodName, LogSeverityTypes.Standard, "Closest entity \"{0}\" ({1}) is out of maximum weapon range - getting within {2} of it.", targetEntity.Name, targetEntity.ID, entityDestination.Distance); StealthBot.Movement.QueueDestination(entityDestination); } else { //Queue all entities listed in entitiesToKill foreach (var entity in npcEntitiesToKill) { //If we have a valid QueueTarget built in Attackers, use it, otherwise build our own if (StealthBot.Attackers.QueueTargetsByEntityId.ContainsKey(entity.ID)) { //Get the ship type, queue the entity with ship type var target = StealthBot.Attackers.QueueTargetsByEntityId[entity.ID]; StealthBot.TargetQueue.EnqueueTarget(target.Id, target.Priority, target.SubPriority, target.Type); } else { StealthBot.TargetQueue.EnqueueTarget(entity.ID, StealthBot.Attackers.GetTargetPriority(entity), TargetTypes.Kill); } } } } //Wow, no entities at all? Shit sucks. Check for the timeouts! if (!validEntities.Any()) { //If there's no timeout specified... if (action.TimeoutSeconds == 0) { if (_timesClear-- <= 0) { LogMessage(methodName, LogSeverityTypes.Standard, "All entities killed, ClearRoom action complete."); _timesClear = MinimumTimesClear; return(true); } } else { if (_timeoutExpired == DateTime.MinValue) { LogMessage(methodName, LogSeverityTypes.Standard, "All current entities killed, waiting for timeout or spawn."); _timeoutExpired = DateTime.Now.AddSeconds(action.TimeoutSeconds); } else { if (DateTime.Now.CompareTo(_timeoutExpired) >= 0) { LogMessage(methodName, LogSeverityTypes.Standard, "All new entities killed or timeout expired, ClearRoom action complete."); _timeoutExpired = DateTime.MinValue; return(true); } } } } return(false); }