154 lines
6.2 KiB
Lua
154 lines
6.2 KiB
Lua
-- ============================================================
|
|
-- mercyv-garage | client/admin.lua
|
|
-- Ingame Garage-Editor für Admins
|
|
-- ============================================================
|
|
|
|
local AdminOpen = false
|
|
|
|
-- Server fragt ob Spieler Admin ist und gibt Ergebnis zurück
|
|
local PlayerIsAdmin = false
|
|
RegisterNetEvent('mercyv-garage:setAdminStatus', function(status)
|
|
PlayerIsAdmin = status
|
|
if status then
|
|
SendNUIMessage({ action = "SET_ADMIN", isAdmin = true })
|
|
end
|
|
end)
|
|
|
|
-- Bei Laden einmalig Status anfragen
|
|
AddEventHandler('onClientResourceStart', function(res)
|
|
if res ~= GetCurrentResourceName() then return end
|
|
Citizen.Wait(4000)
|
|
TriggerServerEvent('mercyv-garage:checkAdminStatus')
|
|
end)
|
|
|
|
local function IsLocalAdmin()
|
|
return PlayerIsAdmin or IsAceAllowed(Config.AdminAce)
|
|
end
|
|
|
|
-- ──────────────────────────────────────────────────────────────
|
|
-- Admin-Panel öffnen
|
|
-- ──────────────────────────────────────────────────────────────
|
|
|
|
RegisterCommand('garageadmin', function()
|
|
if not IsLocalAdmin() then
|
|
Config.ClientNotification(Config.Notify.ADMIN_NO_PERM, "error")
|
|
return
|
|
end
|
|
|
|
AdminOpen = true
|
|
GarageIsOpen = true -- Verhindert NPC-Interaction-Loop
|
|
|
|
SetNuiFocus(true, true)
|
|
exports['hex_4_hud']:HideHud(true)
|
|
|
|
SendNUIMessage({
|
|
action = "OPEN_ADMIN",
|
|
})
|
|
|
|
-- Garagen-Liste direkt an NUI senden (Callback in main.lua handled das)
|
|
end, false)
|
|
|
|
-- ──────────────────────────────────────────────────────────────
|
|
-- Admin-Panel schließen (NUI Callback)
|
|
-- ──────────────────────────────────────────────────────────────
|
|
|
|
RegisterNUICallback('closeAdmin', function(data, cb)
|
|
AdminOpen = false
|
|
GarageIsOpen = false
|
|
|
|
-- NUI-Fokus freigeben und Steuerung zurückgeben
|
|
SetNuiFocus(false, false)
|
|
SetNuiFocusKeepInput(false)
|
|
exports['hex_4_hud']:HideHud(false)
|
|
|
|
-- Preview-Fahrzeug löschen falls vorhanden
|
|
if PreviewVeh and DoesEntityExist(PreviewVeh) then
|
|
DeleteEntity(PreviewVeh)
|
|
PreviewVeh = nil
|
|
end
|
|
|
|
CurrentGarage = nil
|
|
cb({})
|
|
end)
|
|
|
|
-- ──────────────────────────────────────────────────────────────
|
|
-- Positions-Erfassung: NUI wird temporär deaktiviert
|
|
-- Spieler geht zur Position, drückt G oder ESC
|
|
-- ──────────────────────────────────────────────────────────────
|
|
|
|
local CaptureActive = false
|
|
local CaptureField = nil
|
|
|
|
RegisterNUICallback('startCapture', function(data, cb)
|
|
CaptureField = data.field
|
|
|
|
-- NUI Fokus temporär aufheben
|
|
SetNuiFocus(false, false)
|
|
CaptureActive = true
|
|
cb({})
|
|
|
|
-- Capture-Thread starten
|
|
Citizen.CreateThread(function()
|
|
-- Warte auf G (drücken zum erfassen) oder ESC (abbrechen)
|
|
while CaptureActive do
|
|
-- On-Screen Anleitung
|
|
SetTextFont(4)
|
|
SetTextScale(0.5, 0.5)
|
|
SetTextColour(255, 255, 255, 255)
|
|
SetTextEntry("STRING")
|
|
AddTextComponentString("~INPUT_CONTEXT~ Position erfassen ~INPUT_FRONTEND_CANCEL~ Abbrechen")
|
|
DrawText(0.35, 0.03)
|
|
|
|
if IsControlJustPressed(0, 38) then -- E / G
|
|
local ped = PlayerPedId()
|
|
local coords = GetEntityCoords(ped)
|
|
local heading = GetEntityHeading(ped)
|
|
|
|
CaptureActive = false
|
|
SetNuiFocus(true, true)
|
|
|
|
SendNUIMessage({
|
|
action = "POSITION_CAPTURED",
|
|
field = CaptureField,
|
|
x = coords.x,
|
|
y = coords.y,
|
|
z = coords.z,
|
|
heading = heading,
|
|
})
|
|
elseif IsControlJustPressed(0, 200) then -- ESC
|
|
CaptureActive = false
|
|
SetNuiFocus(true, true)
|
|
SendNUIMessage({ action = "CAPTURE_CANCELLED", field = CaptureField })
|
|
end
|
|
|
|
Citizen.Wait(0)
|
|
end
|
|
end)
|
|
end)
|
|
|
|
-- ──────────────────────────────────────────────────────────────
|
|
-- Admin: Teleport zu Garage
|
|
-- ──────────────────────────────────────────────────────────────
|
|
|
|
RegisterNUICallback('teleportToGarage', function(data, cb)
|
|
if not IsLocalAdmin() then cb({}); return end
|
|
if data.x and data.y and data.z then
|
|
local ped = PlayerPedId()
|
|
SetEntityCoords(ped, data.x, data.y, data.z + 0.5, false, false, false, false)
|
|
if data.heading then SetEntityHeading(ped, data.heading) end
|
|
end
|
|
cb({})
|
|
end)
|
|
|
|
-- ──────────────────────────────────────────────────────────────
|
|
-- Hilfs-Befehl: Aktuelle Koordinaten ausgeben
|
|
-- ──────────────────────────────────────────────────────────────
|
|
|
|
RegisterCommand('gcoords', function()
|
|
local ped = PlayerPedId()
|
|
local c = GetEntityCoords(ped)
|
|
local h = GetEntityHeading(ped)
|
|
print(string.format("[mercyv-garage] Coords: x=%.4f y=%.4f z=%.4f heading=%.4f", c.x, c.y, c.z, h))
|
|
Config.ClientNotification(string.format("X: %.2f Y: %.2f Z: %.2f H: %.2f", c.x, c.y, c.z, h), "info", 6000)
|
|
end, false)
|