Files
gta6/src/player.js
T

52 lines
3.0 KiB
JavaScript

/**
* Einzige Quelle für "wo ist der Spieler gerade" (Befund A, Fix-Runde 3). main.js trieb
* Streaming, isReadyAt, Auffangnetz, lastSafe und Schattenwurf an sechs Stellen ausnahmslos
* mit player.playerCapsule.position an - das ist falsch, sobald ein Fahrzeug aktiv ist:
* PlayerController.syncMountedPlayer() hängt die Kapsel beim Einsteigen als Kind an
* vehicle.vehicleGroup und überschreibt cap.position mit driverSeatPosition * scale, einer
* festen, kleinen lokalen Zahl nahe dem Ursprung - NICHT der Weltposition. playerCapsule.
* position bleibt also beim Fahren nicht etwa nur stehen, es springt auf einen bedeutungslosen
* Sitzplatz-Offset. Jede Stelle, die "wo ist der Spieler" braucht, muss über playerPosition()
* laufen, sonst hört das Streaming beim Fahren auf nachzuladen.
*/
/**
* getActiveVehicle() allein reicht nicht: VehicleSystem löscht this.active beim Aussteigen
* NICHT (weder exit() noch das stopActive(), das reset() bei aktivem Fahrzeug aufruft, setzen
* es zurück - nur destroy() tut das, beim kompletten Abbau aller Fahrzeuge). getActiveVehicle()
* bleibt also auf dem zuletzt benutzten Fahrzeug stehen, lange nachdem man ausgestiegen ist.
* getControllerMode() === 1 ist das einzige verlässliche "fährt gerade wirklich"-Signal (von
* enter()/exit() korrekt gesetzt) - per Hand im Browser nachgewiesen: nach reset() bei aktivem
* Fahrzeug lieferte getActiveVehicle() weiterhin das verlassene Fahrzeug, obwohl die Kapsel
* schon zurück auf dem Spawnpunkt stand und controllerMode schon wieder 0 war.
*/
export function activeVehicleOrNull(player) {
return player.getControllerMode() === 1 ? player.getActiveVehicle() : null;
}
export function playerPosition(player) {
const vehicle = activeVehicleOrNull(player);
return vehicle ? vehicle.vehicleGroup.position : player.playerCapsule.position;
}
/**
* Echtes Bodensignal für lastSafe, fahrzeugbewusst (Ruling 52 gilt auch im Auto). Zu Fuß
* das vorhandene, raycast-gestützte getIsOnGround(). Im Fahrzeug NICHT dasselbe
* getIsOnGround(): controllerMode 1 (Fahrzeug) läuft nie durch CharacterMovement, das
* einzige, was playerIsOnGround setzt - der Wert bliebe beim Fahren auf dem Zustand von
* kurz vor dem Einsteigen eingefroren (nahezu immer "true", man steigt ja stehend ein) und
* würde lastSafe jeden Frame unbesehen überschreiben, auch wenn das Fahrzeug gerade über
* einer Klippe oder einer noch nicht geladenen Lücke schwebt - exakt das Verhalten, das
* Ruling 52 ("an ein echtes Bodensignal binden statt an die Höhe") verhindern sollte.
* Stattdessen derselbe Radkontakt-Test, den VehicleSystem.finishPhysics() intern für
* "hasWheelContact" benutzt: mindestens ein Rad mit Bodenkontakt.
*/
export function playerIsGrounded(player) {
const vehicle = activeVehicleOrNull(player);
if (!vehicle) return player.getIsOnGround();
const wheels = vehicle.vehicleController;
for (let i = 0; i < wheels.numWheels(); i++) {
if (wheels.wheelIsInContact(i)) return true;
}
return false;
}