Skip to content

Commit

Permalink
Merge pull request #1 from Giana/feature/g-drugselling
Browse files Browse the repository at this point in the history
Feature/g drugselling
  • Loading branch information
Giana committed Feb 19, 2023
2 parents 1ed80eb + 3edc36c commit f5e93a8
Show file tree
Hide file tree
Showing 9 changed files with 644 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .idea/discord.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# G-DrugSelling

G-DrugSelling is a script for FiveM QBCore for selling drugs (or any items) from the player's inventory via vehicle and/or walk up, or target, at configurable coordinates.

<h1>INSTALLATION GUIDE</h1>

1. Drop the g-drugselling folder into your [standalone] folder (or whichever other ensured folder you want to use)

<h1>FEATURES</h1>

- Create locations anywhere for selling items and choose sellable items and rewards for each location
- Enable/disable locations, blips, markers, NPCs, and notifications
- Configure means of selling by location
- Examples include walk up, drive up, both, or target
- Configure sellable quantities and reward amounts per item
- Configure police required to sell and chance of police alert per location

**IMAGES**
-----
Coming Soon

**DEPENDENCIES**
-----
- [QBCore](https://github.com/qbcore-framework)
- [qb-core](https://github.com/qbcore-framework/qb-core)
- [qb-inventory](https://github.com/qbcore-framework/qb-inventory)
- [qb-target](https://github.com/qbcore-framework/qb-target)

**CREDIT**
-----
Code excerpts for NPC spawning and the concept of NPC render distance were repurposed and refactored from [pickle_farming](https://github.com/PickleModifications/pickle_farming).
Code excerpts for getting and caching current police count were repurposed from [qb-jewelery](https://github.com/qbcore-framework/qb-jewelery).
185 changes: 185 additions & 0 deletions client/main.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
local QBCore = exports['qb-core']:GetCoreObject()

local IsSelling = false
local Peds = {}

-- Functions --

function createPed(hash, ...)
RequestModel(hash)
while not HasModelLoaded(hash) do
Citizen.Wait(100)
end
local ped = CreatePed(26, hash, ...)
SetModelAsNoLongerNeeded(hash)
return ped
end

function createClientNpc(index)
if (Peds[index]) then
deleteClientNpc(index)
end
Peds[index] = {}
local location = Config.SellLocations[index]
local ped = createPed(location.npc.ped, location.coords.x, location.coords.y, location.coords.z - 0.97, location.npc.heading, false, true)
FreezeEntityPosition(ped, true)
SetEntityHeading(ped, location.npc.heading)
SetEntityInvincible(ped, true)
SetBlockingOfNonTemporaryEvents(ped, true)
Peds[index].npc = ped
end

function deleteClientNpc(index)
if (Peds[index]) then
DeleteEntity(Peds[index].npc)
Peds[index] = nil
end
end

function attemptSell(sellLocationIndex)
local notificationsEnabled = Config.SellLocations[sellLocationIndex].notificationsEnabled
if IsSelling then
return
end
IsSelling = true
QBCore.Functions.TriggerCallback('g-drugselling:server:getCopCount', function(copCount)
if copCount >= Config.SellLocations[sellLocationIndex].policeRequired then
QBCore.Functions.TriggerCallback('g-drugselling:server:getSellableItems', function(sellableItems)
if sellableItems and #sellableItems > 0 then
if notificationsEnabled then
QBCore.Functions.Notify(Lang:t('info.selling'))
end
TriggerServerEvent('g-drugselling:server:sellItems', sellLocationIndex, sellableItems, Config.SellLocations[sellLocationIndex].money_reward_type)
Citizen.Wait(10000)
IsSelling = false
else
if notificationsEnabled then
QBCore.Functions.Notify(Lang:t('error.not_enough'))
end
Citizen.Wait(10000)
IsSelling = false
end
end, sellLocationIndex)
else
if notificationsEnabled then
QBCore.Functions.Notify(Lang:t('error.cannot_sell'))
end
Citizen.Wait(20000)
IsSelling = false
end
end)
end

-- Events --

AddEventHandler('onResourceStart', function(resourceName)
if resourceName == GetCurrentResourceName() then
IsSelling = false
end
end)

AddEventHandler('onResourceStop', function(resourceName)
if resourceName == GetCurrentResourceName() then
for k, v in pairs(Peds) do
deleteClientNpc(k)
end
end
end)

RegisterNetEvent('g-drugselling:client:registerTarget', function()
local ped = PlayerPedId()
local pos = GetEntityCoords(ped)
for k, v in pairs(Config.SellLocations) do
local dist = #(pos - v.coords)
if dist < 2 then
attemptSell(k)
break
end
end
end)

RegisterNetEvent('g-drugselling:client:policeAlert', function(message)
TriggerServerEvent('police:server:policeAlert', message)
end)

-- Threads --

-- Blip setup
Citizen.CreateThread(function()
for k, v in pairs(Config.SellLocations) do
if v.active and v.blip.enabled then
local locationBlip = AddBlipForCoord(v.coords.x, v.coords.y, v.coords.z)
SetBlipColour(locationBlip, v.blip.color)
SetBlipSprite(locationBlip, v.blip.sprite)
SetBlipScale(locationBlip, v.blip.scale)
SetBlipDisplay(locationBlip, v.blip.display)
SetBlipAsShortRange(locationBlip, v.blip.shortRange)
BeginTextCommandSetBlipName('STRING')
AddTextComponentSubstringPlayerName(v.blip.label)
EndTextCommandSetBlipName(locationBlip)
end
end
end)

-- NPC ped setup
Citizen.CreateThread(function()
while true do
if LocalPlayer.state.isLoggedIn then
local ped = PlayerPedId()
local pos = GetEntityCoords(ped)
local inRange = false
for k, v in pairs(Config.SellLocations) do
if v.active and v.npc.enabled then
local dist = #(pos - v.coords)
if dist < Config.NpcRenderDistance then
if not Peds[k] then
createClientNpc(k)
end
inRange = true
elseif Peds[k] then
deleteClientNpc(k)
end
end
end
if not inRange then
Citizen.Wait(2000)
end
end
Citizen.Wait(3)
end
end)

-- Walk up & drive up
Citizen.CreateThread(function()
while true do
if LocalPlayer.state.isLoggedIn then
local ped = PlayerPedId()
local pos = GetEntityCoords(ped)
local inRange = false
for k, v in pairs(Config.SellLocations) do
if v.active then
local dist = #(pos - v.coords)
if dist < 20 then
if v.marker.enabled then
if (v.type == 'walkup' and not IsPedInAnyVehicle(ped, false)) or (v.type == 'driveup' and IsPedInAnyVehicle(ped, false)) or v.type == 'any' or v.type == 'target' then
DrawMarker(v.marker.type, v.coords.x, v.coords.y, v.coords.z - 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.marker.scaleX, v.marker.scaleY, v.marker.scaleZ, v.marker.red, v.marker.green, v.marker.blue, v.marker.alpha, v.marker.bob, v.marker.faceCamera, 0, 1, 0, 0, 0)
end
end
if dist < 2 then
if (v.type == 'walkup' and not IsPedInAnyVehicle(ped, false)) or (v.type == 'driveup' and IsPedInAnyVehicle(ped, false)) or v.type == 'any' then
if not IsSelling then
attemptSell(k)
end
end
end
inRange = true
end
end
end
if not inRange then
Citizen.Wait(2000)
end
end
Citizen.Wait(3)
end
end)
21 changes: 21 additions & 0 deletions client/target.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
for k, v in pairs(Config.SellLocations) do
if Config.SellLocations[k].active and Config.SellLocations[k].type == 'target' then
exports['qb-target']:AddBoxZone(Config.SellLocations[k].blip.label, Config.SellLocations[k].coords, 2.5, 2.5, {
name = Config.SellLocations[k].blip.label,
heading = 0,
debugPoly = false,
minZ = Config.SellLocations[k].coords.z - 1,
maxZ = Config.SellLocations[k].coords + 1,
}, {
options = {
{
type = 'client',
event = 'g-drugselling:client:registerTarget',
icon = 'fas fa-pills',
label = Lang:t('other.target_label'),
},
},
distance = 2
})
end
end

0 comments on commit f5e93a8

Please sign in to comment.