fix(client): Ausruestung verschwindet nicht mehr bei Animationen
Lint / Lint Resource (push) Has been cancelled

Die Props waren soft-pinned angehaengt (useSoftPinning = true), wodurch die
Physik-Engine die Attachment bei Ragdoll und harten Anim-Uebergaengen loesen
darf. Dazu kam, dass ein Ped-Model-Wechsel und aufraeumende Fremd-Scripts
(Emotes, Handcuffs) gar nicht abgefangen wurden.

- attachProp() Helper mit harter Attachment (useSoftPinning = false)
- Watchdog-Thread prueft jede Sekunde, ob beide Props noch am aktuellen Ped
  haengen, und haengt sie sonst neu an
- Scuba-Flags werden im Watchdog neu gesetzt, weil das Spiel sie bei Respawn
  und Fahrzeugausstieg zuruecksetzt
- lib.onCache('ped') haengt die Props nach einem Model-Wechsel neu an
- Ausruestung wird beim Tod abgenommen (removeGearOnDeath, default true)
- removeGear() als gemeinsamer Teardown fuer Ablegen, leere Flasche und Tod
- onResourceStop raeumt Props und Scuba-Flags auf
- maxTimeUnderwater / maxTimeUnderwaterOutOfAir statt Magic Numbers

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-10 23:24:39 +02:00
co-authored by Claude Opus 5
parent c6b35ebe28
commit 921d9c89c8
3 changed files with 147 additions and 54 deletions
+18 -13
View File
@@ -34,21 +34,26 @@ Reihenfolge ist bewusst gewählt: Phase 1 und 2 sind Fundament, Phase 35 baue
Zuerst, weil kleinster Aufwand, echter Bug, und die Taschenlampe dieselbe
Attach-Logik nutzt.
- [ ] `attachGear()` auf harte Attachment umstellen: `useSoftPinning = false`,
`p9 = false`, `fixedRot = true`
- [ ] `isGearIntact()` Helper: `DoesEntityExist` + `GetEntityAttachedTo(...) == cache.ped`
- [x] `attachGear()` auf harte Attachment umstellen: `useSoftPinning = false`,
`p9 = false`, `fixedRot = true` — ausgelagert in einen `attachProp()`-Helper,
den Phase 5 für die Lampe mitbenutzt
- [x] `isGearIntact()` Helper: `DoesEntityExist` + `GetEntityAttachedTo(...) == cache.ped`
für beide Props
- [ ] Watchdog-Thread (1000 ms) solange `currentGear.enabled`: bei Defekt
`deleteGear()` + `attachGear()`, und `enableScuba()` unbedingt neu setzen
(`SetEnableScuba`/`SetPedMaxTimeUnderwater` werden bei Respawn/Fahrzeugausstieg
vom Spiel zurückgesetzt)
- [ ] `lib.onCache('ped', ...)` → bei Model-Wechsel (Kleiderladen, Skin-Change)
- [x] Watchdog-Thread (`gearWatchdogIntervalMs`, default 1000 ms) solange
`currentGear.enabled`: bei Defekt `deleteGear()` + `attachGear()`, und
`enableScuba()` neu setzen (`SetEnableScuba`/`SetPedMaxTimeUnderwater` werden bei
Respawn/Fahrzeugausstieg vom Spiel zurückgesetzt)
- [x] `lib.onCache('ped', ...)` → bei Model-Wechsel (Kleiderladen, Skin-Change)
Props neu anhängen, Scuba-State neu setzen
- [ ] Death-Handler: beim Tod Gear sofort ablegen (ohne Progressbar), Restluft
vorher sichern — Flasche bleibt im Inventar
- [ ] Inkonsistenz aufräumen: `takeOffSuit()` setzt `SetPedMaxTimeUnderwater(ped, 50.0)`,
`disableScuba()` setzt `1.0` — einen Wert festlegen
- [ ] `onResourceStop` Cleanup-Handler für Props
- [x] Death-Handler: `IsPedDeadOrDying`-Check im Watchdog statt eigenem Event —
keine Abhängigkeit zu qbx_medical o.ä. Sichern der Restluft kommt in Phase 2 dazu
- [x] Gemeinsamer `removeGear(outOfAir)`-Teardown für Ablegen, leere Flasche und Tod
- [x] `onResourceStop` Cleanup-Handler für Props
**Zu `SetPedMaxTimeUnderwater`:** war doch kein Bug. Die `50.0` beim Ablegen und die
`1.0` bei leerer Flasche sind zwei verschiedene Absichten (normal weiterschwimmen vs.
ohne Luft absaufen). Beide Werte sind jetzt als `maxTimeUnderwater` /
`maxTimeUnderwaterOutOfAir` in der Config statt als Magic Number im Code.
### Phase 2 — Sauerstoff-Logik neu (~1 h)