Files
d4rk_divegear/client/light.lua
T
D4rkst3randClaude Opus 5 d2f6e3cd30
Lint / Lint Resource (push) Has been cancelled
feat(light): auf die spieleigene Scuba-Lampe umgestellt
GTA bringt seit v1493 eine eigene Lampe an der Tauchausruestung mit:

    SetEnableScubaGearLight(ped, toggle)   0xEE2476B9EE4A094F
    IsScubaGearLightEnabled(ped)           0x88274C11CF0D866D

Die sitzt an der richtigen Stelle, leuchtet in Blickrichtung und braucht weder
Prop noch Offsets noch einen Draw-Thread. Damit faellt der komplette
DrawSpotLight-Aufbau weg: Kegelwerte, Farbe, Schatten, Distanzfilter,
Lichter-Limit, die bone-relative Richtungsrechnung und das Sortieren der
Kandidaten pro Frame. client/light.lua schrumpft von ~110 auf ~55 Zeilen.

Gefunden ueber wobozkyng/esx_scuba.

- Der Flag ist ein lokaler Ped-Zustand, der Statebag bleibt also. Gesetzt wird
  er per AddStateBagChangeHandler und zusaetzlich alle 500ms nachgezogen, weil
  Peds beim Streaming, Respawn und Model-Wechsel neu erzeugt werden
- Die Lampe haengt an der Scuba-Kleidung (Component 8). Das Outfit wird bewusst
  nicht angefasst; wer sie nicht traegt, bekommt beim Einschalten eine Meldung
  statt stiller Wirkungslosigkeit
- /divelampcheck sagt, ob das aktuelle Outfit eine Lampe hat
- Prop ist jetzt optional und per Default aus

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 08:45:02 +02:00

61 lines
2.2 KiB
Lua

local config = require 'config.client'
-- Tauchlampe über die spieleigene Scuba-Lampe.
--
-- GTA bringt seit v1493 (Cayo Perico) eine eigene Lampe an der Tauchausrüstung mit:
-- SetEnableScubaGearLight(ped, toggle) 0xEE2476B9EE4A094F
-- IsScubaGearLightEnabled(ped) 0x88274C11CF0D866D
--
-- Die sitzt an der richtigen Stelle, leuchtet in Blickrichtung und braucht weder
-- Prop noch Offsets noch einen eigenen Draw-Thread.
--
-- WICHTIG: Die Lampe hängt an der echten Scuba-Kleidung des Peds (Component 8).
-- Trägt der Spieler die nicht, tut die Native nichts - dieses Script fasst das
-- Outfit bewusst nicht an.
--
-- Der Flag ist ein lokaler Ped-Zustand und wird nicht von selbst repliziert.
-- Deshalb wie vorher der Umweg über den Statebag: jeder Client setzt den Flag für
-- jeden Taucher in seiner Nähe selbst.
local STATE_KEY = 'divelight'
--- @param ped number
--- @param enabled boolean
local function applyLight(ped, enabled)
if ped == 0 or not DoesEntityExist(ped) then return end
-- Nur setzen wenn es sich tatsächlich ändert. Die Native ist billig, aber der
-- Aufruf pro Ped und Durchlauf wäre trotzdem unnötig.
if IsScubaGearLightEnabled(ped) == enabled then return end
SetEnableScubaGearLight(ped, enabled)
end
--- Reagiert sofort auf Änderungen, auch von entfernten Spielern.
AddStateBagChangeHandler(STATE_KEY, nil, function(bagName, _, value)
local player = GetPlayerFromStateBagName(bagName)
if player == 0 then return end
applyLight(GetPlayerPed(player), value == true)
end)
--- Der Statebag-Handler allein reicht nicht: Peds werden beim Streaming neu
--- erzeugt, beim Respawn ausgetauscht und beim Model-Wechsel ersetzt - der Flag
--- ist dann wieder weg, ohne dass sich der Statebag geändert hat. Deshalb
--- regelmäßig nachziehen.
CreateThread(function()
while true do
local players = GetActivePlayers()
for i = 1, #players do
local player = players[i]
local state = Player(GetPlayerServerId(player)).state
applyLight(GetPlayerPed(player), state and state[STATE_KEY] == true)
end
Wait(config.lampReconcileIntervalMs)
end
end)