feat(light): auf die spieleigene Scuba-Lampe umgestellt
Lint / Lint Resource (push) Has been cancelled
Lint / Lint Resource (push) Has been cancelled
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>
This commit is contained in:
@@ -172,44 +172,31 @@ FiveM* umlegbar.
|
|||||||
| Option | Default | Bedeutung |
|
| Option | Default | Bedeutung |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `lampKey` | `'l'` | Vorbelegung |
|
| `lampKey` | `'l'` | Vorbelegung |
|
||||||
| `lampBone` | `12844` | Bone für Prop **und** Licht — derselbe, damit der Strahl aus der Lampe kommt. `28422` = Hand statt Kopf |
|
| `lampReconcileIntervalMs` | `500` | Wie oft der Lampen-Zustand auf die Peds in der Nähe nachgezogen wird |
|
||||||
| `lampProp` | `'prop_cs_police_torch'` | Optik. Ungültiges Model → Warnung im Log, Licht funktioniert trotzdem. `''` = kein Prop |
|
| `lampProp` | `''` | Optionales Prop am Kopf, rein optisch. Die Lampe leuchtet unabhängig davon |
|
||||||
| `lampPropOffset` / `lampPropRotation` | `vec3(0,0,0)` | Sitz des Props am Bone — mit `/divelamp` einstellen |
|
| `lampBone` / `lampPropOffset` / `lampPropRotation` | `12844` / `vec3(0,0,0)` | Sitz des optionalen Props — mit `/divelamp` einstellen |
|
||||||
| `lampOffset` | `vec3(0,0,0)` | Ursprung des Lichtkegels, bone-relativ |
|
|
||||||
| `lampDirection` | `vec3(0, 1, 0)` | Richtung des Kegels, bone-relativ |
|
|
||||||
| `lampColour` | `{255, 250, 235}` | RGB |
|
|
||||||
| `lampDistance` / `lampBrightness` / `lampRoundness` / `lampRadius` / `lampFalloff` | `28/3/0/16/2` | Form des Lichtkegels, Werte aus `d4rk_phone` übernommen |
|
|
||||||
| `lampShadows` | `false` | `true` nutzt `DrawSpotLightWithShadow` — sieht besser aus, kostet aber deutlich Performance |
|
|
||||||
| `lampDrawDistance` | `45.0` | Ab hier werden fremde Lampen nicht mehr gezeichnet |
|
|
||||||
| `lampMaxLights` | `4` | Gleichzeitige Lampen, die nächstgelegenen gewinnen |
|
|
||||||
|
|
||||||
> **Beim Balancing beachten:** `maxDrainPerSecond` (shared) muss über
|
> **Beim Balancing beachten:** `maxDrainPerSecond` (shared) muss über
|
||||||
> `maxDecayFactor` (client) liegen. Sonst hält der Server den ehrlichen Verbrauch
|
> `maxDecayFactor` (client) liegen. Sonst hält der Server den ehrlichen Verbrauch
|
||||||
> in großer Tiefe für Cheat und schreibt Luft zurück.
|
> in großer Tiefe für Cheat und schreibt Luft zurück.
|
||||||
|
|
||||||
## Lampe einstellen
|
## Debug-Befehle
|
||||||
|
|
||||||
Wo Prop und Lichtkegel am Kopf sitzen, hängt daran, wie das Prop-Model selbst
|
Mit `debug = true` in `config/client.lua`:
|
||||||
ausgerichtet ist — das lässt sich nicht am Schreibtisch erraten. Mit
|
|
||||||
`debug = true` in `config/client.lua` gibt es zwei Befehle, die die Werte im
|
|
||||||
laufenden Spiel ändern und die fertige Config-Zeile ins Log schreiben:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
/divelamp <x> <y> <z> <rx> <ry> <rz> Sitz des Lampen-Props
|
/divelampcheck Hat das aktuelle Outfit eine Scuba-Lampe?
|
||||||
/divelight <x> <y> <z> <dx> <dy> <dz> Ursprung und Richtung des Lichtkegels
|
/divelamp <x> <y> <z> <rx> <ry> <rz> Sitz des optionalen Lampen-Props
|
||||||
```
|
```
|
||||||
|
|
||||||
Das Prop wird sofort neu angehängt, das Licht zieht ohne Verzögerung mit — kein
|
`/divelamp` hängt das Prop sofort neu an und schreibt die fertige Config-Zeile ins
|
||||||
Resource-Restart pro Versuch. Sind die Werte gut, die ausgegebenen Zeilen in die
|
Log — kein Resource-Restart pro Versuch. Alternativ mit einem Prop-Attach-Editor
|
||||||
Config übernehmen und `debug` wieder ausschalten.
|
wie [noted_propattacher](https://github.com/NotedDevelopment/noted_propattacher)
|
||||||
|
ausmessen.
|
||||||
|
|
||||||
Alternativ mit einem Prop-Attach-Editor wie
|
> Ein Tauchlampen-Prop gibt es im Basegame nicht. Was es gibt, sind Varianten
|
||||||
[noted_propattacher](https://github.com/NotedDevelopment/noted_propattacher)
|
> derselben Polizei-Taschenlampe: `prop_cs_police_torch`, `prop_police_torch`,
|
||||||
ausmessen: Prop spawnen, mit der Maus an die Stelle ziehen, Werte übernehmen.
|
> `prop_scn_police_torch`. Für die Beleuchtung braucht es das Prop ohnehin nicht.
|
||||||
|
|
||||||
> Im Basegame gibt es **keine** Tauchlampe. `prop_cs_police_torch` ist eine
|
|
||||||
> Polizei-Taschenlampe; Varianten davon sind `prop_police_torch` und
|
|
||||||
> `prop_scn_police_torch`. Wer eine echte Tauchlampe will, braucht ein Custom-Model.
|
|
||||||
|
|
||||||
## Exports
|
## Exports
|
||||||
|
|
||||||
@@ -222,18 +209,31 @@ Gedacht für HUD- und Screenshot-Resources. Zusätzlich folgt das HUD automatisc
|
|||||||
`IsHudHidden()`, greift also bei allem was `DisplayHud(false)` setzt, ohne dass
|
`IsHudHidden()`, greift also bei allem was `DisplayHud(false)` setzt, ohne dass
|
||||||
etwas angebunden werden muss.
|
etwas angebunden werden muss.
|
||||||
|
|
||||||
## Wie die Lampe synchron wird
|
## Wie die Lampe funktioniert
|
||||||
|
|
||||||
Licht ist in GTA nie synchronisiert — `DrawSpotLight` zeichnet nur lokal für den
|
Es wird kein Licht selbst gezeichnet. GTA bringt seit v1493 (Cayo Perico) eine
|
||||||
aktuellen Frame. Der Lampenzustand wird deshalb als Statebag repliziert
|
eigene Lampe an der Tauchausrüstung mit:
|
||||||
(`LocalPlayer.state:set('divelight', …, true)`), und jeder Client zeichnet die
|
|
||||||
Lampen aller Taucher in seiner Nähe selbst.
|
|
||||||
|
|
||||||
Die Richtung kommt aus **zwei bone-relativen Punkten** am Kopf-Bone, nicht aus
|
```lua
|
||||||
`GetEntityForwardVector`: beim Tauchen liegt der Ped waagerecht im Wasser, der
|
SetEnableScubaGearLight(ped, toggle) -- 0xEE2476B9EE4A094F
|
||||||
Entity-Forward würde stur horizontal leuchten. Die Offsets von `GetPedBoneCoords`
|
IsScubaGearLightEnabled(ped) -- 0x88274C11CF0D866D
|
||||||
sind laut Native-Doku *"relative to the bone's rotation"*, die Differenz zweier
|
```
|
||||||
solcher Punkte enthält also den Pitch.
|
|
||||||
|
Die sitzt an der richtigen Stelle, leuchtet in Blickrichtung und braucht weder
|
||||||
|
Prop noch Offsets noch einen Draw-Thread.
|
||||||
|
|
||||||
|
> **Voraussetzung:** Die Lampe hängt an der echten **Scuba-Kleidung** des Peds
|
||||||
|
> (Component 8). Trägt der Spieler die nicht, tut die Native nichts. Diese
|
||||||
|
> Resource fasst das Outfit bewusst **nicht** an — das gehört ins Kleidungs-System.
|
||||||
|
> Beim Einschalten ohne passendes Outfit gibt es eine Meldung statt stiller Wirkungslosigkeit.
|
||||||
|
> Mit `debug = true` sagt `/divelampcheck`, ob das aktuelle Outfit eine Lampe hat.
|
||||||
|
|
||||||
|
Der Flag ist ein **lokaler** Ped-Zustand und wird nicht von selbst repliziert.
|
||||||
|
Deshalb läuft der Zustand über einen Statebag
|
||||||
|
(`LocalPlayer.state:set('divelight', …, true)`), und jeder Client setzt den Flag
|
||||||
|
für die Taucher in seiner Nähe selbst — sofort per `AddStateBagChangeHandler`,
|
||||||
|
plus ein Abgleich alle `lampReconcileIntervalMs`, weil Peds beim Streaming,
|
||||||
|
Respawn und Model-Wechsel neu erzeugt werden und den Flag dabei verlieren.
|
||||||
|
|
||||||
## Entwicklung
|
## Entwicklung
|
||||||
|
|
||||||
|
|||||||
+35
-86
@@ -1,111 +1,60 @@
|
|||||||
local config = require 'config.client'
|
local config = require 'config.client'
|
||||||
|
|
||||||
-- Reiner Renderer: zeichnet die Lampen aller Taucher in der Nähe, gesteuert
|
-- Tauchlampe über die spieleigene Scuba-Lampe.
|
||||||
-- ausschließlich über den replizierten Statebag. Kein gemeinsamer Zustand mit
|
|
||||||
-- client/main.lua - das hier läuft auch für Spieler, deren Ausrüstung wir gar
|
|
||||||
-- nicht kennen.
|
|
||||||
--
|
--
|
||||||
-- Licht ist in GTA nie synchronisiert: DrawSpotLight zeichnet nur lokal, für den
|
-- GTA bringt seit v1493 (Cayo Perico) eine eigene Lampe an der Tauchausrüstung mit:
|
||||||
-- aktuellen Frame. "Gesynct" heißt deshalb, dass jeder Client das Licht jedes
|
-- SetEnableScubaGearLight(ped, toggle) 0xEE2476B9EE4A094F
|
||||||
-- anderen Tauchers selbst zeichnet.
|
-- 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'
|
local STATE_KEY = 'divelight'
|
||||||
|
|
||||||
--- Kandidaten des aktuellen Frames. Wird wiederverwendet statt jedes Frame neu
|
--- @param ped number
|
||||||
--- angelegt, damit der GC bei Dauerbetrieb nichts zu tun bekommt.
|
--- @param enabled boolean
|
||||||
local candidates = {}
|
local function applyLight(ped, enabled)
|
||||||
|
if ped == 0 or not DoesEntityExist(ped) then return end
|
||||||
|
|
||||||
--- Position und Richtung der Lampe eines Peds.
|
-- Nur setzen wenn es sich tatsächlich ändert. Die Native ist billig, aber der
|
||||||
---
|
-- Aufruf pro Ped und Durchlauf wäre trotzdem unnötig.
|
||||||
--- Die Offsets von GetPedBoneCoords sind laut Native-Doku "relative to the bone's
|
if IsScubaGearLightEnabled(ped) == enabled then return end
|
||||||
--- rotation" - zwei bone-relative Punkte ergeben also die echte Blickrichtung
|
|
||||||
--- inklusive Pitch. Genau das wird beim Tauchen gebraucht: der Ped liegt waagerecht
|
|
||||||
--- im Wasser, GetEntityForwardVector würde die Lampe stur horizontal leuchten lassen.
|
|
||||||
local function getLampVectors(ped)
|
|
||||||
local offset = config.lampOffset
|
|
||||||
local direction = config.lampDirection
|
|
||||||
|
|
||||||
local from = GetPedBoneCoords(ped, config.lampBone, offset.x, offset.y, offset.z)
|
SetEnableScubaGearLight(ped, enabled)
|
||||||
local ahead = GetPedBoneCoords(ped, config.lampBone,
|
|
||||||
offset.x + direction.x,
|
|
||||||
offset.y + direction.y,
|
|
||||||
offset.z + direction.z)
|
|
||||||
|
|
||||||
local delta = ahead - from
|
|
||||||
local length = #delta
|
|
||||||
|
|
||||||
if length <= 0 then return end
|
|
||||||
|
|
||||||
return from, delta / length
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function drawLamp(ped)
|
--- Reagiert sofort auf Änderungen, auch von entfernten Spielern.
|
||||||
local from, direction = getLampVectors(ped)
|
AddStateBagChangeHandler(STATE_KEY, nil, function(bagName, _, value)
|
||||||
|
local player = GetPlayerFromStateBagName(bagName)
|
||||||
|
|
||||||
if not from then return end
|
if player == 0 then return end
|
||||||
|
|
||||||
local colour = config.lampColour
|
applyLight(GetPlayerPed(player), value == true)
|
||||||
|
end)
|
||||||
if config.lampShadows then
|
|
||||||
DrawSpotLightWithShadow(from.x, from.y, from.z, direction.x, direction.y, direction.z,
|
|
||||||
colour[1], colour[2], colour[3],
|
|
||||||
config.lampDistance, config.lampBrightness, config.lampRoundness,
|
|
||||||
config.lampRadius, config.lampFalloff, 0)
|
|
||||||
else
|
|
||||||
DrawSpotLight(from.x, from.y, from.z, direction.x, direction.y, direction.z,
|
|
||||||
colour[1], colour[2], colour[3],
|
|
||||||
config.lampDistance, config.lampBrightness, config.lampRoundness,
|
|
||||||
config.lampRadius, config.lampFalloff)
|
|
||||||
end
|
|
||||||
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()
|
CreateThread(function()
|
||||||
while true do
|
while true do
|
||||||
local players = GetActivePlayers()
|
local players = GetActivePlayers()
|
||||||
local myCoords = GetEntityCoords(cache.ped)
|
|
||||||
local count = 0
|
|
||||||
|
|
||||||
for i = 1, #players do
|
for i = 1, #players do
|
||||||
local player = players[i]
|
local player = players[i]
|
||||||
local state = Player(GetPlayerServerId(player)).state
|
local state = Player(GetPlayerServerId(player)).state
|
||||||
|
|
||||||
if state and state[STATE_KEY] then
|
applyLight(GetPlayerPed(player), state and state[STATE_KEY] == true)
|
||||||
local ped = GetPlayerPed(player)
|
|
||||||
|
|
||||||
if ped ~= 0 and DoesEntityExist(ped) then
|
|
||||||
local distance = #(myCoords - GetEntityCoords(ped))
|
|
||||||
|
|
||||||
if distance < config.lampDrawDistance then
|
|
||||||
count += 1
|
|
||||||
local entry = candidates[count]
|
|
||||||
|
|
||||||
if entry then
|
|
||||||
entry.ped, entry.distance = ped, distance
|
|
||||||
else
|
|
||||||
candidates[count] = { ped = ped, distance = distance }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Reste des letzten Frames abschneiden, sonst sortiert table.sort veraltete
|
Wait(config.lampReconcileIntervalMs)
|
||||||
-- Einträge mit und ein alter, näherer Eintrag verdrängt einen echten.
|
|
||||||
for i = #candidates, count + 1, -1 do
|
|
||||||
candidates[i] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Nur sortieren wenn tatsächlich mehr Lampen da sind als gezeichnet werden
|
|
||||||
-- dürfen. DrawSpotLightWithShadow ist teuer, in einer vollen Höhle sonst
|
|
||||||
-- der erstbeste Frame-Killer.
|
|
||||||
if count > config.lampMaxLights then
|
|
||||||
table.sort(candidates, function(a, b) return a.distance < b.distance end)
|
|
||||||
end
|
|
||||||
|
|
||||||
for i = 1, math.min(count, config.lampMaxLights) do
|
|
||||||
drawLamp(candidates[i].ped)
|
|
||||||
end
|
|
||||||
|
|
||||||
Wait(count > 0 and 0 or 300)
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|||||||
+21
-13
@@ -144,12 +144,22 @@ local function attachGear(ped)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- @param state boolean
|
--- @param state boolean
|
||||||
local function setLamp(state)
|
--- @param notifyIfUnavailable boolean? Rückmeldung, wenn das Outfit keine Lampe hat
|
||||||
|
local function setLamp(state, notifyIfUnavailable)
|
||||||
if not currentGear.enabled then state = false end
|
if not currentGear.enabled then state = false end
|
||||||
|
|
||||||
lampOn = state
|
lampOn = state
|
||||||
-- Repliziert: client/light.lua zeichnet daraus die Lampen aller Taucher.
|
-- Repliziert: client/light.lua setzt daraus den Lampen-Flag bei allen Tauchern.
|
||||||
LocalPlayer.state:set('divelight', state, true)
|
LocalPlayer.state:set('divelight', state, true)
|
||||||
|
|
||||||
|
-- Lokal sofort setzen statt auf den Abgleich-Thread zu warten.
|
||||||
|
SetEnableScubaGearLight(cache.ped, state)
|
||||||
|
|
||||||
|
-- Die Spiel-Lampe hängt an der Scuba-Kleidung (Component 8). Fehlt die, tut
|
||||||
|
-- die Native nichts - ohne Hinweis sieht das nach einem kaputten Keybind aus.
|
||||||
|
if state and notifyIfUnavailable and not IsScubaGearLightEnabled(cache.ped) then
|
||||||
|
exports.qbx_core:Notify(locale('error.no_lamp_on_outfit'), 'error')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function isPropIntact(prop)
|
local function isPropIntact(prop)
|
||||||
@@ -532,7 +542,7 @@ lib.addKeybind({
|
|||||||
onPressed = function()
|
onPressed = function()
|
||||||
if not currentGear.enabled then return end
|
if not currentGear.enabled then return end
|
||||||
|
|
||||||
setLamp(not lampOn)
|
setLamp(not lampOn, true)
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -575,17 +585,15 @@ if config.debug then
|
|||||||
lib.print.info(('lampPropOffset = %s,\nlampPropRotation = %s,'):format(fmtVec(offset), fmtVec(rotation)))
|
lib.print.info(('lampPropOffset = %s,\nlampPropRotation = %s,'):format(fmtVec(offset), fmtVec(rotation)))
|
||||||
end, false)
|
end, false)
|
||||||
|
|
||||||
RegisterCommand('divelight', function(_, args)
|
--- Die Spiel-Lampe braucht die Scuba-Kleidung am Ped. Dieser Befehl sagt, ob
|
||||||
local offset, direction = readVec(args, 1), readVec(args, 4)
|
--- das aktuelle Outfit sie überhaupt hat - sonst rätselt man, warum nichts
|
||||||
|
--- leuchtet.
|
||||||
|
RegisterCommand('divelampcheck', function()
|
||||||
|
SetEnableScubaGearLight(cache.ped, true)
|
||||||
|
local works = IsScubaGearLightEnabled(cache.ped)
|
||||||
|
SetEnableScubaGearLight(cache.ped, lampOn)
|
||||||
|
|
||||||
if not offset or not direction then
|
lib.print.info(('Scuba-Lampe am aktuellen Outfit: %s'):format(works and 'ja' or 'nein'))
|
||||||
lib.print.info('/divelight <x> <y> <z> <dx> <dy> <dz> - Ursprung und Richtung des Lichtkegels')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
config.lampOffset, config.lampDirection = offset, direction
|
|
||||||
|
|
||||||
lib.print.info(('lampOffset = %s,\nlampDirection = %s,'):format(fmtVec(offset), fmtVec(direction)))
|
|
||||||
end, false)
|
end, false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+22
-51
@@ -66,58 +66,29 @@ return {
|
|||||||
--- Tastenbelegungen unter "FiveM" umlegen.
|
--- Tastenbelegungen unter "FiveM" umlegen.
|
||||||
lampKey = 'l',
|
lampKey = 'l',
|
||||||
|
|
||||||
--- Bone, an dem Lampe und Licht hängen. Beides derselbe Bone, damit der
|
--- Die Lampe ist die spieleigene Scuba-Lampe (SetEnableScubaGearLight, seit
|
||||||
--- Strahl auch sichtbar aus der Lampe kommt.
|
--- v1493). Sie sitzt an der richtigen Stelle und leuchtet in Blickrichtung -
|
||||||
--- 12844 = Kopf (wie die Maske) - Strahl folgt der Blickrichtung
|
--- deshalb gibt es hier weder Offsets noch Farb- und Kegelwerte.
|
||||||
--- 28422 = Hand (wie das Prop in d4rk_phone) - Handlampe, aber beim
|
---
|
||||||
--- Schwimmen sind die Arme seitlich ausgestreckt, der Kegel
|
--- ACHTUNG: Sie hängt an der echten Scuba-Kleidung des Peds (Component 8).
|
||||||
--- wandert also mit den Schwimmzügen
|
--- Trägt der Spieler die nicht, passiert nichts. Diese Resource fasst das
|
||||||
|
--- Outfit bewusst nicht an - das macht bei Bedarf das Kleidungs-System.
|
||||||
|
|
||||||
|
--- Wie oft der Lampen-Zustand auf die Peds in der Nähe nachgezogen wird (ms).
|
||||||
|
--- Nötig, weil Peds beim Streaming, Respawn und Model-Wechsel neu erzeugt
|
||||||
|
--- werden und den Flag dabei verlieren.
|
||||||
|
lampReconcileIntervalMs = 500,
|
||||||
|
|
||||||
|
--- Optionales Prop am Kopf, rein optisch. Die Lampe leuchtet unabhängig davon.
|
||||||
|
--- Standardmäßig aus, weil die Spiel-Lampe schon an der Ausrüstung sitzt.
|
||||||
|
--- Ein Basegame-Tauchlampen-Prop gibt es nicht; die Polizei-Taschenlampe
|
||||||
|
--- ('prop_cs_police_torch', 'prop_police_torch', 'prop_scn_police_torch')
|
||||||
|
--- passt optisch nur bedingt.
|
||||||
|
lampProp = '',
|
||||||
|
|
||||||
|
--- Bone und Sitz des optionalen Props. 12844 = Kopf (wie die Maske).
|
||||||
|
--- Mit /divelamp im Spiel einstellen statt hier zu raten.
|
||||||
lampBone = 12844,
|
lampBone = 12844,
|
||||||
|
|
||||||
--- Prop am Kopf. Rein optisch - das Licht hängt nicht daran, es wird nur
|
|
||||||
--- vom selben Bone aus gezeichnet. Ist das Model ungültig, leuchtet es
|
|
||||||
--- trotzdem und es gibt eine Warnung im Log.
|
|
||||||
--- Im Basegame gibt es keine Tauchlampe. Alternativen sind Varianten
|
|
||||||
--- derselben Polizei-Lampe: 'prop_police_torch', 'prop_scn_police_torch'.
|
|
||||||
--- Auf '' setzen = gar kein Prop, nur Licht.
|
|
||||||
lampProp = 'prop_cs_police_torch',
|
|
||||||
|
|
||||||
--- Sitz des Props am Bone. Wie in d4rk_phone bewusst auf null: das Prop sitzt
|
|
||||||
--- dann genau im Bone statt auf geratenen Offsets. Beim Kopf-Bone darf ein
|
|
||||||
--- kleiner Versatz nach vorne/seitlich nötig sein, damit die Lampe nicht im
|
|
||||||
--- Schädel steckt - mit /divelamp im Spiel einstellen statt hier zu raten.
|
|
||||||
lampPropOffset = vec3(0.0, 0.0, 0.0),
|
lampPropOffset = vec3(0.0, 0.0, 0.0),
|
||||||
lampPropRotation = vec3(0.0, 0.0, 0.0),
|
lampPropRotation = vec3(0.0, 0.0, 0.0),
|
||||||
|
|
||||||
--- Ursprung des Lichtkegels relativ zum Bone (bone-relativ, nicht Welt).
|
|
||||||
--- Sollte ungefähr dort liegen, wo das Prop sitzt.
|
|
||||||
lampOffset = vec3(0.0, 0.0, 0.0),
|
|
||||||
|
|
||||||
--- Richtung des Lichtkegels, ebenfalls bone-relativ. Leuchtet der Kegel in die
|
|
||||||
--- falsche Richtung, hier die Achse tauschen oder das Vorzeichen drehen -
|
|
||||||
--- welche lokale Achse des Kopf-Bones nach vorne zeigt, hängt am Skelett.
|
|
||||||
lampDirection = vec3(0.0, 1.0, 0.0),
|
|
||||||
|
|
||||||
--- Lichtwerte aus d4rk_phone übernommen - dort im Betrieb erprobt, statt hier
|
|
||||||
--- neu geraten. Leicht warmweiß wie eine echte Taschenlampe.
|
|
||||||
lampColour = { 255, 250, 235 },
|
|
||||||
|
|
||||||
lampDistance = 28.0, -- Reichweite in Metern
|
|
||||||
lampBrightness = 3.0, -- Helligkeit
|
|
||||||
lampRoundness = 0.0, -- Weichzeichnung des Kegelrands
|
|
||||||
lampRadius = 16.0, -- Öffnungswinkel
|
|
||||||
lampFalloff = 2.0, -- Abfall zum Rand hin
|
|
||||||
|
|
||||||
--- Schatten kosten deutlich Performance. d4rk_phone nutzt bewusst das
|
|
||||||
--- schattenlose DrawSpotLight, deshalb hier auch der Default - unter Wasser
|
|
||||||
--- fällt der Unterschied kaum auf, in einer Höhle mit mehreren Tauchern
|
|
||||||
--- dagegen sehr wohl.
|
|
||||||
lampShadows = false,
|
|
||||||
|
|
||||||
--- Ab dieser Entfernung werden fremde Lampen nicht mehr gezeichnet (Meter).
|
|
||||||
lampDrawDistance = 45.0,
|
|
||||||
|
|
||||||
--- Wie viele Lampen gleichzeitig gezeichnet werden. Die nächstgelegenen
|
|
||||||
--- gewinnen. Schützt vor Frame-Einbrüchen bei Gruppentauchgängen.
|
|
||||||
lampMaxLights = 4,
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -6,7 +6,8 @@
|
|||||||
"no_tank": "Du hast keine Tauchflasche zum Auffüllen dabei!",
|
"no_tank": "Du hast keine Tauchflasche zum Auffüllen dabei!",
|
||||||
"tank_empty": "Diese Tauchflasche ist leer!",
|
"tank_empty": "Diese Tauchflasche ist leer!",
|
||||||
"tank_already_full": "Diese Tauchflasche ist bereits voll!",
|
"tank_already_full": "Diese Tauchflasche ist bereits voll!",
|
||||||
"out_of_air": "Deine Luft ist alle! Sofort auftauchen!"
|
"out_of_air": "Deine Luft ist alle! Sofort auftauchen!",
|
||||||
|
"no_lamp_on_outfit": "Deine Tauchausrüstung hat keine Lampe."
|
||||||
},
|
},
|
||||||
"success": {
|
"success": {
|
||||||
"took_out": "Du hast deine Ausrüstung abgelegt!",
|
"took_out": "Du hast deine Ausrüstung abgelegt!",
|
||||||
|
|||||||
+2
-1
@@ -6,7 +6,8 @@
|
|||||||
"no_tank": "You don't have an air tank to refill!",
|
"no_tank": "You don't have an air tank to refill!",
|
||||||
"tank_empty": "This air tank is empty!",
|
"tank_empty": "This air tank is empty!",
|
||||||
"tank_already_full": "This air tank is already full!",
|
"tank_already_full": "This air tank is already full!",
|
||||||
"out_of_air": "You're out of air! Surface now!"
|
"out_of_air": "You're out of air! Surface now!",
|
||||||
|
"no_lamp_on_outfit": "Your diving suit doesn't have a lamp."
|
||||||
},
|
},
|
||||||
"success": {
|
"success": {
|
||||||
"took_out": "You've taken your gear off!",
|
"took_out": "You've taken your gear off!",
|
||||||
|
|||||||
Reference in New Issue
Block a user