227 lines
12 KiB
Markdown
227 lines
12 KiB
Markdown
# Freie Flugreisen
|
||
|
||
Die Umsetzung ergänzt die Planungsgrundlage in [free-flying.md](free-flying.md).
|
||
Freies Fliegen ist eine vorübergehend berechnete Alternative im Fernreisesystem.
|
||
Es werden dafür weder Nodes noch Kanten in der Datenbank aufgezeichnet.
|
||
|
||
## Reiseplanung
|
||
|
||
Ein Flug kann an einem regulären Graphnode oder einem virtuellen Straßenausstieg
|
||
beginnen und an einem regulären Node oder einer Location enden. Virtuelle
|
||
Straßeneinstiege sind keine Flugziele. Der Abflugpunkt muss tatsächlich erreicht
|
||
sein. Für den Rückfall bei fehlendem Bodenweg kann der tatsächliche sichere
|
||
Aufenthaltsort als Abflugpunkt dienen; dabei gelten dieselben nativen Startprüfungen.
|
||
|
||
Normale Straßenreisen haben einen Kostenvorteil. Flug wird bei genügend großem
|
||
Vorteil berücksichtigt; bevorzugte Flugzonen senken Mindestdistanz und Kosten.
|
||
Damit können dort auch die Anschlussstrecken zwischen Nodes und Locations fliegen.
|
||
Die Vorgabe meint insbesondere Gebiete, deren Aufbau und gefährliche Gegner
|
||
Bodenreisen ungeeignet machen. Die Kosten sind Planungsgewichte, keine Sekunden.
|
||
Scheitert eine Flugoption am Boden, wird nur diese Option für die aktuelle Reise
|
||
gesperrt und mit den übrigen Möglichkeiten erneut geplant.
|
||
|
||
Die Planung berücksichtigt Kartentyp, bekannte Gebietsregeln, Reitfähigkeit und
|
||
Lizenzen. Instanzen sowie bekannte Flugverbote wie Immersangwald und Geisterlande
|
||
werden ausgeschlossen. Dynamische Schlachtfeldregeln bleiben zur Laufzeit maßgeblich.
|
||
Unbekannte Gebietsmetadaten erlauben lediglich einen Planungsversuch: Beim Start
|
||
entscheiden die normalen Mountfähigkeiten und Zauberprüfungen des Servers.
|
||
Vashj'irs besondere Unterwasserreisen sind nicht enthalten.
|
||
|
||
## Optionale Straßenausstiege und Flug als Rückfall
|
||
|
||
Ein vom Planer vorgeschlagener virtueller Exit ist ein optionaler Anschluss.
|
||
Die Ausführung behält die aufgezeichnete Kante bis zum nächsten regulären Node
|
||
in ihrer gewählten Richtung bei, auch nach einem virtuellen Einstieg mitten auf
|
||
der Kante. Alle sechs Sekunden prüft sie von der aktuellen Position den lokalen
|
||
MMAP-Anschluss zum Reiseziel. Während einer negativen Prüfung läuft die bestehende
|
||
Straßenspline weiter: kein Halt, kein Umdrehen, keine Sperre der Kante und kein
|
||
Verbrauch der fünf Recovery-Versuche. Das gilt auch nach beliebig vielen negativen
|
||
Prüfungen. Nur ein vollständiger Anschluss mit höchstens 500 Yards Pfadlänge und
|
||
höchstens 1,5 Yards Zielabweichung löst den lokalen Ausstieg aus.
|
||
|
||
Scheitert ein bereits gestarteter lokaler Ausstieg, versucht die Ausführung den
|
||
Wiedereinstieg am nächsten noch nicht passierten Straßenpunkt über MMAP. Den
|
||
Fortschritt bestimmt der Index der laufenden Spline, nicht der geometrisch nächste
|
||
Punkt, der auf sich kreuzenden Straßen hinter dem Bot liegen könnte. Ein tatsächlich
|
||
nicht mehr erreichbarer Wiedereinstieg ist dagegen ein Bewegungsfehler und darf
|
||
Recovery auslösen. Ein geplantes Flugziel ab einem virtuellen Exit bleibt eine
|
||
optionale normale Flugalternative mit den üblichen Auswahlregeln.
|
||
|
||
Wird kein Exit nutzbar, erreicht der Bot den regulären Endnode. Erst dort wird die
|
||
Fortsetzung neu geplant; das Erreichen dieses Nodes zählt nicht als Fehlversuch.
|
||
Nach vollständig durchfahrener Kante wird deren erfolglose geometrische
|
||
Ausstiegsannahme für diese Reiserichtung nicht erneut als gesicherte Zieloption
|
||
geplant. Die Kante bleibt befahrbar und bei späteren Durchfahrten werden weiterhin
|
||
Live-Prüfungen durchgeführt. So führen dieselben unbelegten Ausstiegsannahmen
|
||
nicht zu endlosen Rundreisen zwischen den regulären Endnodes.
|
||
Ein angeforderter Intentwechsel kann dort wie an anderen sicheren Nodes stattfinden.
|
||
|
||
Wenn keine reguläre Reise geplant werden kann, eine nutzbare Teilroute endet oder
|
||
die tatsächliche Bewegungs-Recovery ausgeschöpft ist, prüft die Ausführung freien
|
||
Flug zum Ziel auf derselben Karte. Für diesen Rückfall gelten weder die normale
|
||
Mindestdistanz noch Zonenpräferenzen, Straßenkostenvorteile oder die normale
|
||
20.000-Yards-Auswahlschranke. Flugberechtigung, gelernte Flugmounts, native
|
||
Zauberprüfungen, Geometrie, sichere Landung und der Fußweg vom Landeplatz zum Ziel
|
||
bleiben erforderlich. Eine erfolgreich gestartete Rückfalloption wird innerhalb
|
||
derselben Reiseaktion nicht endlos erneut gestartet.
|
||
|
||
Die Diagnoseeinträge heißen `GROUND_EXIT_CHECK`, `GROUND_EXIT_ARRIVED`,
|
||
`FLIGHT_FALLBACK_UNAVAILABLE` und `FLIGHT_FALLBACK_STARTED`.
|
||
|
||
Regressionstests:
|
||
|
||
```bash
|
||
python3 tests/clientless/test_ground_exit_continuation.py
|
||
python3 tests/clientless/test_free_flight_planner.py
|
||
python3 tests/clientless/test_flight_policy.py
|
||
python3 tests/clientless/test_adventure_graph_handover.py
|
||
```
|
||
|
||
Sie führen produktive Methoden mit kontrollierten Bewegungs- und MMAP-Daten aus.
|
||
Unter anderem bleiben bei zwanzig negativen Exitprüfungen Route, Straßenfahrt,
|
||
Richtung, Sperrlisten und Recovery-Zähler erhalten; ein später gültiger Anschluss
|
||
führt zum ursprünglichen Ziel. Das ersetzt keine visuelle Abnahme im Spiel.
|
||
|
||
Prüfstand vom 27.10.2026 für diese Korrektur: Alle 21 Skripte unter
|
||
`tests/clientless/test_*.py` bestanden. Der bestehende Debug-Build wurde mit
|
||
`cmake --build /home/wow_admin/wow_cata_server/build/debug -j10` erfolgreich
|
||
gebaut und über die vorhandene CMake-Installation übernommen. Der frische
|
||
Testserver-Start erreichte `(worldserver-daemon) ready...`; Prozess und Listener
|
||
auf Port 8085 wurden danach bestätigt. Arthorans konkrete Hafen–Tor–Tavernenreise
|
||
ist mit diesem Stand noch nicht im Spiel abgenommen.
|
||
|
||
## Profil und Konfiguration
|
||
|
||
Im `movement`-Abschnitt des Charakterprofils:
|
||
|
||
```lua
|
||
can_free_fly = true,
|
||
flight_mounts = { [32235] = 100 }, -- Zauber-ID: Goldener Greif; Gewicht 100
|
||
```
|
||
|
||
Flugmounts verwenden **gelernte Mountzauber**, im Unterschied zu den bisherigen
|
||
Display-IDs der Bodenmounts. Die Auswahl erfolgt gewichtet nach der Routenwahl.
|
||
Benötigt werden mindestens Expertenreiten (225), ein geeignetes gelerntes Flugtier
|
||
und die native Flugberechtigung. Für Karten 0/1 wird die Flugmeisterlizenz (90267),
|
||
für Nordend Kaltwetterflug (54197) berücksichtigt. Ein Profil allein erteilt keine
|
||
Fähigkeiten. Arthorans Profil enthält den bereits bereitgestellten Greifen.
|
||
|
||
```ini
|
||
Clientless.Flight.Enabled = 1
|
||
Clientless.Flight.Clearance = 60
|
||
Clientless.Flight.MinDistance = 600
|
||
Clientless.Flight.PreferredZones = "210 4197"
|
||
```
|
||
|
||
`Clearance` ist der nominelle Geländeabstand in Yards (begrenzt auf 20–200).
|
||
`MinDistance` gilt außerhalb bevorzugter Zonen, dort mindestens 100 Yards;
|
||
in bevorzugten Zonen sind Flüge ab 60 Yards planbar. Die voreingestellten
|
||
Zonen sind Eiskrone und Tausendwinter; aktuelle Flugverbote gelten weiterhin.
|
||
Konfigurationsänderungen können über `reload config` übernommen werden.
|
||
|
||
## Flugausführung
|
||
|
||
Nach dem normalen Mountzauber wartet die Steuerung auf die tatsächliche native
|
||
Flugfähigkeit. Es gibt keine künstliche Flugfreigabe und keinen Zielteleport.
|
||
Die Bewegung erfolgt in kurzen nativen Flugsplines mit Flugmountgeschwindigkeit.
|
||
Im normalen Flug wird die nächste Spline bis zu 600 ms vor dem Ende der laufenden
|
||
Spline ab der aktuellen Position gestartet. Dadurch entsteht zwischen den
|
||
Abschnitten kein regulärer Halt. Der neue Korridor wird vollständig geprüft;
|
||
Landungen und die konservative Rückkehr über die Flugspur erreichen weiterhin
|
||
ihre Endpunkte. Die Wegstrecke zählt tatsächlich geflogene Bewegung, nicht die
|
||
überlappenden Längen der erteilten Bewegungsaufträge. `status` zeigt mit
|
||
`handoffs` die Anzahl der Übergaben während einer noch laufenden Spline.
|
||
|
||
Die Navigation prüft Gelände und Wasseroberfläche, native maximale Flughöhe,
|
||
VMAP-Geometrie und kollidierbare dynamische GameObjects in der jeweiligen Phase.
|
||
Mehrere versetzte Kollisionsstrahlen approximieren die Körperbreite und -höhe.
|
||
Vorausschau und geglättete Geländehöhe verhindern das Nachfahren jeder kleinen
|
||
Spitze; längere Absenkungen erhalten eine Verzögerung. Höhenänderungen erfolgen
|
||
diagonal. Hindernisse können moderate seitliche Umwege oder zusätzliche Steigung
|
||
auslösen; die maximale Flughöhe bleibt eine harte Grenze.
|
||
|
||
Für Landungen wird fester Boden mit freiem Luftraum gesucht. Ersatzpunkte liegen
|
||
höchstens 20 Yards neben dem Ziel und benötigen einen kurzen vollständigen
|
||
MMAP-Anschluss zum eigentlichen Ziel. Auf Wasser wird nicht gelandet. Nach
|
||
bestätigtem Bodenkontakt endet die Flugsteuerung, gegebenenfalls folgt die lokale
|
||
Bodenstrecke; danach setzt die normale Graph- beziehungsweise Intentlogik fort.
|
||
|
||
## Diagnosebefehle
|
||
|
||
In der Serverkonsole ohne führenden Punkt, ingame mit Punkt:
|
||
|
||
```text
|
||
clientless flight status 26
|
||
clientless flight probe 26 -10100 -600
|
||
clientless flight test_node 26 northshire
|
||
clientless flight abort 26
|
||
```
|
||
|
||
`status` zeigt Zustand, Fortschritt und Fehler; `probe` prüft Gelände und
|
||
Flughöhenbegrenzung auf der aktuellen Karte ohne Bewegung. `test_node` ist ein
|
||
isolierter Ausführungstest zwischen einem tatsächlich erreichten regulären
|
||
Abflugnode und einem regulären Zielnode derselben Karte. Er verlangt einen
|
||
untätigen Bot und ersetzt keinen Test der normalen Reiseplanung.
|
||
|
||
`abort` bricht einen ausstehenden Mountzauber ab oder versucht in der Luft eine
|
||
Rückkehr über die aufgezeichneten, erneut kollisionsgeprüften Flugabschnitte.
|
||
Erst nach der Landung wird abgestiegen. Ist auch die Rückstrecke blockiert,
|
||
stoppt der Bot gemountet und meldet den Fehler; dieser Sonderfall benötigt
|
||
weitere Betreuung. Neue Bodenaktionen werden in der Luft abgelehnt.
|
||
|
||
Das Log `adventurebot-navigation.log` enthält `FLIGHT_START`, `FLIGHT_SEGMENT`,
|
||
`FLIGHT_RETURN`, `FLIGHT_FAILED` und `FLIGHT_LANDED`.
|
||
|
||
## Grenzen und Prüfungen
|
||
|
||
Die erste Umsetzung verwendet begrenzte lokale Vorausschau und einen begrenzten
|
||
Umweg, keinen globalen dreidimensionalen Pfadsolver. Fehlende Geometriedaten
|
||
werden abgelehnt. Komplexe Gebäude, Schluchten und vollständig umschlossene Ziele
|
||
können eine Flugoption scheitern lassen. Spieler und NPC-Körper bilden keine
|
||
zusätzlichen Hindernisse über die native Weltgeometrie hinaus. Schauflüge und
|
||
Tagesroutinen gehören weiterhin in die spätere Verhaltenssteuerung.
|
||
|
||
Automatisierte Prüfungen:
|
||
|
||
```bash
|
||
python3 tests/clientless/test_free_flight.py
|
||
python3 tests/clientless/test_free_flight_planner.py
|
||
python3 tests/clientless/test_flight_policy.py
|
||
python3 tests/clientless/test_flight_handoff.py
|
||
```
|
||
|
||
Sie prüfen die produktive Geometrie und Planungslogik mit kontrollierten Daten:
|
||
Start/Landung, geglättete Spitzen, Flughöhenlimit, seitliches/vertikales Ausweichen,
|
||
fehlende Geometrie, hohen Zielanflug, dynamische Flugoptionen, Straßenpräferenz,
|
||
virtuelle Ausstiege, Flugverbote und Fehlerbehandlung. Build und Servertests
|
||
ersetzen keine abschließende visuelle Abnahme im Spiel.
|
||
|
||
Serverseitige Testbeobachtungen am 26.10.2026 mit Arthoran (GUID 26):
|
||
|
||
- Goldhain → Nordhain und zurück: natives Aufmounten, Flugsegmente und bestätigte Landung.
|
||
- Manueller Abbruch in der Luft: Rückflug entlang der geprüften Spur und Landung am Ausgangspunkt.
|
||
- Reguläres `travel_to_location`: Kombination bestehender Wege mit Flug ab virtuellem Straßenausstieg, Landung und `travel-location-complete`.
|
||
- Ein nicht sicher fortsetzbarer Abflug am Node `taxi_12` führte zu Rückkehr und Neuplanung statt einer erfundenen Ankunft.
|
||
|
||
Das Testziel wurde nur temporär als Worldpoint angelegt. Dafür wurden keine
|
||
Flugnodes oder Flugkanten gespeichert.
|
||
|
||
Der abschließende reguläre Location-Test mit dem verbesserten Anflug endete um
|
||
16:44:19 mit `FLIGHT_LANDED` (32 Segmente, Zielabweichung 0,00) und anschließendem
|
||
`travel-location-complete`. Der Test lief über die normale Reiseaktion und den
|
||
virtuellen Straßenausstieg, nicht über `flight test_node`.
|
||
|
||
## Sichtprüfung und Abschluss
|
||
|
||
Beim beobachteten Flug Goldhain → Nordhain fiel zunächst ein kurzes Anhalten
|
||
zwischen den Abschnitten auf. Die vorzeitige Spline-Übergabe behebt diese Lücke.
|
||
Der anschließende Rückflug Nordhain → Goldhain landete am 26.10.2026 um 18:09:14
|
||
nach 36 Abschnitten mit Zielabweichung 0,00. Das Log bestätigt Übergaben während
|
||
noch laufender Splines. Der Nutzer hat den Flug anschließend ausdrücklich als
|
||
sauber und flüssig bestätigt.
|
||
|
||
Damit ist der Entwicklungsmeilenstein Navigation und Fernreisen einschließlich
|
||
unabhängiger Flugreisen abgenommen. Die oben genannten Grenzen der begrenzten
|
||
Flugnavigation bleiben bestehen; weitere Strecken können schrittweise ergänzt
|
||
und geprüft werden. Mikroaktionen folgen als eigener Entwicklungsschritt.
|