forked from Simnation/Main
ed
This commit is contained in:
parent
6d22d5f77c
commit
63fbc60a00
86 changed files with 8352 additions and 3428 deletions
954
resources/[Developer]/sn_vehicleKey/client.lua
Normal file
954
resources/[Developer]/sn_vehicleKey/client.lua
Normal file
|
@ -0,0 +1,954 @@
|
|||
-- error when both menus are enabled
|
||||
if (Config.useContextMenu and Config.useNativeUI) then
|
||||
print("^1[ERROR] You can use only one menu or no menu at all. You cannot use both menus."
|
||||
.. "\nMake sure to set at least one to false in the config and to edit the fxmanifest accordingly!")
|
||||
end
|
||||
|
||||
local keymakers = {}
|
||||
|
||||
local lockNotif = nil
|
||||
local createNewKeyNotif = nil
|
||||
|
||||
local LockStatus = {
|
||||
Unlocked = 1,
|
||||
Locked = 2
|
||||
}
|
||||
|
||||
local CB = exports["kimi_callbacks"]
|
||||
|
||||
local menuPoolNativeUI
|
||||
local keymakerMenuNativeUI
|
||||
local keyInvMenuNativeUI
|
||||
if (Config.useNativeUI) then
|
||||
if (NativeUI == nil) then
|
||||
print("^1[ERROR] NativeUI was not properly initialized! Make sure to install NativeUI and start it before this resource!")
|
||||
end
|
||||
|
||||
menuPoolNativeUI = NativeUI.CreatePool()
|
||||
keymakerMenuNativeUI = NativeUI.CreateMenu(Config.Strings.keymakerTitle, Config.Strings.keymakerSub)
|
||||
keyInvMenuNativeUI = NativeUI.CreateMenu(Config.Strings.keyInvTitle, Config.Strings.keyInvSub)
|
||||
end
|
||||
|
||||
local isAtKeymaker = false
|
||||
local menuOpen = false
|
||||
|
||||
-- create client side peds
|
||||
Citizen.CreateThread(function()
|
||||
for i, keymaker in ipairs(Config.Keymakers) do
|
||||
RequestModel(keymaker.model)
|
||||
while not HasModelLoaded(keymaker.model) do
|
||||
Citizen.Wait(0)
|
||||
end
|
||||
local ped = CreatePed(0, keymaker.model, keymaker.pos.x, keymaker.pos.y, keymaker.pos.z, keymaker.pos.w, false, true)
|
||||
|
||||
SetBlockingOfNonTemporaryEvents(ped, true)
|
||||
FreezeEntityPosition(ped, true)
|
||||
SetEntityInvincible(ped, true)
|
||||
|
||||
table.insert(keymakers, ped)
|
||||
|
||||
-- add blip
|
||||
local blip = AddBlipForCoord(keymaker.pos.x, keymaker.pos.y, keymaker.pos.z)
|
||||
|
||||
SetBlipSprite(blip, 134)
|
||||
SetBlipColour(blip, 0)
|
||||
|
||||
SetBlipScale(blip, 1.0)
|
||||
SetBlipDisplay(blip, 2)
|
||||
SetBlipAsShortRange(blip, true)
|
||||
|
||||
BeginTextCommandSetBlipName('STRING')
|
||||
AddTextComponentSubstringPlayerName(Config.Strings.keymaker)
|
||||
EndTextCommandSetBlipName(blip)
|
||||
end
|
||||
end)
|
||||
|
||||
-- main loop
|
||||
Citizen.CreateThread(function()
|
||||
while (true) do
|
||||
Citizen.Wait(0)
|
||||
|
||||
if (Config.useNativeUI) then
|
||||
if (menuOpen) then
|
||||
menuPoolNativeUI:ProcessMenus()
|
||||
end
|
||||
|
||||
if (isAtKeymaker) then
|
||||
if (not menuOpen) then
|
||||
ShowHelpText(Config.Strings.helpText)
|
||||
end
|
||||
|
||||
if (IsControlJustPressed(0, 51)) then
|
||||
if (menuPoolNativeUI:IsAnyMenuOpen()) then
|
||||
menuPoolNativeUI:CloseAllMenus()
|
||||
menuOpen = false
|
||||
else
|
||||
GenerateKeymakerMenuNativeUI()
|
||||
keymakerMenuNativeUI:Visible(true)
|
||||
menuOpen = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if (IsControlJustPressed(0, Config.keyMenuKey)) then
|
||||
if (menuPoolNativeUI:IsAnyMenuOpen()) then
|
||||
menuPoolNativeUI:CloseAllMenus()
|
||||
menuOpen = false
|
||||
else
|
||||
GenerateKeyInventoryNativeUI()
|
||||
keyInvMenuNativeUI:Visible(true)
|
||||
menuOpen = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- lock vehicle with key
|
||||
--[[ if (Config.lockKey and IsControlJustPressed(0, Config.lockKey)) then
|
||||
local vehicle = GetClosestVehicle(GetEntityCoords(PlayerPedId()), 10.0)
|
||||
if (DoesEntityExist(vehicle) and IsVehicleOrKeyOwner(vehicle)) then
|
||||
ToggleLock(vehicle, GetVehicleDoorLockStatus(vehicle) ~= LockStatus.Locked)
|
||||
end
|
||||
end ]]
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
|
||||
-- ContextMenu
|
||||
if (Config.useContextMenu) then
|
||||
local menuPool = MenuPool()
|
||||
menuPool.OnOpenMenu = function(screenPosition, hitSomething, worldPosition, hitEntity, normalDirection)
|
||||
local playerPos = GetEntityCoords(PlayerPedId())
|
||||
if (Vdist(worldPosition.x, worldPosition.y, worldPosition.z, playerPos.x, playerPos.y, playerPos.z) < Config.maxDistance) then
|
||||
CreateMenu(screenPosition, hitEntity)
|
||||
end
|
||||
end
|
||||
|
||||
function CreateMenu(screenPosition, hitEntity)
|
||||
menuPool:Reset()
|
||||
|
||||
if (hitEntity) then
|
||||
if (hitEntity == PlayerPedId()) then
|
||||
local vehicleData = CB:Trigger("VKC:getPlayerVehicleData")
|
||||
local ownedKeys = GetPlayerKeys()
|
||||
|
||||
menuPool:Reset()
|
||||
|
||||
local playerMenu = menuPool:AddMenu()
|
||||
|
||||
local ownVehMenu, ownVehMenuItem = menuPool:AddSubmenu(playerMenu, Config.Strings.CM.masterKeysTitle)
|
||||
for i, vehicle in ipairs(vehicleData) do
|
||||
local plate = vehicle[1]
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicle[2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(vehicle[2])
|
||||
end
|
||||
|
||||
local item = ownVehMenu:AddItem(model .. " " .. plate)
|
||||
end
|
||||
|
||||
local ownKeyMenu, ownKeyMenuItem = menuPool:AddSubmenu(playerMenu, Config.Strings.CM.keysTitle)
|
||||
for i, key in ipairs(ownedKeys) do
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(key.model))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(key.model)
|
||||
end
|
||||
|
||||
local item = ownKeyMenu:AddItem(model .. " " .. key.plate)
|
||||
item.rightText = Text("x" .. key.count)
|
||||
end
|
||||
|
||||
-- Fahrzeugübergabe-Menü hinzufügen
|
||||
local transferVehMenu, transferVehMenuItem = menuPool:AddSubmenu(playerMenu, "Fahrzeug übergeben")
|
||||
for i, vehicle in ipairs(vehicleData) do
|
||||
local plate = vehicle[1]
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicle[2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(vehicle[2])
|
||||
end
|
||||
|
||||
local item = transferVehMenu:AddItem(model .. " " .. plate)
|
||||
item.closeMenuOnClick = true
|
||||
item.OnClick = function()
|
||||
-- Finde den nächsten Spieler
|
||||
local player = GetClosestPlayer(5.0)
|
||||
|
||||
if player then
|
||||
local targetPlayerId = GetPlayerServerId(player)
|
||||
local playerName = GetPlayerName(player)
|
||||
|
||||
local success = CB:Trigger("VKC:transferVehicleOwnership", plate, targetPlayerId)
|
||||
|
||||
if success then
|
||||
Notification(string.format("Du hast dein %s an %s übergeben", model, playerName))
|
||||
else
|
||||
Notification("Übergabe fehlgeschlagen")
|
||||
end
|
||||
else
|
||||
Notification("Kein Spieler in der Nähe gefunden")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
playerMenu:SetPosition(screenPosition)
|
||||
playerMenu:Visible(true)
|
||||
elseif (IsEntityAKeymaker(hitEntity)) then
|
||||
local vehicleData = GetPlayerVehicleData()
|
||||
local ownedKeys = GetPlayerKeys()
|
||||
|
||||
menuPool:Reset()
|
||||
|
||||
local keymakerMenu = menuPool:AddMenu()
|
||||
|
||||
local createKeyMenu, createKeyMenuItem = menuPool:AddSubmenu(keymakerMenu, Config.Strings.CM.createKeyTitle)
|
||||
for i, vehicle in ipairs(vehicleData) do
|
||||
local plate = vehicle[1]
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicle[2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(vehicle[2])
|
||||
end
|
||||
local keyCount = GetKeyCount(plate, ownedKeys)
|
||||
|
||||
local keyItem = createKeyMenu:AddItem(model .. " " .. plate)
|
||||
keyItem.rightText = Text("x" .. tostring(keyCount))
|
||||
keyItem.OnClick = function()
|
||||
local result = CB:Trigger("VKC:createNewKey", plate, 1)
|
||||
if (type(result) == "boolean" and result == true) then
|
||||
Notification(string.format(Config.Strings.createSuccess, model))
|
||||
|
||||
local oldCount = keyItem.rightText.title:gsub("x", "")
|
||||
keyItem.rightText.title = "x" .. tostring(tonumber(oldCount) + 1)
|
||||
elseif (type(result) == "string" and result == "noMoney") then
|
||||
Notification(string.format(Config.Strings.createNoMoney, model))
|
||||
else
|
||||
Notification(string.format(Config.Strings.createFailed, model))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local invalidateKeyMenu, invalidateKeyMenuItem = menuPool:AddSubmenu(keymakerMenu, Config.Strings.CM.invalKeyTitle)
|
||||
for i, vehicle in ipairs(vehicleData) do
|
||||
local plate = vehicle[1]
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicle[2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(vehicle[2])
|
||||
end
|
||||
|
||||
local item = invalidateKeyMenu:AddItem(model .. " " .. plate)
|
||||
item.closeMenuOnClick = true
|
||||
item.OnClick = function()
|
||||
local result = CB:Trigger("VKC:removeAllKeys", plate)
|
||||
if (type(result) == "boolean" and result == true) then
|
||||
Notification(string.format(Config.Strings.deleteKeys, model))
|
||||
elseif (type(result) == "string" and result == "noMoney") then
|
||||
Notification(string.format(Config.Strings.removeNoMoney, vehName))
|
||||
else
|
||||
Notification(string.format(Config.Strings.removeFailed, vehName))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
keymakerMenu:SetPosition(screenPosition)
|
||||
keymakerMenu:Visible(true)
|
||||
elseif (IsEntityAPed(hitEntity) and IsPedAPlayer(hitEntity)) then
|
||||
local ownedKeys = GetPlayerKeys()
|
||||
|
||||
menuPool:Reset()
|
||||
|
||||
local interactMenu = menuPool:AddMenu()
|
||||
|
||||
local giveKeyMenu, giveKeyMenuItem = menuPool:AddSubmenu(interactMenu, Config.Strings.CM.giveKey)
|
||||
for i, key in ipairs(ownedKeys) do
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(key.model))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(key.model)
|
||||
end
|
||||
|
||||
local keyItem = giveKeyMenu:AddItem(model .. " " .. key.plate)
|
||||
keyItem.rightText = Text("x" .. key.count)
|
||||
keyItem.closeMenuOnClick = true
|
||||
keyItem.OnClick = function()
|
||||
local players = GetActivePlayers()
|
||||
for i, player in ipairs(players) do
|
||||
if (GetPlayerPed(player) == hitEntity) then
|
||||
local success = CB:Trigger("VKC:giveKeyToPlayer", key.plate, GetPlayerServerId(player))
|
||||
if (success) then
|
||||
Notification(string.format(Config.Strings.giveSuccess, model))
|
||||
else
|
||||
Notification(string.format(Config.Strings.giveFailed, model))
|
||||
end
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
interactMenu:SetPosition(screenPosition)
|
||||
interactMenu:Visible(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function IsEntityAKeymaker(entity)
|
||||
for i, keymaker in ipairs(keymakers) do
|
||||
if (entity == keymaker) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- NativeUI
|
||||
function GenerateKeymakerMenuNativeUI()
|
||||
keymakerMenuNativeUI:Clear()
|
||||
|
||||
local vehicleData = GetPlayerVehicleData()
|
||||
local ownedKeys = GetPlayerKeys()
|
||||
|
||||
keymakerMenuNativeUI = NativeUI.CreateMenu(Config.Strings.NUI.keymakerMenuTitle, Config.Strings.NUI.keymakerMenuSub)
|
||||
menuPoolNativeUI:Add(keymakerMenuNativeUI)
|
||||
|
||||
local submenuCreateKey = menuPoolNativeUI:AddSubMenu(keymakerMenuNativeUI, Config.Strings.NUI.createKeyTitle, Config.Strings.NUI.createKeyDesc)
|
||||
submenuCreateKey.ParentItem:RightLabel(">")
|
||||
submenuCreateKey.Subtitle.Text._Text = "~b~" .. Config.Strings.NUI.createKeyTitle
|
||||
for i, vehicle in ipairs(vehicleData) do
|
||||
local plate = vehicle[1]
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicle[2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(vehicle[2])
|
||||
end
|
||||
local keyCount = GetKeyCount(plate, ownedKeys)
|
||||
|
||||
local vehItem = NativeUI.CreateItem(model .. " " .. plate, string.format(Config.Strings.NUI.createVehicleKey, model, plate))
|
||||
vehItem:RightLabel("x" .. tostring(keyCount))
|
||||
|
||||
submenuCreateKey:AddItem(vehItem)
|
||||
end
|
||||
submenuCreateKey.OnItemSelect = function(menu, item, index)
|
||||
Citizen.CreateThread(function()
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicleData[index][2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(vehicleData[index][2])
|
||||
end
|
||||
|
||||
local result = CB:Trigger("VKC:createNewKey", vehicleData[index][1], 1)
|
||||
if (type(result) == "boolean" and result == true) then
|
||||
Notification(string.format(Config.Strings.createSuccess, model))
|
||||
|
||||
if (submenuCreateKey:Visible()) then
|
||||
local oldCount = item.Label.Text._Text:gsub("x", "")
|
||||
item:RightLabel("x" .. tostring(tonumber(oldCount) + 1))
|
||||
end
|
||||
elseif (type(result) == "string" and result == "noMoney") then
|
||||
Notification(string.format(Config.Strings.createNoMoney, model))
|
||||
else
|
||||
Notification(string.format(Config.Strings.createFailed, model))
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local submenuInvalidateKey = menuPoolNativeUI:AddSubMenu(keymakerMenuNativeUI, Config.Strings.NUI.invalKeyTitle, Config.Strings.NUI.invalKeyDesc)
|
||||
submenuInvalidateKey.ParentItem:RightLabel(">")
|
||||
submenuInvalidateKey.Subtitle.Text._Text = "~b~" .. Config.Strings.NUI.invalKeyTitle
|
||||
for i, vehicle in ipairs(vehicleData) do
|
||||
local plate = vehicle[1]
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicle[2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(vehicle[2])
|
||||
end
|
||||
|
||||
local keyItem = NativeUI.CreateItem(model .. " " .. plate, string.format(Config.Strings.NUI.invalVehicleKey, model, plate))
|
||||
submenuInvalidateKey:AddItem(keyItem)
|
||||
end
|
||||
submenuInvalidateKey.OnItemSelect = function(menu, item, index)
|
||||
Citizen.CreateThread(function()
|
||||
local result = CB:Trigger("VKC:removeAllKeys", vehicleData[index][1])
|
||||
|
||||
if (type(result) == "boolean" and result == true) then
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicleData[index][2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(vehicleData[index][2])
|
||||
end
|
||||
Notification(string.format(Config.Strings.deleteKeys, model))
|
||||
elseif (type(result) == "string" and result == "noMoney") then
|
||||
Notification(string.format(Config.Strings.removeNoMoney, vehName))
|
||||
else
|
||||
Notification(string.format(Config.Strings.removeFailed, vehName))
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
keymakerMenuNativeUI.OnMenuClosed = function(menu)
|
||||
menuOpen = false
|
||||
end
|
||||
|
||||
menuPoolNativeUI:ControlDisablingEnabled(false)
|
||||
menuPoolNativeUI:MouseControlsEnabled(false)
|
||||
|
||||
menuPoolNativeUI:RefreshIndex()
|
||||
end
|
||||
|
||||
function GenerateKeyInventoryNativeUI()
|
||||
keyInvMenuNativeUI:Clear()
|
||||
|
||||
local vehicleData = GetPlayerVehicleData()
|
||||
local ownedKeys = GetPlayerKeys()
|
||||
|
||||
keyInvMenuNativeUI = NativeUI.CreateMenu(Config.Strings.NUI.keyInventoryTitle, Config.Strings.NUI.keyInventorySub)
|
||||
menuPoolNativeUI:Add(keyInvMenuNativeUI)
|
||||
|
||||
local submenuShowMasterKeys = menuPoolNativeUI:AddSubMenu(keyInvMenuNativeUI, Config.Strings.NUI.masterKeysTitle, Config.Strings.NUI.masterKeysDesc)
|
||||
submenuShowMasterKeys.ParentItem:RightLabel(">")
|
||||
submenuShowMasterKeys.Subtitle.Text._Text = "~b~" .. Config.Strings.NUI.masterKeysTitle
|
||||
for i, vehicle in ipairs(vehicleData) do
|
||||
local plate = vehicle[1]
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicle[2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(vehicle[2])
|
||||
end
|
||||
--local keyCount = GetKeyCount(plate, ownedKeys)
|
||||
|
||||
local vehItem = NativeUI.CreateItem(model .. " " .. plate, "")
|
||||
--vehItem:RightLabel("x" .. tostring(keyCount))
|
||||
submenuShowMasterKeys:AddItem(vehItem)
|
||||
end
|
||||
|
||||
-- Fahrzeugübergabe-Untermenü hinzufügen
|
||||
local submenuTransferVehicle = menuPoolNativeUI:AddSubMenu(keyInvMenuNativeUI, "Fahrzeug übergeben", "Übertrage ein Fahrzeug an einen Spieler in der Nähe")
|
||||
submenuTransferVehicle.ParentItem:RightLabel(">")
|
||||
submenuTransferVehicle.Subtitle.Text._Text = "~b~Fahrzeug übergeben"
|
||||
for i, vehicle in ipairs(vehicleData) do
|
||||
local plate = vehicle[1]
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicle[2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(vehicle[2])
|
||||
end
|
||||
|
||||
local vehItem = NativeUI.CreateItem(model .. " " .. plate, "Wähle dieses Fahrzeug zum Übergeben")
|
||||
submenuTransferVehicle:AddItem(vehItem)
|
||||
end
|
||||
|
||||
submenuTransferVehicle.OnItemSelect = function(menu, item, index)
|
||||
local selectedVehicle = vehicleData[index]
|
||||
local plate = selectedVehicle[1]
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(selectedVehicle[2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(selectedVehicle[2])
|
||||
end
|
||||
|
||||
-- Finde den nächsten Spieler
|
||||
local player = GetClosestPlayer(5.0)
|
||||
|
||||
if player then
|
||||
local targetPlayerId = GetPlayerServerId(player)
|
||||
local playerName = GetPlayerName(player)
|
||||
|
||||
local success = CB:Trigger("VKC:transferVehicleOwnership", plate, targetPlayerId)
|
||||
|
||||
if success then
|
||||
lib.notify({
|
||||
title = "Fahrzeug übergeben",
|
||||
description = "Du hast dein " .. model .. " an " .. playerName .. " übergeben",
|
||||
position = "top",
|
||||
type = "success",
|
||||
icon = "car"
|
||||
})
|
||||
else
|
||||
lib.notify({
|
||||
title = "Fahrzeug übergeben",
|
||||
description = "Übergabe fehlgeschlagen",
|
||||
position = "top",
|
||||
type = "error",
|
||||
icon = "car"
|
||||
})
|
||||
end
|
||||
else
|
||||
lib.notify({
|
||||
title = "Fahrzeug übergeben",
|
||||
description = "Kein Spieler in der Nähe gefunden",
|
||||
position = "top",
|
||||
type = "error",
|
||||
icon = "car"
|
||||
})
|
||||
end
|
||||
|
||||
menuPoolNativeUI:CloseAllMenus()
|
||||
menuOpen = false
|
||||
end
|
||||
|
||||
local submenuShowKeys = menuPoolNativeUI:AddSubMenu(keyInvMenuNativeUI, Config.Strings.NUI.keysTitle, Config.Strings.NUI.keysDesc)
|
||||
submenuShowKeys.ParentItem:RightLabel(">")
|
||||
submenuShowKeys.Subtitle.Text._Text = "~b~" .. Config.Strings.NUI.keysTitle
|
||||
for i, key in ipairs(ownedKeys) do
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(key.model))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(key.model)
|
||||
end
|
||||
|
||||
local submenuKey = menuPoolNativeUI:AddSubMenu(submenuShowKeys, model .. " " .. key.plate, "")
|
||||
submenuKey.ParentItem:RightLabel("x" .. tostring(key.count) .. " >")
|
||||
submenuKey.Subtitle.Text._Text = "~b~" .. model .. " " .. key.plate
|
||||
|
||||
local giveItem = NativeUI.CreateItem(Config.Strings.NUI.giveKeyTitle, Config.Strings.NUI.giveKeyDesc)
|
||||
submenuKey:AddItem(giveItem)
|
||||
|
||||
local removeItem = NativeUI.CreateItem(Config.Strings.NUI.removeKeyTitle, Config.Strings.NUI.removeKeyDesc)
|
||||
submenuKey:AddItem(removeItem)
|
||||
|
||||
submenuKey.OnItemSelect = function(menu, item, index)
|
||||
if (item == giveItem) then
|
||||
Citizen.CreateThread(function()
|
||||
local player = GetClosestPlayer(2.0)
|
||||
if (player) then
|
||||
local success = CB:Trigger("VKC:giveKeyToPlayer", key.plate, GetPlayerServerId(player))
|
||||
if (success) then
|
||||
Notification(string.format(Config.Strings.giveSuccess, key.plate))
|
||||
else
|
||||
Notification(string.format(Config.Strings.giveFailed, key.plate))
|
||||
end
|
||||
else
|
||||
Notification(string.format(Config.Strings.giveFailed, key.plate))
|
||||
end
|
||||
end)
|
||||
elseif (item == removeItem) then
|
||||
Citizen.CreateThread(function()
|
||||
local success = CB:Trigger("VKC:removeKey", key.plate, 1)
|
||||
if (success) then
|
||||
Notification(string.format(Config.Strings.removeSuccess, key.plate))
|
||||
|
||||
if (submenuShowKeys:Visible() or submenuKey:Visible()) then
|
||||
local oldCount = submenuKey.ParentItem.Label.Text._Text:gsub("x", "")
|
||||
oldCount = oldCount:gsub(" >", "")
|
||||
submenuKey.ParentItem:RightLabel("x" .. tostring(tonumber(oldCount) - 1) .. " >")
|
||||
end
|
||||
else
|
||||
Notification(string.format(Config.Strings.removeFailed, key.plate))
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
keyInvMenuNativeUI.OnMenuClosed = function(menu)
|
||||
menuOpen = false
|
||||
end
|
||||
|
||||
menuPoolNativeUI:ControlDisablingEnabled(false)
|
||||
menuPoolNativeUI:MouseControlsEnabled(false)
|
||||
|
||||
menuPoolNativeUI:RefreshIndex()
|
||||
end
|
||||
|
||||
if (Config.useNativeUI) then
|
||||
Citizen.CreateThread(function()
|
||||
while (true) do
|
||||
Citizen.Wait(250)
|
||||
|
||||
isAtKeymaker = false
|
||||
|
||||
local pos = GetEntityCoords(PlayerPedId())
|
||||
for i, keymaker in ipairs(Config.Keymakers) do
|
||||
if (Vdist(pos.x, pos.y, pos.z, keymaker.pos.x, keymaker.pos.y, keymaker.pos.z) < 2.0) then
|
||||
isAtKeymaker = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if (Config.keyMenuCommand) then
|
||||
RegisterCommand(Config.keyMenuCommand, function(source, args, raw)
|
||||
if (menuPoolNativeUI:IsAnyMenuOpen()) then
|
||||
menuPoolNativeUI:CloseAllMenus()
|
||||
end
|
||||
|
||||
GenerateKeyInventoryNativeUI()
|
||||
keyInvMenuNativeUI:Visible(true)
|
||||
menuOpen = true
|
||||
end, false)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- lock vehicle
|
||||
if (Config.lockCommand) then
|
||||
RegisterCommand(Config.lockCommand, function(source, args, raw)
|
||||
local vehicle = GetClosestVehicle(GetEntityCoords(PlayerPedId()), 10.0)
|
||||
if (DoesEntityExist(vehicle) and IsVehicleOrKeyOwner(vehicle)) then
|
||||
ToggleLock(vehicle, GetVehicleDoorLockStatus(vehicle) ~= LockStatus.Locked)
|
||||
end
|
||||
end, false)
|
||||
end
|
||||
|
||||
function ToggleLock(vehicle, lock)
|
||||
local lockStatus = GetVehicleDoorLockStatus(vehicle)
|
||||
|
||||
if (NetworkHasControlOfEntity(vehicle)) then
|
||||
ToggleLockOnVehicle(vehicle, lock)
|
||||
else
|
||||
TriggerServerEvent("VKC:toggleLockNet", NetworkGetNetworkIdFromEntity(vehicle), lock)
|
||||
end
|
||||
|
||||
-- play sound
|
||||
TriggerServerEvent("VKC:playDoorLockSoundNet", NetworkGetNetworkIdFromEntity(vehicle), lock)
|
||||
|
||||
-- play remote animation
|
||||
if (not IsPedInAnyVehicle(PlayerPedId(), false)) then
|
||||
PlayRemoteAnimation()
|
||||
end
|
||||
|
||||
-- show notification
|
||||
--[[
|
||||
if (lockNotif) then
|
||||
RemoveNotification(lockNotif)
|
||||
end
|
||||
lockNotif = Notification(lockStatus == LockStatus.Locked and Config.Strings.unlockNotif or Config.Strings.lockNotif)
|
||||
]]
|
||||
end
|
||||
|
||||
function ToggleLockOnVehicle(vehicle, lock)
|
||||
if (lock) then
|
||||
SetVehicleDoorsShut(vehicle, false)
|
||||
SetVehicleDoorsLocked(vehicle, LockStatus.Locked)
|
||||
--exports['okokNotify']:Alert("Fahrzeug", "Du hast dein Fahrzeug Abgeschlossen", 3000, 'error')
|
||||
lib.notify({
|
||||
title = "Fahrzeug",
|
||||
description = "Du hast dein Fahrzeug Abgeschlossen",
|
||||
position = "top",
|
||||
type = "error",
|
||||
icon = "car"
|
||||
})
|
||||
|
||||
|
||||
SetVehicleLights(vehicle, 2)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 0)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 2)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 0)
|
||||
else
|
||||
SetVehicleDoorsLocked(vehicle, LockStatus.Unlocked)
|
||||
--exports['okokNotify']:Alert("Fahrzeug", "Du hast dein Fahrzeug Aufgeschlossen", 3000, 'success')
|
||||
lib.notify({
|
||||
title = "Fahrzeug",
|
||||
description = "Du hast dein Fahrzeug Aufgeschlossen",
|
||||
position = "top",
|
||||
type = "success",
|
||||
icon = "car"
|
||||
})
|
||||
|
||||
SetVehicleLights(vehicle, 2)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 0)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 2)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 0)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 2)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 0)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 2)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 0)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 2)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 0)
|
||||
end
|
||||
end
|
||||
|
||||
function PlayDoorLockSound(vehicle, lock)
|
||||
if (lock) then
|
||||
PlayVehicleDoorCloseSound(vehicle, 0)
|
||||
else
|
||||
PlayVehicleDoorOpenSound(vehicle, 0)
|
||||
end
|
||||
end
|
||||
|
||||
if (Config.lockCommand or Config.lockKey) then
|
||||
RegisterNetEvent("VKC:toggleLockOnPlayer")
|
||||
AddEventHandler("VKC:toggleLockOnPlayer", function(vehicleNetId, unlocked)
|
||||
local vehicle = NetworkGetEntityFromNetworkId(vehicleNetId)
|
||||
if (DoesEntityExist(vehicle) and NetworkHasControlOfEntity(vehicle)) then
|
||||
local lockStatus = GetVehicleDoorLockStatus(vehicle)
|
||||
ToggleLockOnVehicle(vehicle, unlocked)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent("VKC:playDoorLockSound")
|
||||
AddEventHandler("VKC:playDoorLockSound", function(vehicleNetId, lock)
|
||||
local vehicle = NetworkGetEntityFromNetworkId(vehicleNetId)
|
||||
if (DoesEntityExist(vehicle)) then
|
||||
PlayDoorLockSound(vehicle, lock)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
|
||||
RegisterNetEvent("VKC:giveKeyNotif")
|
||||
AddEventHandler("VKC:giveKeyNotif", function(plate)
|
||||
Notification(string.format(Config.Strings.giveSuccessPly, plate))
|
||||
end)
|
||||
|
||||
-- Ereignis für Fahrzeugübergabe-Benachrichtigung
|
||||
RegisterNetEvent("VKC:vehicleTransferNotif")
|
||||
AddEventHandler("VKC:vehicleTransferNotif", function(plate, model)
|
||||
lib.notify({
|
||||
title = "Fahrzeug erhalten",
|
||||
description = "Du hast ein " .. model .. " mit dem Kennzeichen " .. plate .. " erhalten",
|
||||
position = "top",
|
||||
type = "success",
|
||||
icon = "car"
|
||||
})
|
||||
end)
|
||||
|
||||
|
||||
function IsVehicleOwner(vehicle)
|
||||
if (not DoesEntityExist(vehicle)) then
|
||||
print("^1[ERROR] Parameter \"vehicle\" was nil or vehicle did not exist while triggering export \"IsVehicleOwner\"!")
|
||||
return
|
||||
end
|
||||
|
||||
return CB:Trigger("VKC:isVehicleOwner", GetVehicleNumberPlateText(vehicle))
|
||||
end
|
||||
|
||||
function IsKeyOwner(vehicle)
|
||||
if (not DoesEntityExist(vehicle)) then
|
||||
print("^1[ERROR] Parameter \"vehicle\" was nil or vehicle did not exist while triggering export \"IsKeyOwner\"!")
|
||||
return
|
||||
end
|
||||
|
||||
return CB:Trigger("VKC:isKeyOwner", GetVehicleNumberPlateText(vehicle), GetEntityModel(vehicle))
|
||||
end
|
||||
|
||||
function IsVehicleOrKeyOwner(vehicle)
|
||||
if (not DoesEntityExist(vehicle)) then
|
||||
print("^1[ERROR] Parameter \"vehicle\" was nil or vehicle did not exist while triggering export \"IsVehicleOrKeyOwner\"!")
|
||||
return
|
||||
end
|
||||
|
||||
return CB:Trigger("VKC:isVehicleOrKeyOwner", GetVehicleNumberPlateText(vehicle), GetEntityModel(vehicle))
|
||||
end
|
||||
|
||||
function GetPlayerKeys()
|
||||
return CB:Trigger("VKC:getPlayerKeys")
|
||||
end
|
||||
|
||||
function GetPlayerVehicleData()
|
||||
return CB:Trigger("VKC:getPlayerVehicleData")
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- play lock animation
|
||||
function PlayRemoteAnimation()
|
||||
Citizen.CreateThread(function()
|
||||
RequestModel(keyPropHash)
|
||||
RequestAnimDict("anim@mp_player_intmenu@key_fob@")
|
||||
while (not HasModelLoaded(keyPropHash) and not HasAnimDictLoaded("anim@mp_player_intmenu@key_fob@")) do
|
||||
Citizen.Wait(0)
|
||||
end
|
||||
|
||||
local playerPed = PlayerPedId()
|
||||
local playerPos = GetEntityCoords(playerPed)
|
||||
|
||||
local keyObj = CreateObjectNoOffset(keyPropHash, playerPos.x, playerPos.y, playerPos.z, true, true, false)
|
||||
SetModelAsNoLongerNeeded(keyPropHash)
|
||||
|
||||
local boneIndex = GetEntityBoneIndexByName(playerPed, "IK_R_Hand")
|
||||
local offset = vector3(0.08, 0.025, -0.01)
|
||||
local rotOffset = vector3(0, 70, 140)
|
||||
AttachEntityToEntity(keyObj, playerPed, boneIndex, offset.x, offset.y, offset.z, rotOffset.x, rotOffset.y, rotOffset.z, false, false, true, false, 2, true)
|
||||
|
||||
TaskPlayAnim(playerPed, "anim@mp_player_intmenu@key_fob@", "fob_click_fp", 8.0, 8.0, -1, 48, 1, false, false, false)
|
||||
RemoveAnimDict("anim@mp_player_intmenu@key_fob@")
|
||||
|
||||
Citizen.Wait(1500)
|
||||
|
||||
DeleteEntity(keyObj)
|
||||
end)
|
||||
end
|
||||
|
||||
-- show text in upper left corner
|
||||
function ShowHelpText(text)
|
||||
BeginTextCommandDisplayHelp('STRING')
|
||||
AddTextComponentSubstringPlayerName(text)
|
||||
EndTextCommandDisplayHelp(0, false, true, -1)
|
||||
end
|
||||
|
||||
-- displays a notification and returns its handle
|
||||
function Notification(text)
|
||||
SetNotificationTextEntry('STRING')
|
||||
AddTextComponentSubstringPlayerName(text)
|
||||
return DrawNotification(false, true)
|
||||
end
|
||||
|
||||
-- get key count
|
||||
function GetKeyCount(plate, keyArray)
|
||||
for i, key in ipairs(keyArray) do
|
||||
if (plate == key.plate) then
|
||||
return key.count
|
||||
end
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
-- get all players
|
||||
function GetAllPlayers()
|
||||
local players = {}
|
||||
|
||||
for k, v in ipairs(GetActivePlayers()) do
|
||||
table.insert(players, v)
|
||||
end
|
||||
|
||||
return players
|
||||
end
|
||||
|
||||
-- get the closest player
|
||||
function GetClosestPlayer(maxRange)
|
||||
local playerPed = PlayerPedId()
|
||||
local players = GetAllPlayers()
|
||||
|
||||
local playerCoords = GetEntityCoords(playerPed)
|
||||
|
||||
local closestDistance = maxRange
|
||||
local closestPlayer = nil
|
||||
|
||||
for i=1, #players, 1 do
|
||||
local coords = GetEntityCoords(GetPlayerPed(players[i]))
|
||||
local dist = Vdist(playerCoords.x, playerCoords.y, playerCoords.z, coords.x, coords.y, coords.z)
|
||||
if (dist < closestDistance and players[i] ~= PlayerId()) then
|
||||
closestDistance = dist
|
||||
closestPlayer = players[i]
|
||||
end
|
||||
end
|
||||
|
||||
if (closestPlayer ~= nil and DoesEntityExist(GetPlayerPed(closestPlayer))) then
|
||||
return closestPlayer
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Return closest loaded vehicle entity or nil if no vehicle is found
|
||||
function GetClosestVehicle(position, maxRadius)
|
||||
local vehicles = GetAllVehicles()
|
||||
local dist = maxRadius
|
||||
local closestVehicle = nil
|
||||
|
||||
for i=1, #vehicles, 1 do
|
||||
local vehicleCoords = GetEntityCoords(vehicles[i])
|
||||
local tempDist = Vdist(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z, position.x, position.y, position.z)
|
||||
if (tempDist < dist) then
|
||||
dist = tempDist
|
||||
closestVehicle = vehicles[i]
|
||||
end
|
||||
end
|
||||
|
||||
if (closestVehicle ~= nil and DoesEntityExist(closestVehicle)) then
|
||||
return closestVehicle
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Returns all loaded vehicles on client side
|
||||
function GetAllVehicles()
|
||||
local vehicles = {}
|
||||
|
||||
for vehicle in EnumerateVehicles() do
|
||||
table.insert(vehicles, vehicle)
|
||||
end
|
||||
|
||||
return vehicles
|
||||
end
|
||||
|
||||
-- getting all vehicles
|
||||
function EnumerateVehicles()
|
||||
return EnumerateEntities(FindFirstVehicle, FindNextVehicle, EndFindVehicle)
|
||||
end
|
||||
function EnumerateEntities(initFunc, moveFunc, disposeFunc)
|
||||
return coroutine.wrap(function()
|
||||
local iter, id = initFunc()
|
||||
if not id or id == 0 then
|
||||
disposeFunc(iter)
|
||||
return
|
||||
end
|
||||
|
||||
local enum = {handle = iter, destructor = disposeFunc}
|
||||
setmetatable(enum, entityEnumerator)
|
||||
|
||||
local next = true
|
||||
repeat
|
||||
coroutine.yield(id)
|
||||
next, id = moveFunc(iter)
|
||||
until not next
|
||||
|
||||
enum.destructor, enum.handle = nil, nil
|
||||
disposeFunc(iter)
|
||||
end)
|
||||
end
|
||||
local entityEnumerator = {
|
||||
__gc = function(enum)
|
||||
if enum.destructor and enum.handle then
|
||||
enum.destructor(enum.handle)
|
||||
end
|
||||
enum.destructor = nil
|
||||
enum.handle = nil
|
||||
end
|
||||
}
|
||||
|
||||
--[[
|
||||
RegisterCommand("plate", function(source, args, raw)
|
||||
local vehicle = GetClosestVehicle(GetEntityCoords(PlayerPedId()), 10.0)
|
||||
if (DoesEntityExist(vehicle)) then
|
||||
SetVehicleNumberPlateText(vehicle, args[1])
|
||||
end
|
||||
end, false)
|
||||
]]
|
||||
|
||||
|
||||
RegisterKeyMapping("vehicleLock", "Vehicle Lock", "keyboard", "PAGEUP")
|
||||
RegisterCommand("vehicleLock", function()
|
||||
local vehicle = GetClosestVehicle(GetEntityCoords(PlayerPedId()), 10.0)
|
||||
if (DoesEntityExist(vehicle) and IsVehicleOrKeyOwner(vehicle)) then
|
||||
ToggleLock(vehicle, GetVehicleDoorLockStatus(vehicle) ~= LockStatus.Locked)
|
||||
end
|
||||
end, false)
|
||||
|
||||
-- Integration mit dem Mietfahrzeug-System
|
||||
RegisterNetEvent('vehiclerental:client:checkRentalKeys')
|
||||
AddEventHandler('vehiclerental:client:checkRentalKeys', function()
|
||||
TriggerServerEvent('vehiclerental:server:checkRentalKeys')
|
||||
end)
|
||||
|
||||
-- Überprüfe Mietfahrzeug-Schlüssel beim Öffnen des Schlüssel-Menüs
|
||||
if Config.useNativeUI then
|
||||
-- Speichere die ursprüngliche Funktion
|
||||
local originalGenerateKeyInventoryNativeUI = GenerateKeyInventoryNativeUI
|
||||
|
||||
-- Überschreibe die Funktion
|
||||
GenerateKeyInventoryNativeUI = function()
|
||||
-- Überprüfe Mietfahrzeug-Schlüssel
|
||||
TriggerServerEvent('vehiclerental:server:checkRentalKeys')
|
||||
|
||||
-- Warte kurz, damit die Schlüssel aktualisiert werden können
|
||||
Citizen.Wait(100)
|
||||
|
||||
-- Rufe die ursprüngliche Funktion auf
|
||||
originalGenerateKeyInventoryNativeUI()
|
||||
end
|
||||
end
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue