diff --git a/mercyv-bike/client/main.lua b/mercyv-bike/client/main.lua
index 536b456..fcbec01 100644
--- a/mercyv-bike/client/main.lua
+++ b/mercyv-bike/client/main.lua
@@ -136,33 +136,30 @@ end)
-- Admin: Aktuelle Position erfassen
RegisterNUICallback('capturePos', function(data, cb)
+ local field = data.field or 'npc'
ClosePanel()
Citizen.Wait(300)
- local ped = PlayerPedId()
- local coords = GetEntityCoords(ped)
- local heading = GetEntityHeading(ped)
- Notify("Geh zur NPC-Position und drücke E.", "info")
+ Notify("Geh zur Position und drücke E.", "info")
exports['hex_4_hud']:ShowHelpNotify("Position erfassen", "E")
Citizen.CreateThread(function()
while true do
Citizen.Wait(0)
- if IsControlJustPressed(0, 38) then -- E
+ if IsControlJustPressed(0, 38) then
exports['hex_4_hud']:HideHelpNotify()
- local c = GetEntityCoords(PlayerPedId())
- local h = GetEntityHeading(PlayerPedId())
- -- Panel wieder öffnen mit erfassten Koordinaten
+ local coords = GetEntityCoords(PlayerPedId())
+ local heading = GetEntityHeading(PlayerPedId())
SetNuiFocus(true, true)
exports['hex_4_hud']:HideHud(true)
PanelOpen = true
SendNUIMessage({
action = "OPEN_ADMIN",
isAdmin = IsAdmin,
- captured = { x = c.x, y = c.y, z = c.z, heading = h },
+ captured = { x = coords.x, y = coords.y, z = coords.z, heading = heading, field = field },
})
break
- elseif IsControlJustPressed(0, 322) then -- ESC
+ elseif IsControlJustPressed(0, 322) then
exports['hex_4_hud']:HideHelpNotify()
OpenPanel()
break
@@ -218,27 +215,47 @@ end)
-- ── Fahrrad spawnen ────────────────────────────────────────────
-RegisterNetEvent('mercyv-bike:doSpawn', function(bikeModel)
+RegisterNetEvent('mercyv-bike:doSpawn', function(bikeModel, spawnData)
+ print('[mercyv-bike] Spawne Fahrrad: ' .. tostring(bikeModel))
+
local model = GetHashKey(bikeModel)
+ if model == 0 then
+ Notify("Unbekanntes Fahrrad-Modell: " .. tostring(bikeModel), "error")
+ return
+ end
+
RequestModel(model)
- local t = GetGameTimer() + 5000
+ local t = GetGameTimer() + 8000
while not HasModelLoaded(model) do
if GetGameTimer() > t then
- Notify("Fahrrad konnte nicht gespawnt werden.", "error")
+ Notify("Fahrrad-Modell konnte nicht geladen werden.", "error")
return
end
Citizen.Wait(100)
end
- local ped = PlayerPedId()
- local coords = GetEntityCoords(ped)
- local heading = GetEntityHeading(ped)
- local rad = math.rad(heading)
- local spawnX = coords.x + math.sin(-rad) * Config.SpawnOffset
- local spawnY = coords.y + math.cos(-rad) * Config.SpawnOffset
+ -- Spawn-Position: vom Server gesetzte Koordinaten oder vor Spieler
+ local sx, sy, sz, sh
+ if spawnData and spawnData.x and spawnData.x ~= 0 then
+ sx = spawnData.x
+ sy = spawnData.y
+ sz = spawnData.z
+ sh = spawnData.heading or 0
+ else
+ local ped = PlayerPedId()
+ local coords = GetEntityCoords(ped)
+ local heading = GetEntityHeading(ped)
+ local rad = math.rad(heading)
+ sx = coords.x + math.sin(-rad) * Config.SpawnOffset
+ sy = coords.y + math.cos(-rad) * Config.SpawnOffset
+ sz = coords.z
+ sh = heading
+ end
- local bike = CreateVehicle(model, spawnX, spawnY, coords.z, heading, true, false)
- local tw = GetGameTimer() + 3000
+ print(string.format('[mercyv-bike] Spawn bei %.1f, %.1f, %.1f', sx, sy, sz))
+
+ local bike = CreateVehicle(model, sx, sy, sz, sh, true, false)
+ local tw = GetGameTimer() + 4000
while not DoesEntityExist(bike) do
if GetGameTimer() > tw then break end
Citizen.Wait(100)
@@ -248,12 +265,11 @@ RegisterNetEvent('mercyv-bike:doSpawn', function(bikeModel)
SetEntityAsMissionEntity(bike, true, true)
SetVehicleEngineOn(bike, true, true, false)
SetModelAsNoLongerNeeded(model)
- -- Schlüssel geben
- local ks = Config.VehicleKeySystem
- if ks == 'jaksam' then
- TriggerServerEvent('vehicles_keys:selfGiveVehicleKeys',
- GetVehicleNumberPlateText(bike))
- end
+ TriggerServerEvent('vehicles_keys:selfGiveVehicleKeys', GetVehicleNumberPlateText(bike))
+ Notify("Fahrrad erhalten! Viel Spaß!", "success")
+ print('[mercyv-bike] Fahrrad erfolgreich gespawnt.')
+ else
+ Notify("Fahrrad konnte nicht gespawnt werden.", "error")
end
end)
diff --git a/mercyv-bike/nui/index.html b/mercyv-bike/nui/index.html
index 8ef3ea0..e5d5868 100644
--- a/mercyv-bike/nui/index.html
+++ b/mercyv-bike/nui/index.html
@@ -285,8 +285,21 @@ body {
+
+
Fahrrad Spawn-Position
+
+
+
+
+
+
+
+
+
@@ -358,7 +371,10 @@ var app = new Vue({
postNUI('close');
},
capturePos: function() {
- postNUI('capturePos', {});
+ postNUI('capturePos', { field: 'npc' });
+ },
+ captureSpawn: function() {
+ postNUI('capturePos', { field: 'spawn' });
},
saveNPC: function() {
postNUI('saveNPC', {
@@ -387,10 +403,17 @@ window.addEventListener('message', function(event) {
app.showAdmin = true;
app.isAdmin = true;
if (msg.captured) {
- app.npc.x = Math.round(msg.captured.x * 100) / 100;
- app.npc.y = Math.round(msg.captured.y * 100) / 100;
- app.npc.z = Math.round(msg.captured.z * 100) / 100;
- app.npc.heading = Math.round(msg.captured.heading * 100) / 100;
+ var rx = Math.round(msg.captured.x * 100) / 100;
+ var ry = Math.round(msg.captured.y * 100) / 100;
+ var rz = Math.round(msg.captured.z * 100) / 100;
+ var rh = Math.round(msg.captured.heading * 100) / 100;
+ if (msg.captured.field === 'spawn') {
+ app.npc.spawn_x = rx; app.npc.spawn_y = ry;
+ app.npc.spawn_z = rz; app.npc.spawn_heading = rh;
+ } else {
+ app.npc.x = rx; app.npc.y = ry;
+ app.npc.z = rz; app.npc.heading = rh;
+ }
}
break;
case 'CLOSE':
diff --git a/mercyv-bike/server/main.lua b/mercyv-bike/server/main.lua
index f14adb4..223f88a 100644
--- a/mercyv-bike/server/main.lua
+++ b/mercyv-bike/server/main.lua
@@ -45,7 +45,8 @@ end)
-- ── NPC-Position synchronisieren ──────────────────────────────
-local NPCData = nil -- wird aus DB oder Config geladen
+local NPCData = nil
+local SpawnData = nil -- separate Spawn-Position für Fahrräder
AddEventHandler('onResourceStart', function(res)
if res ~= GetCurrentResourceName() then return end
@@ -53,18 +54,25 @@ AddEventHandler('onResourceStart', function(res)
-- Tabelle ZUERST anlegen
MySQL.query.await([[
CREATE TABLE IF NOT EXISTS `mercyv_bike_npc` (
- `id` INT AUTO_INCREMENT PRIMARY KEY,
- `model` VARCHAR(100) DEFAULT 'a_m_m_beach_01',
- `x` FLOAT DEFAULT 0,
- `y` FLOAT DEFAULT 0,
- `z` FLOAT DEFAULT 0,
- `heading` FLOAT DEFAULT 0
+ `id` INT AUTO_INCREMENT PRIMARY KEY,
+ `model` VARCHAR(100) DEFAULT 'a_m_m_beach_01',
+ `x` FLOAT DEFAULT 0,
+ `y` FLOAT DEFAULT 0,
+ `z` FLOAT DEFAULT 0,
+ `heading` FLOAT DEFAULT 0,
+ `spawn_x` FLOAT DEFAULT 0,
+ `spawn_y` FLOAT DEFAULT 0,
+ `spawn_z` FLOAT DEFAULT 0,
+ `spawn_heading` FLOAT DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
]])
-- Dann lesen
local r = MySQL.query.await("SELECT * FROM mercyv_bike_npc LIMIT 1")
if r and r[1] then
NPCData = r[1]
+ if r[1].spawn_x and r[1].spawn_x ~= 0 then
+ SpawnData = { x = r[1].spawn_x, y = r[1].spawn_y, z = r[1].spawn_z, heading = r[1].spawn_heading or 0 }
+ end
else
NPCData = {
model = Config.NPC.model,
@@ -117,7 +125,7 @@ RegisterNetEvent('mercyv-bike:claim', function(bikeModel)
)
-- Spawn-Signal
- TriggerClientEvent('mercyv-bike:doSpawn', src, bikeModel)
+ TriggerClientEvent('mercyv-bike:doSpawn', src, bikeModel, SpawnData)
Config.ServerNotification(src, Config.Notify.CLAIMED, "success")
print(string.format('[mercyv-bike] %s hat %s erhalten.', identifier, bikeModel))
end)
@@ -148,15 +156,22 @@ RegisterNetEvent('mercyv-bike:saveNPC', function(data)
end
NPCData = data
+ if data.spawn_x and data.spawn_x ~= 0 then
+ SpawnData = { x = data.spawn_x, y = data.spawn_y, z = data.spawn_z, heading = data.spawn_heading or 0 }
+ end
-- In DB speichern
local existing = MySQL.query.await('SELECT id FROM mercyv_bike_npc LIMIT 1')
+ local sx = data.spawn_x or 0
+ local sy = data.spawn_y or 0
+ local sz = data.spawn_z or 0
+ local sh = data.spawn_heading or 0
if existing and existing[1] then
- MySQL.update('UPDATE mercyv_bike_npc SET model=?, x=?, y=?, z=?, heading=? WHERE id=?',
- { data.model, data.x, data.y, data.z, data.heading, existing[1].id })
+ MySQL.update('UPDATE mercyv_bike_npc SET model=?, x=?, y=?, z=?, heading=?, spawn_x=?, spawn_y=?, spawn_z=?, spawn_heading=? WHERE id=?',
+ { data.model, data.x, data.y, data.z, data.heading, sx, sy, sz, sh, existing[1].id })
else
- MySQL.insert('INSERT INTO mercyv_bike_npc (model, x, y, z, heading) VALUES (?, ?, ?, ?, ?)',
- { data.model, data.x, data.y, data.z, data.heading })
+ MySQL.insert('INSERT INTO mercyv_bike_npc (model, x, y, z, heading, spawn_x, spawn_y, spawn_z, spawn_heading) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)',
+ { data.model, data.x, data.y, data.z, data.heading, sx, sy, sz, sh })
end
TriggerClientEvent('mercyv-bike:syncNPC', -1, NPCData)
diff --git a/mercyv-deathscreen/client/main.lua b/mercyv-deathscreen/client/main.lua
index 8a950f9..01d5f19 100644
--- a/mercyv-deathscreen/client/main.lua
+++ b/mercyv-deathscreen/client/main.lua
@@ -703,7 +703,7 @@ AddEventHandler('mercyv-deathscreen:client:npcReviveTeleport', function()
local ped = PlayerPedId()
-- Kurz warten, damit der Spieler nach dem Revive sicher am Leben ist
- Wait(500)
+ Wait(200)
-- Bildschirm langsam schwarz ausblenden (Dauer: 1000 Millisekunden = 1 Sekunde)
DoScreenFadeOut(1000)