From 10e2278dcb8ccbd0714181f232d4227c61a24068 Mon Sep 17 00:00:00 2001 From: DateFTP <301770276+DateFTP@users.noreply.github.com> Date: Tue, 4 Aug 2026 13:33:57 +0300 Subject: [PATCH] Add licenseplate resource New resource that allows players to set a custom license plate on the vehicle they are driving via an in-game GUI. Commands: - /setplate - open the license plate editor window - /license - alias for /setplate The client validates the plate length (max 8 characters) and sends the new value to the server, which applies it with setVehiclePlateText. --- [gameplay]/licenseplate/client.lua | 89 ++++++++++++++++++++++++++++++ [gameplay]/licenseplate/meta.xml | 7 +++ [gameplay]/licenseplate/server.lua | 26 +++++++++ 3 files changed, 122 insertions(+) create mode 100644 [gameplay]/licenseplate/client.lua create mode 100644 [gameplay]/licenseplate/meta.xml create mode 100644 [gameplay]/licenseplate/server.lua diff --git a/[gameplay]/licenseplate/client.lua b/[gameplay]/licenseplate/client.lua new file mode 100644 index 000000000..758a95871 --- /dev/null +++ b/[gameplay]/licenseplate/client.lua @@ -0,0 +1,89 @@ +local GUI = { + button = {}, + window = {}, + label = {}, + edit = {} +} + +local isWindowOpen = false + +function createLicenseWindow() + if GUI.window[1] then return end + + GUI.window[1] = guiCreateWindow(671, 319, 307, 152, "License plate", false) + guiWindowSetSizable(GUI.window[1], false) + + GUI.edit[1] = guiCreateEdit(13, 46, 284, 44, "", false, GUI.window[1]) + GUI.label[1] = guiCreateLabel(16, 23, 281, 19, "Specify the number you want to install.", false, GUI.window[1]) + guiSetFont(GUI.label[1], "default-bold-small") + + GUI.button[1] = guiCreateButton(9, 104, 129, 38, "Set the number", false, GUI.window[1]) + GUI.button[2] = guiCreateButton(168, 104, 129, 38, "Cancel", false, GUI.window[1]) + + guiSetVisible(GUI.window[1], false) +end + +function showLicenseWindow() + if isWindowOpen then + hideLicenseWindow() + return + end + + if not GUI.window[1] then + createLicenseWindow() + end + guiSetVisible(GUI.window[1], true) + guiSetInputEnabled(true) + guiBringToFront(GUI.window[1]) + guiSetText(GUI.edit[1], "") + isWindowOpen = true +end + +function hideLicenseWindow() + if GUI.window[1] then + guiSetVisible(GUI.window[1], false) + guiSetInputEnabled(false) + isWindowOpen = false + end +end + +addCommandHandler("setplate", showLicenseWindow) +addCommandHandler("license", showLicenseWindow) + +function onClientGUIClick(button, state) + if button ~= "left" or state ~= "up" then return end + local clicked = source + if clicked == GUI.button[1] then + local plate = guiGetText(GUI.edit[1]) + plate = plate:gsub("^%s*(.-)%s*$", "%1") + + if plate == "" then + outputChatBox("Please enter a license plate number.", 255, 0, 0) + return + end + + if #plate > 8 then + outputChatBox("License plate cannot exceed 8 characters.", 255, 0, 0) + return + end + + -- (Optionally – uncomment if necessary) + -- if not string.match(plate, "^[A-Za-z0-9 ]+$") then + -- outputChatBox("License plate contains invalid characters. Use only letters, numbers and spaces.", 255, 0, 0) + -- return + -- end + + local vehicle = getPedOccupiedVehicle(localPlayer) + if not vehicle then + outputChatBox("You are not in a vehicle.", 255, 0, 0) + return + end + + triggerServerEvent("LicensePlate:set", localPlayer, vehicle, plate) + hideLicenseWindow() + + elseif clicked == GUI.button[2] then + hideLicenseWindow() + end +end +addEventHandler("onClientGUIClick", root, onClientGUIClick) \ No newline at end of file diff --git a/[gameplay]/licenseplate/meta.xml b/[gameplay]/licenseplate/meta.xml new file mode 100644 index 000000000..6da65ced2 --- /dev/null +++ b/[gameplay]/licenseplate/meta.xml @@ -0,0 +1,7 @@ + + + +