private static void ActivateTractorBeams()
{
if (Cache.Instance.NextTractorBeamAction > DateTime.UtcNow)
{
if (Settings.Instance.DebugTractorBeams) Logging.Log("Salvage.ActivateTractorBeams", "Debug: Cache.Instance.NextTractorBeamAction is still in the future, waiting", Logging.Teal);
return;
}
IEnumerable<ModuleCache> tractorBeams = Cache.Instance.Modules.Where(m => m.GroupId == (int)Group.TractorBeam);
if (!tractorBeams.Any())
return;
if (Cache.Instance.InMission && Cache.Instance.InSpace && Cache.Instance.ActiveShip.CapacitorPercentage < Settings.Instance.TractorBeamMinimumCapacitor)
{
if (Settings.Instance.DebugTractorBeams) Logging.Log("ActivateTractorBeams", "Capacitor [" + Math.Round(Cache.Instance.ActiveShip.CapacitorPercentage, 0) + "%] below [" + Settings.Instance.TractorBeamMinimumCapacitor + "%] TractorBeamMinimumCapacitor", Logging.Red);
return;
}
double tractorBeamRange = tractorBeams.Min(t => t.OptimalRange);
List<EntityCache> wrecks = Cache.Instance.Targets.Where(t => (t.GroupId == (int)Group.Wreck || t.GroupId == (int)Group.CargoContainer) && t.Distance < tractorBeamRange).ToList();
int tractorsProcessedThisTick = 0;
ModuleNumber = 0;
//
// Deactivate tractorbeams
//
foreach (ModuleCache tractorBeam in tractorBeams)
{
ModuleNumber++;
if (tractorBeam.IsActive)
{
//tractorBeams.Remove(tractorBeam);
if (Settings.Instance.DebugTractorBeams) Logging.Log("ActivateTractorBeams.Deactivating", "[" + ModuleNumber + "] Tractorbeam is: IsActive [" + tractorBeam.IsActive + "]. Continue", Logging.Debug);
continue;
}
if (tractorBeam.InLimboState)
{
//tractorBeams.Remove(tractorBeam);
if (Settings.Instance.DebugTractorBeams) Logging.Log("ActivateTractorBeams.Deactivating", "[" + ModuleNumber + "] Tractorbeam is: InLimboState [" + tractorBeam.InLimboState + "] IsDeactivating [" + tractorBeam.IsDeactivating + "] IsActivatable [" + tractorBeam.IsActivatable + "] IsOnline [" + tractorBeam.IsOnline + "] IsGoingOnline [" + tractorBeam.IsGoingOnline + "]. Continue", Logging.Debug);
continue;
}
//if ( !tractorBeam.IsActive && !tractorBeam.IsDeactivating)
// continue;
EntityCache wreck = wrecks.FirstOrDefault(w => w.Id == tractorBeam.TargetId);
//for Cache.Instance.UnlootedContainers.Contains()
bool currentWreckUnlooted = false;
if (Settings.Instance.DebugTractorBeams) Logging.Log("Salvage.ActivateTractorBeams.Deactivating", "MyShip.Velocity [" + Math.Round(Cache.Instance.MyShipEntity.Velocity, 0) + "]", Logging.Teal);
if (Cache.Instance.MyShipEntity.Velocity > 300)
{
if (Settings.Instance.DebugTractorBeams) Logging.Log("Salvage.ActivateTractorBeams.Deactivating", "if (Cache.Instance.MyShip.Velocity > 300)", Logging.Teal);
foreach (EntityCache unlootedcontainer in Cache.Instance.UnlootedContainers)
{
if (tractorBeam.TargetId == unlootedcontainer.Id)
{
currentWreckUnlooted = true;
if (Settings.Instance.DebugTractorBeams) Logging.Log("Salvage.ActivateTractorBeams.Deactivating", "if (tractorBeam.TargetId == unlootedcontainer.Id) break;", Logging.Teal);
break;
}
}
}
else
{
//if (Settings.Instance.DebugTractorBeams) Logging.Log("Salvage.ActivateTractorBeams", "if (!Cache.Instance.MyShip.Velocity > 300)", Logging.Teal);
}
// If the wreck no longer exists, or its within loot range then disable the tractor beam
// If the wreck no longer exist, beam should be deactivated automatically. Without our interaction.
if (tractorBeam.IsActive && (wreck == null || (wreck.Distance <= (int)Distances.SafeScoopRange && !currentWreckUnlooted)))
{
if (Settings.Instance.DebugTractorBeams) Logging.Log("Salvage.ActivateTractorBeams.Deactivating", "[" + ModuleNumber + "] Tractorbeam: IsActive [" + tractorBeam.IsActive + "] and the wreck [" + wreck.Name + "] is in SafeScoopRange [" + Math.Round(wreck.Distance / 1000, 0) + "]", Logging.Teal);
//tractorBeams.Remove(tractorBeam);
if (tractorBeam.Click())
{
tractorsProcessedThisTick++;
Cache.Instance.NextTractorBeamAction = DateTime.UtcNow.AddMilliseconds(Time.Instance.SalvageDelayBetweenActions_milliseconds);
if (tractorsProcessedThisTick < Settings.Instance.NumberOfModulesToActivateInCycle)
{
if (Settings.Instance.DebugTractorBeams) Logging.Log("Salvage.ActivateTractorBeams.Deactivating", "[" + ModuleNumber + "] Tractorbeam: Process Next Tractorbeam", Logging.Teal);
continue;
}
if (Settings.Instance.DebugTractorBeams) Logging.Log("Salvage.ActivateTractorBeams.Deactivating", "[" + ModuleNumber + "] Tractorbeam: We have processed [" + Settings.Instance.NumberOfModulesToActivateInCycle + "] tractors this tick, return", Logging.Teal);
return;
}
return;
}
wrecks.RemoveAll(w => w.Id == tractorBeam.TargetId);
}
//
// Activate tractorbeams
//
int WreckNumber = 0;
foreach (EntityCache wreck in wrecks.OrderByDescending(i => i.IsLootTarget))
{
WreckNumber++;
// This velocity check solves some bugs where velocity showed up as 150000000m/s
if ((int)wreck.Velocity != 0) //if the wreck is already moving assume we should not tractor it.
{
if (Settings.Instance.DebugTractorBeams) Logging.Log("Salvage.ActivateTractorBeams.Activating", "[" + WreckNumber + "] Wreck [" + wreck.Name + "][" + wreck.MaskedId + "] is already moving: do not tractor a wreck that is moving", Logging.Debug);
continue;
}
// Is this wreck within range?
if (wreck.Distance < (int)Distances.SafeScoopRange)
{
continue;
}
if (!tractorBeams.Any()) return;
foreach (ModuleCache tractorBeam in tractorBeams)
{
ModuleNumber++;
if (tractorBeam.IsActive)
{
if (Settings.Instance.DebugTractorBeams) Logging.Log("Salvage.ActivateTractorBeams.Activating", "[" + WreckNumber + "][::" + ModuleNumber + "] Tractorbeam is: IsActive [" + tractorBeam.IsActive + "]. Continue", Logging.Debug);
continue;
}
if (tractorBeam.InLimboState)
{
if (Settings.Instance.DebugTractorBeams) Logging.Log("Salvage.ActivateTractorBeams.Activating", "[" + WreckNumber + "][::" + ModuleNumber + "] Tractorbeam is: InLimboState [" + tractorBeam.InLimboState + "] IsDeactivating [" + tractorBeam.IsDeactivating + "] IsActivatable [" + tractorBeam.IsActivatable + "] IsOnline [" + tractorBeam.IsOnline + "] IsGoingOnline [" + tractorBeam.IsGoingOnline + "]. Continue", Logging.Debug);
continue;
}
//
// this tractor has already been activated at least once
//
if (Cache.Instance.LastActivatedTimeStamp != null && Cache.Instance.LastActivatedTimeStamp.ContainsKey(tractorBeam.ItemId))
{
if (Cache.Instance.LastActivatedTimeStamp[tractorBeam.ItemId].AddSeconds(5) > DateTime.UtcNow)
{
continue;
}
}
if (tractorBeams.Any(i => i.TargetId == wreck.Id))
{
continue;
}
//tractorBeams.Remove(tractorBeam);
if (tractorBeam.Activate(wreck))
{
tractorsProcessedThisTick++;
Logging.Log("Salvage", "[" + WreckNumber + "][::" + ModuleNumber + "] Activating tractorbeam [" + ModuleNumber + "] on [" + wreck.Name + "][" + Math.Round(wreck.Distance / 1000, 0) + "k][" + wreck.MaskedId + "] IsWreckEmpty [" + wreck.IsWreckEmpty + "]", Logging.White);
Cache.Instance.NextTractorBeamAction = DateTime.UtcNow.AddMilliseconds(Time.Instance.SalvageDelayBetweenActions_milliseconds);
break; //we do not need any more tractors on this wreck
}
continue;
}
if (tractorsProcessedThisTick > Settings.Instance.NumberOfModulesToActivateInCycle)
{
//
// if we have processed 'enough' wrecks this tick, return
//
return;
}
//
// move on to the next wreck
//
continue;
}
return;
}