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? }