local QBCore = exports['qb-core']:GetCoreObject() local currentDealer = nil local knockingDoor = false local dealerIsHome = false local waitingDelivery = nil local activeDelivery = nil local interacting = false local deliveryTimeout = 0 local isHealingPerson = false local healAnimDict = "mini@cpr@char_a@cpr_str" local healAnim = "cpr_pumpchest" RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() QBCore.Functions.TriggerCallback('cr-drugs:server:RequestConfig', function(DealerConfig) Config.Dealers = DealerConfig end) end) local 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, 41, 11, 41, 68) ClearDrawOrigin() end Citizen.CreateThread(function() while true do local ped = PlayerPedId() local pos = GetEntityCoords(ped) nearDealer = false for id, dealer in pairs(Config.Dealers) do local dealerDist = #(pos - vector3(dealer["coords"]["x"], dealer["coords"]["y"], dealer["coords"]["z"])) if dealerDist <= 6 then nearDealer = true if dealerDist <= 1.5 and not isHealingPerson then if not interacting then if not dealerIsHome then DrawText3D(dealer["coords"]["x"], dealer["coords"]["y"], dealer["coords"]["z"], '[E] To knock') if IsControlJustPressed(0, 38) then currentDealer = id knockDealerDoor() end elseif dealerIsHome then if dealer["name"] == "Mysteryman" then DrawText3D(dealer["coords"]["x"], dealer["coords"]["y"], dealer["coords"]["z"], '[E] To buy / [G] Help your guy ($5000)') else DrawText3D(dealer["coords"]["x"], dealer["coords"]["y"], dealer["coords"]["z"], '[E] To buy / [G] Start a mission') end if IsControlJustPressed(0, 38) then buyDealerStuff() end if IsControlJustPressed(0, 47) then if dealer["name"] == "Mysteryman" then local player, distance = GetClosestPlayer() if player ~= -1 and distance < 5.0 then local playerId = GetPlayerServerId(player) isHealingPerson = true QBCore.Functions.Progressbar("hospital_revive", "Treating Person", 5000, false, true, { disableMovement = false, disableCarMovement = false, disableMouse = false, disableCombat = true, }, { animDict = healAnimDict, anim = healAnim, flags = 16, }, {}, {}, function() -- Done isHealingPerson = false StopAnimTask(PlayerPedId(), healAnimDict, "exit", 1.0) QBCore.Functions.Notify("You have treated a person!") TriggerServerEvent("hospital:server:RevivePlayer", playerId, true) end, function() -- Cancel isHealingPerson = false StopAnimTask(PlayerPedId(), healAnimDict, "exit", 1.0) QBCore.Functions.Notify("Failed!", "error") end) else QBCore.Functions.Notify("There is no one nearby.", "error") end else if waitingDelivery == nil then TriggerEvent("chatMessage", "Dealer "..Config.Dealers[currentDealer]["name"], "These are the products, I\'ll keep in touch through email, stay alert.") requestDelivery() interacting = false dealerIsHome = false else TriggerEvent("chatMessage", "Dealer "..Config.Dealers[currentDealer]["name"], "error", 'You still have a pending delivery, what are you waiting for?!') end end end end end end end end if not nearDealer then dealerIsHome = false Citizen.Wait(2000) end Citizen.Wait(3) end end) function GetClosestPlayer() local closestPlayers = QBCore.Functions.GetPlayersFromCoords() local closestDistance = -1 local closestPlayer = -1 local coords = GetEntityCoords(PlayerPedId()) for i=1, #closestPlayers, 1 do if closestPlayers[i] ~= PlayerId() then local pos = GetEntityCoords(GetPlayerPed(closestPlayers[i])) local distance = #(pos - coords) if closestDistance == -1 or closestDistance > distance then closestPlayer = closestPlayers[i] closestDistance = distance end end end return closestPlayer, closestDistance end knockDealerDoor = function() local hours = GetClockHours() local min = Config.Dealers[currentDealer]["time"]["min"] local max = Config.Dealers[currentDealer]["time"]["max"] if hours >= min and hours <= max then knockDoorAnim(true) else knockDoorAnim(false) end end function buyDealerStuff() local repItems = {} repItems.label = Config.Dealers[currentDealer]["name"] repItems.items = {} repItems.slots = 30 for k, v in pairs(Config.Dealers[currentDealer]["products"]) do if QBCore.Functions.GetPlayerData().metadata["dealerrep"] >= Config.Dealers[currentDealer]["products"][k].minrep then repItems.items[k] = Config.Dealers[currentDealer]["products"][k] end end TriggerServerEvent("inventory:server:OpenInventory", "shop", "Dealer_"..Config.Dealers[currentDealer]["name"], repItems) end function knockDoorAnim(home) local knockAnimLib = "timetable@jimmy@doorknock@" local knockAnim = "knockdoor_idle" local PlayerPed = PlayerPedId() local myData = QBCore.Functions.GetPlayerData() if home then TriggerServerEvent('InteractSound_SV:PlayWithinDistance', 2.0, 'doorknock', 0.5) Citizen.Wait(100) while (not HasAnimDictLoaded(knockAnimLib)) do RequestAnimDict(knockAnimLib) Citizen.Wait(100) end knockingDoor = true TaskPlayAnim(PlayerPed, knockAnimLib, knockAnim, 3.0, 3.0, -1, 1, 0, false, false, false ) Citizen.Wait(3500) TaskPlayAnim(PlayerPed, knockAnimLib, "exit", 3.0, 3.0, -1, 1, 0, false, false, false) knockingDoor = false Citizen.Wait(1000) dealerIsHome = true if Config.Dealers[currentDealer]["name"] == "Mysteryman" then TriggerEvent("chatMessage", "Dealer "..Config.Dealers[currentDealer]["name"], "normal", 'Hello my child, what can I do for you') elseif Config.Dealers[currentDealer]["name"] == "Fred" then dealerIsHome = false TriggerEvent("chatMessage", "Dealer "..Config.Dealers[currentDealer]["name"], "normal", 'Unfortunately I don\'t do business anymore ... You should have treated me better') else TriggerEvent("chatMessage", "Dealer "..Config.Dealers[currentDealer]["name"], "normal", 'Yo '..myData.charinfo.firstname..', what can I do for you?') end -- knockTimeout() else TriggerServerEvent('InteractSound_SV:PlayWithinDistance', 2.0, 'doorknock', 0.5) Citizen.Wait(100) while (not HasAnimDictLoaded(knockAnimLib)) do RequestAnimDict(knockAnimLib) Citizen.Wait(100) end knockingDoor = true TaskPlayAnim(PlayerPed, knockAnimLib, knockAnim, 3.0, 3.0, -1, 1, 0, false, false, false ) Citizen.Wait(3500) TaskPlayAnim(PlayerPed, knockAnimLib, "exit", 3.0, 3.0, -1, 1, 0, false, false, false) knockingDoor = false Citizen.Wait(1000) QBCore.Functions.Notify('It looks like no one is home..', 'error', 3500) end end RegisterNetEvent('cr-drugs:client:updateDealerItems') AddEventHandler('cr-drugs:client:updateDealerItems', function(itemData, amount) TriggerServerEvent('cr-drugs:server:updateDealerItems', itemData, amount, currentDealer) end) RegisterNetEvent('cr-drugs:client:setDealerItems') AddEventHandler('cr-drugs:client:setDealerItems', function(itemData, amount, dealer) Config.Dealers[dealer]["products"][itemData.slot].amount = Config.Dealers[dealer]["products"][itemData.slot].amount - amount end) function requestDelivery() local location = math.random(1, #Config.DeliveryLocations) local amount = math.random(1, 3) local item = randomDeliveryItemOnRep() waitingDelivery = { ["coords"] = Config.DeliveryLocations[location]["coords"], ["locationLabel"] = Config.DeliveryLocations[location]["label"], ["amount"] = amount, ["dealer"] = currentDealer, ["itemData"] = Config.DeliveryItems[item] } TriggerServerEvent('cr-drugs:server:giveDeliveryItems', amount) SetTimeout(2000, function() TriggerServerEvent('qb-phone:server:sendNewMail', { sender = Config.Dealers[currentDealer]["name"], subject = "Delivery Location", message = "Here is all info about the delivery,
Items:
"..amount.."x "..QBCore.Shared.Items[waitingDelivery["itemData"]["item"]]["label"].."

make sure to be on time.", button = { enabled = true, buttonEvent = "cr-drugs:client:setLocation", buttonData = waitingDelivery } }) end) end function randomDeliveryItemOnRep() local ped = PlayerPedId() local myRep = QBCore.Functions.GetPlayerData().metadata["dealerrep"] retval = nil for k, v in pairs(Config.DeliveryItems) do if Config.DeliveryItems[k]["minrep"] <= myRep then local availableItems = {} availableItems[#availableItems+1] = k local item = math.random(1, #availableItems) retval = item end end return retval end function setMapBlip(x, y) SetNewWaypoint(x, y) QBCore.Functions.Notify('The route to the delivery location has been set on your map.', 'success'); end RegisterNetEvent('cr-drugs:client:setLocation') AddEventHandler('cr-drugs:client:setLocation', function(locationData) if activeDelivery == nil then activeDelivery = locationData else setMapBlip(activeDelivery["coords"]["x"], activeDelivery["coords"]["y"]) QBCore.Functions.Notify('You still have a pending delivery...') return end deliveryTimeout = 300 deliveryTimer() setMapBlip(activeDelivery["coords"]["x"], activeDelivery["coords"]["y"]) Citizen.CreateThread(function() while true do local ped = PlayerPedId() local pos = GetEntityCoords(ped) local inDeliveryRange = false if activeDelivery ~= nil then local dist = #(pos - vector3(activeDelivery["coords"]["x"], activeDelivery["coords"]["y"], activeDelivery["coords"]["z"])) if dist < 15 then inDeliveryRange = true if dist < 1.5 then DrawText3D(activeDelivery["coords"]["x"], activeDelivery["coords"]["y"], activeDelivery["coords"]["z"], '[E] '..activeDelivery["amount"]..'x '..QBCore.Shared.Items[activeDelivery["itemData"]["item"]]["label"]..' deliver.') if IsControlJustPressed(0, 38) then deliverStuff(activeDelivery) activeDelivery = nil waitingDelivery = nil break end end end if not inDeliveryRange then Citizen.Wait(1500) end else break end Citizen.Wait(3) end end) end) function deliveryTimer() Citizen.CreateThread(function() while true do if deliveryTimeout - 1 > 0 then deliveryTimeout = deliveryTimeout - 1 else deliveryTimeout = 0 break end Citizen.Wait(1000) end end) end function deliverStuff(activeDelivery) if deliveryTimeout > 0 then TriggerEvent('animations:client:EmoteCommandStart', {"c"}) Citizen.Wait(500) TriggerEvent('animations:client:EmoteCommandStart', {"bumbin"}) checkPedDistance() QBCore.Functions.Progressbar("work_dropbox", "Delivering Products", 3500, false, true, { disableMovement = true, disableCarMovement = true, disableMouse = false, disableCombat = true, }, {}, {}, {}, function() -- Done TriggerServerEvent('cr-drugs:server:succesDelivery', activeDelivery, true) end, function() -- Cancel ClearPedTasks(PlayerPedId()) QBCore.Functions.Notify("Canceled", "error") end) else TriggerServerEvent('cr-drugs:server:succesDelivery', activeDelivery, false) end deliveryTimeout = 0 end function checkPedDistance() local PlayerPeds = {} if next(PlayerPeds) == nil then for _, player in ipairs(GetActivePlayers()) do local ped = GetPlayerPed(player) PlayerPeds[#PlayerPeds+1] = ped end end local closestPed, closestDistance = QBCore.Functions.GetClosestPed(coords, PlayerPeds) if closestDistance < 40 and closestPed ~= 0 then local callChance = math.random(1, 100) if callChance < 15 then doPoliceAlert() end end end function doPoliceAlert() local ped = PlayerPedId() local pos = GetEntityCoords(ped) local s1, s2 = GetStreetNameAtCoord(pos.x, pos.y, pos.z) local street1 = GetStreetNameFromHashKey(s1) local street2 = GetStreetNameFromHashKey(s2) local streetLabel = street1 if street2 ~= nil then streetLabel = streetLabel .. " " .. street2 end TriggerServerEvent('cr-drugs:server:callCops', streetLabel, pos) end RegisterNetEvent('cr-drugs:client:robberyCall') AddEventHandler('cr-drugs:client:robberyCall', function(msg, streetLabel, coords) PlaySound(-1, "Lose_1st", "GTAO_FM_Events_Soundset", 0, 0, 1) TriggerEvent("chatMessage", "911-ALERT", "error", msg) local transG = 250 local blip = AddBlipForCoord(coords.x, coords.y, coords.z) SetBlipSprite(blip, 458) SetBlipColour(blip, 1) SetBlipDisplay(blip, 4) SetBlipAlpha(blip, transG) SetBlipScale(blip, 1.0) BeginTextCommandSetBlipName('STRING') AddTextComponentString("911: Drug Dealing") EndTextCommandSetBlipName(blip) while transG ~= 0 do Wait(180 * 4) transG = transG - 1 SetBlipAlpha(blip, transG) if transG == 0 then SetBlipSprite(blip, 2) RemoveBlip(blip) return end end end) RegisterNetEvent('cr-drugs:client:sendDeliveryMail') AddEventHandler('cr-drugs:client:sendDeliveryMail', function(type, deliveryData) if type == 'perfect' then TriggerServerEvent('qb-phone:server:sendNewMail', { sender = Config.Dealers[deliveryData["dealer"]]["name"], subject = "Delivery", message = "You did good work, hope to see you again ;)

Groeten, "..Config.Dealers[deliveryData["dealer"]]["name"] }) elseif type == 'bad' then TriggerServerEvent('qb-phone:server:sendNewMail', { sender = Config.Dealers[deliveryData["dealer"]]["name"], subject = "Delivery", message = "I have received complaints about your delivery, don\'t let this happen again..." }) elseif type == 'late' then TriggerServerEvent('qb-phone:server:sendNewMail', { sender = Config.Dealers[deliveryData["dealer"]]["name"], subject = "Delivery", message = "You weren\'t on time. Did you have more important things to do than business?" }) end end) RegisterNetEvent('cr-drugs:client:CreateDealer') AddEventHandler('cr-drugs:client:CreateDealer', function(dealerName, minTime, maxTime) local ped = PlayerPedId() local loc = GetEntityCoords(ped) local DealerData = { name = dealerName, time = { min = minTime, max = maxTime, }, pos = { x = loc.x, y = loc.y, z = loc.z, } } TriggerServerEvent('cr-drugs:server:CreateDealer', DealerData) end) RegisterNetEvent('cr-drugs:client:RefreshDealers') AddEventHandler('cr-drugs:client:RefreshDealers', function(DealerData) Config.Dealers = DealerData end) RegisterNetEvent('cr-drugs:client:GotoDealer') AddEventHandler('cr-drugs:client:GotoDealer', function(DealerData) local ped = PlayerPedId() SetEntityCoords(ped, DealerData["coords"]["x"], DealerData["coords"]["y"], DealerData["coords"]["z"]) QBCore.Functions.Notify('You have been teleported : '.. DealerData["name"] .. ' Good luck!', 'success') end)