diff --git a/client/events.lua b/client/events.lua index f08e0195e..c49c45cf5 100644 --- a/client/events.lua +++ b/client/events.lua @@ -163,7 +163,7 @@ RegisterNetEvent('QBCore:Client:VehicleInfo', function(info) local plate = QBCore.Functions.GetPlate(info.vehicle) local hasKeys = true - if GetResourceState('qb-vehiclekeys') == 'started' then + if GetResourceState('qb-vehiclekeys') == 'started' or GetResourceState('qb-vehiclekeys') == 'starting' then -- qb-vehiclekeys starting AFTER qb-core hasKeys = exports['qb-vehiclekeys']:HasKeys(plate) end diff --git a/events.lua b/events.lua new file mode 100644 index 000000000..c49c45cf5 --- /dev/null +++ b/events.lua @@ -0,0 +1,279 @@ +-- Player load and unload handling +-- New method for checking if logged in across all scripts (optional) +-- if LocalPlayer.state['isLoggedIn'] then +RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() + ShutdownLoadingScreenNui() + LocalPlayer.state:set('isLoggedIn', true, false) + if not QBCore.Config.Server.PVP then return end + SetCanAttackFriendly(PlayerPedId(), true, false) + NetworkSetFriendlyFireOption(true) +end) + +RegisterNetEvent('QBCore:Client:OnPlayerUnload', function() + LocalPlayer.state:set('isLoggedIn', false, false) +end) + +RegisterNetEvent('QBCore:Client:PvpHasToggled', function(pvp_state) + SetCanAttackFriendly(PlayerPedId(), pvp_state, false) + NetworkSetFriendlyFireOption(pvp_state) +end) +-- Teleport Commands + +RegisterNetEvent('QBCore:Command:TeleportToPlayer', function(coords) + local ped = PlayerPedId() + SetPedCoordsKeepVehicle(ped, coords.x, coords.y, coords.z) +end) + +RegisterNetEvent('QBCore:Command:TeleportToCoords', function(x, y, z, h) + local ped = PlayerPedId() + SetPedCoordsKeepVehicle(ped, x, y, z) + SetEntityHeading(ped, h or GetEntityHeading(ped)) +end) + +RegisterNetEvent('QBCore:Command:GoToMarker', function() + local PlayerPedId = PlayerPedId + local GetEntityCoords = GetEntityCoords + local GetGroundZFor_3dCoord = GetGroundZFor_3dCoord + + local blipMarker = GetFirstBlipInfoId(8) + if not DoesBlipExist(blipMarker) then + QBCore.Functions.Notify(Lang:t('error.no_waypoint'), 'error', 5000) + return 'marker' + end + + -- Fade screen to hide how clients get teleported. + DoScreenFadeOut(650) + while not IsScreenFadedOut() do + Wait(0) + end + + local ped, coords = PlayerPedId(), GetBlipInfoIdCoord(blipMarker) + local vehicle = GetVehiclePedIsIn(ped, false) + local oldCoords = GetEntityCoords(ped) + + -- Unpack coords instead of having to unpack them while iterating. + -- 825.0 seems to be the max a player can reach while 0.0 being the lowest. + local x, y, groundZ, Z_START = coords['x'], coords['y'], 850.0, 950.0 + local found = false + if vehicle > 0 then + FreezeEntityPosition(vehicle, true) + else + FreezeEntityPosition(ped, true) + end + + for i = Z_START, 0, -25.0 do + local z = i + if (i % 2) ~= 0 then + z = Z_START - i + end + + NewLoadSceneStart(x, y, z, x, y, z, 50.0, 0) + local curTime = GetGameTimer() + while IsNetworkLoadingScene() do + if GetGameTimer() - curTime > 1000 then + break + end + Wait(0) + end + NewLoadSceneStop() + SetPedCoordsKeepVehicle(ped, x, y, z) + + while not HasCollisionLoadedAroundEntity(ped) do + RequestCollisionAtCoord(x, y, z) + if GetGameTimer() - curTime > 1000 then + break + end + Wait(0) + end + + -- Get ground coord. As mentioned in the natives, this only works if the client is in render distance. + found, groundZ = GetGroundZFor_3dCoord(x, y, z, false); + if found then + Wait(0) + SetPedCoordsKeepVehicle(ped, x, y, groundZ) + break + end + Wait(0) + end + + -- Remove black screen once the loop has ended. + DoScreenFadeIn(650) + if vehicle > 0 then + FreezeEntityPosition(vehicle, false) + else + FreezeEntityPosition(ped, false) + end + + if not found then + -- If we can't find the coords, set the coords to the old ones. + -- We don't unpack them before since they aren't in a loop and only called once. + SetPedCoordsKeepVehicle(ped, oldCoords['x'], oldCoords['y'], oldCoords['z'] - 1.0) + QBCore.Functions.Notify(Lang:t('error.tp_error'), 'error', 5000) + end + + -- If Z coord was found, set coords in found coords. + SetPedCoordsKeepVehicle(ped, x, y, groundZ) + QBCore.Functions.Notify(Lang:t('success.teleported_waypoint'), 'success', 5000) +end) + +-- Vehicle Commands + +RegisterNetEvent('QBCore:Command:SpawnVehicle', function(vehName) + local ped = PlayerPedId() + local hash = joaat(vehName) + local veh = GetVehiclePedIsUsing(ped) + if not IsModelInCdimage(hash) then return end + RequestModel(hash) + while not HasModelLoaded(hash) do + Wait(0) + end + + if IsPedInAnyVehicle(ped) then + SetEntityAsMissionEntity(veh, true, true) + DeleteVehicle(veh) + end + + local vehicle = CreateVehicle(hash, GetEntityCoords(ped), GetEntityHeading(ped), true, false) + TaskWarpPedIntoVehicle(ped, vehicle, -1) + SetVehicleFuelLevel(vehicle, 100.0) + SetVehicleDirtLevel(vehicle, 0.0) + SetModelAsNoLongerNeeded(hash) + TriggerEvent('vehiclekeys:client:SetOwner', QBCore.Functions.GetPlate(vehicle)) +end) + +RegisterNetEvent('QBCore:Command:DeleteVehicle', function() + local ped = PlayerPedId() + local veh = GetVehiclePedIsUsing(ped) + if veh ~= 0 then + SetEntityAsMissionEntity(veh, true, true) + DeleteVehicle(veh) + else + local pcoords = GetEntityCoords(ped) + local vehicles = GetGamePool('CVehicle') + for _, v in pairs(vehicles) do + if #(pcoords - GetEntityCoords(v)) <= 5.0 then + SetEntityAsMissionEntity(v, true, true) + DeleteVehicle(v) + end + end + end +end) + +RegisterNetEvent('QBCore:Client:VehicleInfo', function(info) + local plate = QBCore.Functions.GetPlate(info.vehicle) + local hasKeys = true + + if GetResourceState('qb-vehiclekeys') == 'started' or GetResourceState('qb-vehiclekeys') == 'starting' then -- qb-vehiclekeys starting AFTER qb-core + hasKeys = exports['qb-vehiclekeys']:HasKeys(plate) + end + + local data = { + vehicle = info.vehicle, + seat = info.seat, + name = info.modelName, + plate = plate, + driver = GetPedInVehicleSeat(info.vehicle, -1), + inseat = GetPedInVehicleSeat(info.vehicle, info.seat), + haskeys = hasKeys + } + + TriggerEvent('QBCore:Client:' .. info.event .. 'Vehicle', data) +end) + +-- Other stuff + +RegisterNetEvent('QBCore:Player:SetPlayerData', function(val) + QBCore.PlayerData = val +end) + +RegisterNetEvent('QBCore:Player:UpdatePlayerData', function() + TriggerServerEvent('QBCore:UpdatePlayer') +end) + +RegisterNetEvent('QBCore:Notify', function(text, type, length, icon) + QBCore.Functions.Notify(text, type, length, icon) +end) + +-- This event is exploitable and should not be used. It has been deprecated, and will be removed soon. +RegisterNetEvent('QBCore:Client:UseItem', function(item) + QBCore.Debug(string.format('%s triggered QBCore:Client:UseItem by ID %s with the following data. This event is deprecated due to exploitation, and will be removed soon. Check qb-inventory for the right use on this event.', GetInvokingResource(), GetPlayerServerId(PlayerId()))) + QBCore.Debug(item) +end) + +RegisterNUICallback('getNotifyConfig', function(_, cb) + cb(QBCore.Config.Notify) +end) + +-- Callback Events -- + +-- Client Callback +RegisterNetEvent('QBCore:Client:TriggerClientCallback', function(name, ...) + if not QBCore.ClientCallbacks[name] then return end + + QBCore.ClientCallbacks[name](function(...) + TriggerServerEvent('QBCore:Server:TriggerClientCallback', name, ...) + end, ...) +end) + +-- Server Callback +RegisterNetEvent('QBCore:Client:TriggerCallback', function(name, ...) + if QBCore.ServerCallbacks[name] then + QBCore.ServerCallbacks[name].promise:resolve(...) + + if QBCore.ServerCallbacks[name].callback then + QBCore.ServerCallbacks[name].callback(...) + end + + QBCore.ServerCallbacks[name] = nil + end +end) + +-- Me command + +local function Draw3DText(coords, str) + local onScreen, worldX, worldY = World3dToScreen2d(coords.x, coords.y, coords.z) + local camCoords = GetGameplayCamCoord() + local scale = 200 / (GetGameplayCamFov() * #(camCoords - coords)) + if onScreen then + SetTextScale(1.0, 0.5 * scale) + SetTextFont(4) + SetTextColour(255, 255, 255, 255) + SetTextEdge(2, 0, 0, 0, 150) + SetTextProportional(1) + SetTextOutline() + SetTextCentre(1) + BeginTextCommandDisplayText('STRING') + AddTextComponentSubstringPlayerName(str) + EndTextCommandDisplayText(worldX, worldY) + end +end + +RegisterNetEvent('QBCore:Command:ShowMe3D', function(senderId, msg) + local sender = GetPlayerFromServerId(senderId) + CreateThread(function() + local displayTime = 5000 + GetGameTimer() + while displayTime > GetGameTimer() do + local targetPed = GetPlayerPed(sender) + local tCoords = GetEntityCoords(targetPed) + Draw3DText(tCoords, msg) + Wait(0) + end + end) +end) + +-- Listen to Shared being updated +RegisterNetEvent('QBCore:Client:OnSharedUpdate', function(tableName, key, value) + QBCore.Shared[tableName][key] = value + TriggerEvent('QBCore:Client:UpdateObject') +end) + +RegisterNetEvent('QBCore:Client:OnSharedUpdateMultiple', function(tableName, values) + for key, value in pairs(values) do + QBCore.Shared[tableName][key] = value + end + TriggerEvent('QBCore:Client:UpdateObject') +end) + +RegisterNetEvent('QBCore:Client:SharedUpdate', function(table) + QBCore.Shared = table +end)