ESX = exports['es_extended']:getSharedObject() local spawnedPeds = {} local isNuiOpen = false local currentStation = nil -- ===================== -- DRAW TEXT 3D -- ===================== function DrawText3D(x, y, z, text) SetTextScale(0.35, 0.35) SetTextFont(4) SetTextProportional(1) SetTextColour(255, 255, 255, 215) SetTextEntry('STRING') SetTextCentre(true) AddTextComponentString(text) SetDrawOrigin(x, y, z, 0) DrawText(0.0, 0.0) local factor = (string.len(text)) / 370 DrawRect(0.0, 0.0 + 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 100) ClearDrawOrigin() end -- ===================== -- NPC SPAWNING -- ===================== Citizen.CreateThread(function() for stationId, station in pairs(Config.WashStations) do local npc = station.npc local hash = GetHashKey(npc.model) RequestModel(hash) while not HasModelLoaded(hash) do Citizen.Wait(10) end local ped = CreatePed(4, hash, npc.coords.x, npc.coords.y, npc.coords.z - 1.0, npc.coords.w, false, true) SetEntityHeading(ped, npc.coords.w) FreezeEntityPosition(ped, true) SetEntityInvincible(ped, true) SetBlockingOfNonTemporaryEvents(ped, true) if npc.scenario then TaskStartScenarioInPlace(ped, npc.scenario, 0, true) end spawnedPeds[stationId] = ped SetModelAsNoLongerNeeded(hash) end end) AddEventHandler('onResourceStop', function(resourceName) if resourceName ~= GetCurrentResourceName() then return end for _, ped in pairs(spawnedPeds) do if DoesEntityExist(ped) then DeleteEntity(ped) end end end) -- ===================== -- NPC INTERACTION -- ===================== Citizen.CreateThread(function() while true do local sleep = 1000 local playerCoords = GetEntityCoords(PlayerPedId()) local closestStation = nil local closestDist = Config.InteractionDistance + 1 for stationId, station in pairs(Config.WashStations) do local dist = #(playerCoords - vector3(station.npc.coords.x, station.npc.coords.y, station.npc.coords.z)) if dist < closestDist then closestDist = dist closestStation = stationId end end if closestStation and closestDist <= Config.InteractionDistance then sleep = 0 local station = Config.WashStations[closestStation] if not isNuiOpen then local npcCoords = station.npc.coords DrawText3D(npcCoords.x, npcCoords.y, npcCoords.z + 1.0, '[E] ' .. station.label) if IsControlJustReleased(0, 38) then OpenWashMenu(closestStation) end end end Citizen.Wait(sleep) end end) -- ===================== -- NUI MANAGEMENT -- ===================== function OpenWashMenu(stationId) if isNuiOpen then return end currentStation = stationId local station = Config.WashStations[stationId] ESX.TriggerServerCallback('mercyv-wash:getDirtyMoney', function(dirtyAmount) isNuiOpen = true SetNuiFocus(true, true) SendNUIMessage({ type = 'open', stationLabel = station.label, stationId = stationId, dirtyAmount = dirtyAmount, washRate = Config.WashRate, dirtyLabel = Config.DirtyLabel, }) end) end function CloseWashMenu() if not isNuiOpen then return end isNuiOpen = false currentStation = nil SetNuiFocus(false, false) SendNUIMessage({ type = 'close' }) end -- ===================== -- NUI CALLBACKS -- ===================== RegisterNUICallback('close', function(_, cb) CloseWashMenu() cb('ok') end) RegisterNUICallback('wash', function(data, cb) if not currentStation then cb({ success = false }) return end TriggerServerEvent('mercyv-wash:wash', data.amount, currentStation) cb('ok') end) -- ===================== -- SERVER EVENT HANDLERS -- ===================== RegisterNetEvent('mercyv-wash:washResult') AddEventHandler('mercyv-wash:washResult', function(success, message) if success then TriggerEvent('hex_4_hud:notify', 'Geldwaesche', message, 'success', 4000) SendNUIMessage({ type = 'washSuccess' }) -- Refresh dirty money amount if currentStation then ESX.TriggerServerCallback('mercyv-wash:getDirtyMoney', function(dirtyAmount) SendNUIMessage({ type = 'updateAmount', dirtyAmount = dirtyAmount }) end) end else TriggerEvent('hex_4_hud:notify', 'Geldwaesche', message, 'error', 3000) end end)