/*
* Summary: Finds the best safe spot. distance yards away from all mobs.
*/
private Point FindSafeSpot()
{
Log("Finding safe spot...");
Stopwatch timer = Stopwatch.StartNew();
WoWPoint safeSpot = Me.Location;
List<WoWUnit> units = new List<WoWUnit>(ObjectManager.NpcObjectList.Values);
units.Sort(CompareDistance);
List<WoWUnit> unitsInRange = new List<WoWUnit>();
List<double> unitsDistance = new List<double>();
List<Point> ThreadList1 = new List<Point>();
List<Point> ThreadList2 = new List<Point>();
List<Point> ThreadList3 = new List<Point>();
int goodDistance = 0; //number of lowest distance found
int distance = 30;
double angleIncrements = DegreeToRadian(20);
double angle = 0;
foreach (WoWUnit unit in units)
{
if (Me.Combat || unit.Distance > distance)
break;
if (ValidUnitCheck(unit) && unit.Distance <= distance
// UnitRelationCommented
//&& unit.GetUnitRelation(Me) != WoWUnit.WoWUnitRelation.Neutral
)
{
unitsDistance.Add(0);
unitsInRange.Add(unit);
}
}
Log("Looking target npc's finished. " + timer.ElapsedMilliseconds.ToString());
if (unitsInRange.Count > 0)
Log("Number of hostiles within a " + distance + " yard range: " + unitsInRange.Count.ToString());
else
{
Log("No hostiles within a " + distance + " yard range");
return safeSpot;
}
int distanceFromLocation = 15;
int count = 1;
for (int i = 0; i < 18; i++)
{
if (Me.Combat)
break;
Point point = CalculatePointTo(Me.Location, angle, distanceFromLocation);
switch (count)
{
case 1:
ThreadList1.Add(point);
break;
case 2:
ThreadList2.Add(point);
break;
case 3:
ThreadList3.Add(point);
break;
}
count++;
if (count == 4)
count = 1;
angle += angleIncrements;
}
angle = 10;
distanceFromLocation = 25;
for (int i = 0; i < 18; i++)
{
if (Me.Combat)
break;
Point point = CalculatePointTo(Me.Location, angle, distanceFromLocation);
switch (count)
{
case 1:
ThreadList1.Add(point);
break;
case 2:
ThreadList2.Add(point);
break;
case 3:
ThreadList3.Add(point);
break;
}
count++;
if (count == 4)
count = 1;
angle += angleIncrements;
}
_safeSpotPoints.Clear();
_safeSpotPointsThread3.Clear();
_safeSpotPointsThread2.Clear();
_safeSpotPointsThread1.Clear();
List<Point> npcLoc = new List<Point>();
foreach (WoWUnit unit in units)
{
if (Me.Combat || unit.Distance > 75)
break;
if (ValidUnitCheck(unit)
// UnitRelationCommented
//&& unit.GetUnitRelation(Me) != WoWUnit.WoWUnitRelation.Neutral
)
{
npcLoc.Add(unit.Location);
}
}
Log("Starting threads...");
ThreadStart safeSpotCheck3 = () => SafeSpotCheck(ThreadList3, npcLoc, 3);
_safeSpotCheck3 = new Thread(safeSpotCheck3);
if (ThreadList3.Count > 0 && !Me.Combat)
_safeSpotCheck3.Start();
ThreadStart safeSpotCheck2 = () => SafeSpotCheck(ThreadList2, npcLoc, 2);
_safeSpotCheck2 = new Thread(safeSpotCheck2);
if (ThreadList2.Count > 0 && !Me.Combat)
_safeSpotCheck2.Start();
ThreadStart safeSpotCheck1 = () => SafeSpotCheck(ThreadList1, npcLoc, 1);
_safeSpotCheck1 = new Thread(safeSpotCheck1);
if (ThreadList1.Count > 0 && !Me.Combat)
_safeSpotCheck1.Start();
Log("Threads started waiting for complete...");
while ((_safeSpotCheck1.IsAlive || _safeSpotCheck2.IsAlive || _safeSpotCheck3.IsAlive) && !Me.Combat)
Thread.Sleep(50);
_safeSpotPoints.AddRange(_safeSpotPointsThread3);
_safeSpotPoints.AddRange(_safeSpotPointsThread2);
_safeSpotPoints.AddRange(_safeSpotPointsThread1);
Log("End threads: " + timer.ElapsedMilliseconds.ToString());
if (Me.Combat)
return safeSpot;
foreach (Point testPoint in _safeSpotPoints)
{
if (Me.Combat)
break;
bool skip = false;
List<double> tempDistance = new List<double>(); // stores the distance of all units
int countDistance = 0; // variable to count the number of good distance
for (int i = 0; i < unitsInRange.Count; i++)
{
if (Me.Combat)
break;
WoWUnit unitTest = unitsInRange[i];
tempDistance.Add(unitTest.Location.Distance(testPoint)); //gets unitdistance from new point
if (tempDistance[i] <= distance)
{
skip = true;
break;
}
if (tempDistance[i] >= unitsDistance[i])
countDistance++;
}
if (skip)
continue;
else
{
if (countDistance > goodDistance)
{
unitsDistance = tempDistance;
goodDistance = countDistance;
safeSpot = testPoint;
}
}
}
timer.Stop();
if (safeSpot != Me.Location)
Log("Safe spot found... " + timer.ElapsedMilliseconds.ToString());
else
Log("Using current spot... " + timer.ElapsedMilliseconds.ToString());
return safeSpot;
}