public void FlyTo(P3d destination)
{
Random rnd = new Random();
FrameLock fl = new FrameLock(false);
fl.Lock();
P3d me = new P3d(isxwow.Me.X, isxwow.Me.Y, isxwow.Me.Z);
fl.Unlock();
P3d tempDestination = me;
double newZ;
double closeZ;
double distantZ;
double oldZ = me.Z;
do // bis wir am endgültigen zielpunkt angekommen sind
{
Thread.Sleep(125); // 8x pro sekunde maximum
// aktuelle position auffrischen
fl.Lock();
me = new P3d(isxwow.Me.X, isxwow.Me.Y, isxwow.Me.Z);
// terrainhöhe = schnittpunkt von mir zum boden
destination.Z = isxwow.CollisionTest(me.X, me.Y, me.Z, me.X, me.Y, 0).Z;
fl.Unlock();
// wir sind nah am temporären zielort -> neuen click berechnen und ausführen
if (InInterval(me.X, tempDestination.X, 20) && InInterval(me.Y, tempDestination.Y, 20))
{
newZ = me.Z; // alle z's für die nächste runde resetten, wir ermitteln neue
closeZ = 0;
distantZ = 0;
// ermittlung des vektors
P3d vektor = new P3d(destination.X - me.X, destination.Y - me.Y, 0);
double vektorLaenge = vektor.Pyth();
// umrechnung zu einheitsvektor; z ist total wayne, kennen wir eh nicht vom ziel
vektor.X = vektor.X / vektorLaenge;
vektor.Y = vektor.Y / vektorLaenge;
destination.Z = me.Z;
// ermittle einen neuen punkt zum anklicken. 5 yards weit weg vom aktuellen ziel
tempDestination = new P3d(vektor.X * 50 + me.X, vektor.Y * 50 + me.Y, me.Z);
// der eigentliche zielpunkt ist näher als unsere ermittelte temporäre koordinate
if (tempDestination.DistanceTo(me) > destination.DistanceTo(me))
tempDestination = destination;
fl.Lock();
for (int i = 1; i < 102; i += 10) // ermittle das höchste z in 101 yards entfernung
{
Point3f collision = isxwow.CollisionTest(vektor.X * i + me.X, vektor.Y * i + me.Y, 0, vektor.X * i + me.X, vektor.Y * i + me.Y, 600);
if (collision.Z > closeZ)
closeZ = collision.Z;
}
for (int i = 102; i < 303; i += 50) // ermittle das höchste z in 102-302 yards entfernung
{
Point3f collision = isxwow.CollisionTest(vektor.X * i + me.X, vektor.Y * i + me.Y, 0, vektor.X * i + me.X, vektor.Y * i + me.Y, 600);
if (collision.Z > distantZ)
distantZ = collision.Z;
}
if (distantZ > closeZ) // in weiter ferne ist ein berg; langsam schonmal die höhe anpassen damit man später nicht ganz so steil aufsteigen muss
newZ = (distantZ - closeZ) / 3 + closeZ;
else // in der nähe ist der höchste punkt, mindestens so hoch steigen
newZ = closeZ;
richTextBox1.BeginInvoke(new UpdateTextCallback(this.UpdateText), new object[] { "new temp loc! Z = " + newZ });
// + flughöhe + x, außer es geht zu steil bergab, dann nur um ~50 sinken
if (!InInterval(oldZ, newZ, 20))
{
if ((oldZ - newZ) > 50 && newZ < oldZ)
{
newZ = oldZ - 50;
}
else
{
newZ += 50 + rnd.NextDouble() * 10;
}
}
else
{
// verändere z nur wenn es sich um 20 yards oder weniger ändert um kleine geländeveränderungen zu ignorieren
newZ = oldZ;
}
richTextBox1.BeginInvoke(new UpdateTextCallback(this.UpdateText), new object[] { "new temp loc! Z = " + newZ });
isxwow.RightClickTerrain(tempDestination.X, tempDestination.Y, newZ);
oldZ = newZ; // zwischenspeichern für die z pufferung
fl.Unlock();
}
}
while (!InInterval(me.X, destination.X, 10) && !InInterval(me.Y, destination.Y, 10)); // sind wir schon da?
}