287 lines
8.6 KiB
Lua
287 lines
8.6 KiB
Lua
ESX = exports['es_extended']:getSharedObject()
|
|
|
|
local isNuiOpen = false
|
|
local playerLoaded = false
|
|
local isTestDriving = false
|
|
local testDriveVehicle = nil
|
|
|
|
-- PlayerData laden
|
|
Citizen.CreateThread(function()
|
|
local pd = ESX.GetPlayerData()
|
|
if pd and pd.job and pd.job.name then
|
|
ESX.PlayerData = pd
|
|
playerLoaded = true
|
|
end
|
|
end)
|
|
|
|
RegisterNetEvent('esx:playerLoaded')
|
|
AddEventHandler('esx:playerLoaded', function(xPlayer)
|
|
ESX.PlayerData = xPlayer
|
|
playerLoaded = true
|
|
end)
|
|
|
|
RegisterNetEvent('esx:setJob')
|
|
AddEventHandler('esx:setJob', function(job)
|
|
ESX.PlayerData.job = job
|
|
playerLoaded = true
|
|
end)
|
|
|
|
-- =====================
|
|
-- KEYBIND
|
|
-- =====================
|
|
RegisterCommand('openCoinshop', function()
|
|
if isNuiOpen then return end
|
|
OpenCoinshop()
|
|
end, false)
|
|
|
|
RegisterKeyMapping('openCoinshop', Config.KeyBind.description, 'keyboard', Config.KeyBind.key)
|
|
|
|
-- =====================
|
|
-- NUI MANAGEMENT
|
|
-- =====================
|
|
function OpenCoinshop()
|
|
if isNuiOpen then return end
|
|
|
|
ESX.TriggerServerCallback('mercy-coinshop:getShopData', function(data)
|
|
if not data then return end
|
|
|
|
isNuiOpen = true
|
|
SetNuiFocus(true, true)
|
|
SendNUIMessage({
|
|
type = 'open',
|
|
coins = data.coins,
|
|
categories = data.categories,
|
|
theme = Config.Theme,
|
|
locale = Config.Locale,
|
|
confirmPopup = Config.ConfirmPopup,
|
|
isAdmin = data.isAdmin,
|
|
shopName = Config.ShopName,
|
|
logoURL = Config.LogoURL,
|
|
playtimeBonus = data.playtimeBonus,
|
|
tebexEnabled = data.tebexEnabled,
|
|
tebexStoreUrl = Config.Tebex.storeUrl or '',
|
|
testDriveEnabled = Config.TestDrive and Config.TestDrive.enabled or false,
|
|
})
|
|
end)
|
|
end
|
|
|
|
function CloseMenu()
|
|
if not isNuiOpen then return end
|
|
isNuiOpen = false
|
|
SetNuiFocus(false, false)
|
|
SendNUIMessage({ type = 'close' })
|
|
end
|
|
|
|
-- =====================
|
|
-- NUI CALLBACKS
|
|
-- =====================
|
|
RegisterNUICallback('close', function(_, cb)
|
|
CloseMenu()
|
|
cb('ok')
|
|
end)
|
|
|
|
RegisterNUICallback('buyVehicle', function(data, cb)
|
|
TriggerServerEvent('mercy-coinshop:buyVehicle', data.model, data.isWeekly or false)
|
|
cb('ok')
|
|
end)
|
|
|
|
RegisterNUICallback('buyItem', function(data, cb)
|
|
TriggerServerEvent('mercy-coinshop:buyItem', data.categoryId, data.itemIndex)
|
|
cb('ok')
|
|
end)
|
|
|
|
RegisterNUICallback('buyPack', function(data, cb)
|
|
TriggerServerEvent('mercy-coinshop:buyPack', data.categoryId, data.itemIndex)
|
|
cb('ok')
|
|
end)
|
|
|
|
RegisterNUICallback('buyPlate', function(data, cb)
|
|
TriggerServerEvent('mercy-coinshop:buyPlate', data.vehiclePlate, data.newPlate)
|
|
cb('ok')
|
|
end)
|
|
|
|
RegisterNUICallback('redeemCode', function(data, cb)
|
|
ESX.TriggerServerCallback('mercy-coinshop:redeemCode', function(result)
|
|
SendNUIMessage({
|
|
type = 'redeemResult',
|
|
success = result.success,
|
|
message = result.message,
|
|
coins = result.coins,
|
|
})
|
|
end, data.code)
|
|
cb('ok')
|
|
end)
|
|
|
|
RegisterNUICallback('getHistory', function(_, cb)
|
|
ESX.TriggerServerCallback('mercy-coinshop:getHistory', function(history)
|
|
SendNUIMessage({ type = 'updateHistory', history = history })
|
|
end)
|
|
cb('ok')
|
|
end)
|
|
|
|
-- Testfahrt beenden (wiederverwendbar)
|
|
local function EndTestDrive()
|
|
if not isTestDriving then return end
|
|
isTestDriving = false
|
|
end
|
|
|
|
RegisterNUICallback('testDrive', function(data, cb)
|
|
cb('ok')
|
|
if not Config.TestDrive or not Config.TestDrive.enabled then return end
|
|
if isTestDriving then
|
|
TriggerEvent(Config.Notification.event, Config.Notification.title, Config.Locale.testDriveAlready or 'Du bist bereits auf einer Testfahrt!', 'error', Config.Notification.duration)
|
|
return
|
|
end
|
|
|
|
local model = data.model
|
|
if not model then return end
|
|
|
|
CloseMenu()
|
|
isTestDriving = true
|
|
|
|
Citizen.CreateThread(function()
|
|
-- Spieler-Position merken
|
|
local playerPed = PlayerPedId()
|
|
local returnCoords = GetEntityCoords(playerPed)
|
|
local returnHeading = GetEntityHeading(playerPed)
|
|
|
|
-- Model laden
|
|
local modelHash = GetHashKey(model)
|
|
RequestModel(modelHash)
|
|
while not HasModelLoaded(modelHash) do
|
|
Wait(100)
|
|
end
|
|
|
|
-- Spawn-Position
|
|
local spawnCoords = Config.TestDrive.spawnCoords
|
|
local spawnX, spawnY, spawnZ, spawnH = spawnCoords.x, spawnCoords.y, spawnCoords.z, spawnCoords.w
|
|
|
|
-- Spieler teleportieren
|
|
SetEntityCoords(playerPed, spawnX, spawnY, spawnZ, false, false, false, true)
|
|
Wait(1000)
|
|
|
|
-- Fahrzeug spawnen
|
|
local vehicle = CreateVehicle(modelHash, spawnX, spawnY, spawnZ, spawnH, true, false)
|
|
SetModelAsNoLongerNeeded(modelHash)
|
|
testDriveVehicle = vehicle
|
|
|
|
-- Spieler ins Fahrzeug setzen
|
|
TaskWarpPedIntoVehicle(playerPed, vehicle, -1)
|
|
|
|
-- Kennzeichen setzen
|
|
local plate = "TEST" .. tostring(math.random(1000, 9999))
|
|
SetVehicleNumberPlateText(vehicle, plate)
|
|
|
|
-- Keys geben
|
|
TriggerServerEvent("vehicles_keys:selfGiveVehicleKeys", plate)
|
|
|
|
-- Fahrzeug-Extras
|
|
SetVehicleEngineOn(vehicle, true, true, false)
|
|
SetVehicleOnGroundProperly(vehicle)
|
|
|
|
-- Kurz warten damit ESC vom NUI-Schliessen nicht sofort die Testfahrt beendet
|
|
Wait(2000)
|
|
|
|
-- Countdown mit Aussteig- und ESC-Erkennung
|
|
local duration = Config.TestDrive.duration or 60
|
|
local remaining = duration
|
|
local lastSecond = GetGameTimer()
|
|
while remaining > 0 and isTestDriving do
|
|
local ped = PlayerPedId()
|
|
|
|
-- Aussteigen erkennen
|
|
if not IsPedInAnyVehicle(ped, false) then
|
|
break
|
|
end
|
|
|
|
-- ESC (Backspace/200) erkennen
|
|
if IsControlJustPressed(0, 200) then
|
|
break
|
|
end
|
|
|
|
-- HUD-Text anzeigen
|
|
local helpText = string.format("~b~Testfahrt~s~ | ~y~%ds~s~ | ~r~ESC~s~ = Beenden | ~r~Aussteigen~s~ = Beenden", remaining)
|
|
SetTextComponentFormat("STRING")
|
|
AddTextComponentString(helpText)
|
|
DisplayHelpTextFromStringLabel(0, false, true, -1)
|
|
|
|
-- Jede Sekunde runterzaehlen
|
|
if GetGameTimer() - lastSecond >= 1000 then
|
|
remaining = remaining - 1
|
|
lastSecond = GetGameTimer()
|
|
end
|
|
|
|
Wait(0)
|
|
end
|
|
|
|
-- Testfahrt beenden
|
|
isTestDriving = false
|
|
|
|
-- Keys entfernen
|
|
TriggerServerEvent("vehicles_keys:selfRemoveKeys", plate)
|
|
|
|
-- Spieler aus Fahrzeug holen
|
|
local ped = PlayerPedId()
|
|
if IsPedInVehicle(ped, vehicle, false) then
|
|
TaskLeaveVehicle(ped, vehicle, 16)
|
|
Wait(1500)
|
|
end
|
|
|
|
-- Fahrzeug löschen
|
|
if DoesEntityExist(vehicle) then
|
|
DeleteEntity(vehicle)
|
|
end
|
|
testDriveVehicle = nil
|
|
|
|
-- Zurück teleportieren
|
|
Wait(500)
|
|
ped = PlayerPedId()
|
|
SetEntityCoords(ped, returnCoords.x, returnCoords.y, returnCoords.z, false, false, false, true)
|
|
SetEntityHeading(ped, returnHeading)
|
|
|
|
TriggerEvent(Config.Notification.event, Config.Notification.title, Config.Locale.testDriveEnd or 'Testfahrt beendet!', 'info', Config.Notification.duration)
|
|
end)
|
|
end)
|
|
|
|
RegisterNUICallback('getPlayerVehicles', function(_, cb)
|
|
ESX.TriggerServerCallback('mercy-coinshop:getPlayerVehicles', function(vehicles)
|
|
SendNUIMessage({ type = 'updatePlayerVehicles', vehicles = vehicles })
|
|
end)
|
|
cb('ok')
|
|
end)
|
|
|
|
-- =====================
|
|
-- SERVER EVENT HANDLERS
|
|
-- =====================
|
|
RegisterNetEvent('mercy-coinshop:notify')
|
|
AddEventHandler('mercy-coinshop:notify', function(message, nType)
|
|
TriggerEvent(Config.Notification.event, Config.Notification.title, message, nType or 'info', Config.Notification.duration)
|
|
end)
|
|
|
|
RegisterNetEvent('mercy-coinshop:updateCoins')
|
|
AddEventHandler('mercy-coinshop:updateCoins', function(coins)
|
|
if isNuiOpen then
|
|
SendNUIMessage({ type = 'updateCoins', coins = coins })
|
|
end
|
|
end)
|
|
|
|
RegisterNetEvent('mercy-coinshop:purchaseSuccess')
|
|
AddEventHandler('mercy-coinshop:purchaseSuccess', function(model)
|
|
if isNuiOpen then
|
|
SendNUIMessage({ type = 'purchaseSuccess', model = model })
|
|
end
|
|
end)
|
|
|
|
RegisterNetEvent('mercy-coinshop:playtimeReset')
|
|
AddEventHandler('mercy-coinshop:playtimeReset', function()
|
|
if isNuiOpen then
|
|
SendNUIMessage({ type = 'playtimeReset' })
|
|
end
|
|
end)
|
|
|
|
RegisterNetEvent('mercy-coinshop:forceClose')
|
|
AddEventHandler('mercy-coinshop:forceClose', function()
|
|
CloseMenu()
|
|
end)
|
|
|