├── __resource.lua ├── Config.lua ├── LICENSE ├── Server.lua ├── README.md └── Client.lua /__resource.lua: -------------------------------------------------------------------------------- 1 | resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' 2 | 3 | server_scripts { 4 | '@mysql-async/lib/MySQL.lua', 5 | '@es_extended/locale.lua', 6 | 'Server.lua', 7 | 'Config.lua', 8 | 9 | } 10 | 11 | client_scripts { 12 | 'Client.lua', 13 | 'Config.lua', 14 | } 15 | 16 | -------------------------------------------------------------------------------- /Config.lua: -------------------------------------------------------------------------------- 1 | 2 | 3 | Config = {} 4 | 5 | Config.Items = { 6 | 7 | -- Example / Exemple 8 | 9 | -- 'item' is the database name of the item ( not the label ) 10 | -- 'prix' is the price it will be sold at a 10% marge 11 | -- 'legal' if set on false it will call the cop 1/Chance of the time 12 | -- 'sale' if the money is gived in black money 13 | 14 | -- 'item' est le nom de l'item dans la bdd ( pas le label ) 15 | -- 'prix' est le prix de vente avec une marge 10% 16 | -- 'legal' si mis sur false la police sera prevenu 1/Chance du temps 17 | -- 'sale' si l'argent est donné en sale 18 | 19 | -- { item = '', prix = , legal = , sale = }, 20 | 21 | 22 | { item = 'weed_pooch', prix = 50, legal = false, sale = false }, 23 | { item = 'coke_pooch', prix = 70, legal = false, sale = false }, 24 | { item = 'meth_pooch', prix = 80, legal = false, sale = false }, 25 | { item = 'opium_pooch', prix = 100, legal = false, sale = false }, 26 | 27 | 28 | { item = 'cigare', prix = 45, legal = true, sale = false }, 29 | { item = 'gitanes', prix = 20, legal = true, sale = false }, 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [2021] [Sélène Desna] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Server.lua: -------------------------------------------------------------------------------- 1 | ------------------------- 2 | --- Declaration d'ESX --- 3 | ------------------------- 4 | 5 | ESX = nil TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) 6 | 7 | ---------------------- 8 | --- Register Event --- 9 | ---------------------- 10 | 11 | ESX.RegisterServerCallback('seln_SellItem:recupInventaire', function(source, cb) 12 | local xPlayer = ESX.GetPlayerFromId(source) 13 | local items = xPlayer.inventory 14 | local accounts = nil 15 | local data = nil 16 | 17 | cb({items = items}) 18 | end) 19 | 20 | 21 | 22 | RegisterServerEvent("seln_SellItem:checkInventaire") 23 | AddEventHandler("seln_SellItem:checkInventaire", function(Notif) 24 | if possedeItems() then 25 | TriggerClientEvent("seln_SellItem:OuvrirInventaire", source) 26 | else TriggerClientEvent('esx:showAdvancedNotification', source, '[ Ventes ]', Notif, nil, 'CHAR_BIKESITE', 0) 27 | end 28 | end) 29 | 30 | RegisterServerEvent("seln_SellItem:VendreItem") 31 | AddEventHandler("seln_SellItem:VendreItem", function(item, Prix, Notif, Combien, Sale) 32 | local xPlayer = ESX.GetPlayerFromId(source) 33 | 34 | if xPlayer.getInventoryItem(item).count > Combien then 35 | xPlayer.removeInventoryItem(item, Combien) 36 | Prix = Prix*Combien 37 | 38 | if Sale == false then xPlayer.addMoney(Prix) 39 | else xPlayer.addAccountMoney('black_money', Prix) 40 | end 41 | 42 | local itemlabel = ESX.GetItemLabel(item) 43 | Notif = Combien..Notif..Prix 44 | TriggerClientEvent('esx:showAdvancedNotification', source, '[ Ventes ]', Notif, nil, 'CHAR_BIKESITE', 0) 45 | 46 | else 47 | Combien = xPlayer.getInventoryItem(item).count 48 | 49 | xPlayer.removeInventoryItem(item, Combien) 50 | Prix = Prix*Combien 51 | xPlayer.addMoney(Prix) 52 | 53 | local itemlabel = ESX.GetItemLabel(item) 54 | 55 | Notif = Combien..' '..itemlabel..Notif..Prix 56 | 57 | TriggerClientEvent('esx:showAdvancedNotification', source, '[ Ventes ]', Notif, nil, 'CHAR_BIKESITE', 0) 58 | 59 | end 60 | 61 | end) 62 | 63 | 64 | RegisterServerEvent('seln_SellItem:AlertePolice') 65 | AddEventHandler('seln_SellItem:AlertePolice', function(serverid) 66 | _source = source 67 | xPlayer = ESX.GetPlayerFromId(_source) 68 | local xPlayers = ESX.GetPlayers() 69 | for i=1, #xPlayers, 1 do 70 | local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) 71 | if xPlayer.job.name == 'police' then 72 | TriggerClientEvent('seln_SellItem:PhotoMugshot', xPlayers[i], serverid) 73 | end 74 | end 75 | end) 76 | 77 | --------------- 78 | -- Fonctions -- 79 | --------------- 80 | 81 | function possedeItems() 82 | local xPlayer = ESX.GetPlayerFromId(source) 83 | local possede = false 84 | 85 | for i,v in ipairs(Config.Items) do 86 | if xPlayer.getInventoryItem(v.item).count > 0 then possede = true end 87 | end 88 | 89 | if possede then return true else return false end 90 | end 91 | 92 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D44EGNM) 2 | 3 | ### [EN] [FR] https://youtu.be/5cGgQSnExMg 4 | 5 | ###### Allow Players to | Permet au Joueurs de 6 | - [x] Sell Legals Item to NPC ( for jobs ) | | Vendre des Item legaux au PNJ ( Pour le Boulot ) 7 | - [x] Deal Item to NPC ( Drugs/..) | | Dealer des Items au PNJ ( Drogues/..) 8 | - [x] Cops Get Alerts when Dealing (1/Chance) | | La Police est informé des Deals (1/Chance) 9 | 10 | # [EN] Selling Item to NPC Script for Fivem [ ESX ] 11 | Created by Selene Desna on August 15 & 16, 2020 for [ Holliday's RP ] 12 | 13 | This Script need the server to have the wanted items in your database. 14 | If you need help to modify it, you can contact me on GitHub. 15 | 16 | ### Config : 17 | Warning : Changing variables that are not in the following list can broke the script ! 18 | ``` 19 | Chance : Chance for police to get alerted when selling illegal items ( the chance is 1/Chance ) 20 | Notif1 : Message when you have sold ( will get the number and name name of item before and money received after ) 21 | Notif2 : Message when nobody is nearby 22 | Notif3 : Message when the NPC or player is in a car 23 | Notif4 : Message when the NPC already have bought something or is unable to buy 24 | Notif5 : Message when the NPC to not accept an illegal item 25 | Notif6 : Message when try to open F11 menu but dont have item to sell 26 | Notif7 : Message in the police alert notification whith the head and place 27 | ``` 28 | To add a item to sell copy the following line ( Explained more deeply in Config.lua ) 29 | (do not forget the ',' at the end !) : 30 | ``` 31 | { item = '', prix = , legal = }, 32 | ``` 33 | 34 | 35 | 36 | 37 | # [FR] Script de Vente d'Item au PNJ pour Fivem [ ESX ] 38 | Creer par Selene Desna les 15 & 16 aout 2020 pour [ Holliday's RP ] 39 | 40 | Ce Script à besoin que votre serveur est les items choisis dans la base de donnée. 41 | Si vous avez besoin d'aide afin de le modifier contactez moi sur GitHub. 42 | 43 | ### Config : 44 | Attention : Changer des variable autre que les suivante peut bloqué le script ! 45 | ``` 46 | Chance : Chance pour la police de recevoir une alerte lors d'une vente illegale ( la chance est de 1/Chance ) 47 | Notif1 : Message lors d'une vente ( avec le nombre et nom de l'item avant le message et son prix a la fin ) 48 | Notif2 : Message quand aucun pnj n'est trouvé 49 | Notif3 : Message lorsque le joueur ou pnj est en véhicule 50 | Notif4 : Message lorsque la personne a deja acheter ou ne peut pas 51 | Notif5 : Message si la personne refuse un item illegal 52 | Notif6 : Message quand le joueur ouvre le menu F11 mais n'as pas d'item a vendre 53 | Notif7 : Message dans l'alerte police avec le visage et la position 54 | ``` 55 | Pour ajouter un item , copier la ligne suivante, ( Explication plus approfondies dans le Config.lua ) 56 | ( n'oublier pas le ',' a la fin !): 57 | ``` 58 | { item = '', prix = , legal = }, 59 | ``` 60 | -------------------------------------------------------------------------------- /Client.lua: -------------------------------------------------------------------------------- 1 | 2 | 3 | --[[ GitHub : Selene-Desna ]]-- 4 | 5 | -- If you need help editing 6 | -- this script, contact me on 7 | -- my github or add an issue 8 | -- in the github script page 9 | 10 | -- Si vous avez besoin d'aide 11 | -- pour modifier ce script 12 | -- contacter moi sur github 13 | -- ou créez une issue sur la 14 | -- page github du script 15 | 16 | 17 | ----------------- 18 | --- Variables --- 19 | ----------------- 20 | 21 | local Chance = 4 22 | local Notif1 = ' Vendu pour $' 23 | local Notif2 = '~r~Personne à Proximitée' 24 | local Notif3 = '~r~Vente Impossible en Vehicule' 25 | local Notif4 = '~r~La Personne à refusé !' -- deja acheter 26 | local Notif5 = '~r~La Personne à refusé !' -- appel police 27 | local Notif6 = '~r~Aucun Article' 28 | local Notif7 = '~y~Trafic de Stupéfiant en cours !' 29 | 30 | BlacklistNPC = {} 31 | 32 | ------------------------- 33 | --- Declaration d'ESX --- 34 | ------------------------- 35 | 36 | ESX = nil 37 | Citizen.CreateThread(function() 38 | Citizen.Wait(5000) 39 | 40 | -- Joueur 41 | while ESX == nil do 42 | TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) 43 | Citizen.Wait(0) 44 | end 45 | 46 | -- Job 47 | while ESX.GetPlayerData().job == nil do 48 | Citizen.Wait(1000) 49 | end 50 | 51 | -- Faction 52 | while ESX.GetPlayerData().faction == nil do 53 | Citizen.Wait(100) 54 | end 55 | 56 | PlayerData = ESX.GetPlayerData() 57 | end) 58 | 59 | --------------------- 60 | --- Thread Client --- 61 | --------------------- 62 | 63 | 64 | 65 | Citizen.CreateThread(function() 66 | while ESX == nil do Wait(100) end 67 | while true do Wait(0) 68 | 69 | -- Ouverture du menu F11 ? 70 | if IsControlJustPressed(0, 344) and GetLastInputMethod( 0 ) then 71 | TriggerServerEvent("seln_SellItem:checkInventaire", Notif6) 72 | 73 | end 74 | 75 | end 76 | end) 77 | 78 | 79 | 80 | 81 | ---------------------- 82 | --- Register Event --- 83 | ---------------------- 84 | 85 | RegisterNetEvent("seln_SellItem:OuvrirInventaire") 86 | AddEventHandler("seln_SellItem:OuvrirInventaire", function() 87 | ouvreInventaire() 88 | end) 89 | 90 | RegisterNetEvent('seln_SellItem:PhotoMugshot') 91 | AddEventHandler('seln_SellItem:PhotoMugshot', function(serverid) 92 | 93 | local serverid = GetPlayerPed(GetPlayerFromServerId(serverid)) 94 | local Joueur = GetEntityCoords(serverid, true) 95 | local r1, r2 = Citizen.InvokeNative( 0x2EB41072B4C1E4C0, Joueur.x, Joueur.y, Joueur.z, Citizen.PointerValueInt(), Citizen.PointerValueInt() ) 96 | local rue = GetStreetNameFromHashKey(r1) 97 | local zone = GetNameOfZone(Joueur.x, Joueur.y, Joueur.z) 98 | 99 | ESX.ShowAdvancedNotification('~o~Alerte BCSO :', '~o~['..zone..']', Notif7, 'CHAR_CALL911', 1) 100 | 101 | 102 | 103 | blipscrimescene(Joueur.x, Joueur.y, Joueur.z) 104 | end) 105 | 106 | 107 | ----------------- 108 | --- Fonctions --- 109 | ----------------- 110 | 111 | function ouvreInventaire() 112 | local elements = {} 113 | 114 | ESX.TriggerServerCallback('seln_SellItem:recupInventaire', function(result) 115 | 116 | for i=1, #result.items, 1 do 117 | 118 | local invitem = result.items[i] 119 | 120 | for k,v in ipairs(Config.Items) do 121 | if invitem.count > 0 and invitem.name == v.item then 122 | table.insert(elements, { sale = v.sale , 123 | legal = v.legal , 124 | itemprix = v.prix , 125 | itemlabel = invitem.label ,label = invitem.label .. '| ' .. invitem.count , 126 | type = "item_standard", 127 | count = invitem.count, 128 | value = invitem.name 129 | }) 130 | end 131 | end 132 | end 133 | 134 | ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'items_show', { 135 | css = 'Hollidays', 136 | title= "Vente Citadine", align = 'right', 137 | elements = elements 138 | }, function(data, menu) 139 | 140 | local amount = tonumber(data.value) 141 | local item = data.current.value 142 | local itemLabel = data.current.itemlabel 143 | local itemPrix = data.current.itemprix 144 | local invcount = data.current.count 145 | local itemlegal = data.current.legal 146 | local itemsale = data.current.sale 147 | 148 | menu.close() 149 | RechercheNPC(item, itemLabel, itemPrix, itemlegal, itemsale) 150 | 151 | end,function(data, menu) 152 | menu.close() 153 | end) 154 | 155 | end) 156 | end 157 | 158 | function RechercheNPC(item, itemLabel, itemPrix, itemlegal, itemsale ) 159 | 160 | local Joueur = GetPlayerPed(-1) 161 | local Coords = GetEntityCoords(Joueur) 162 | 163 | local NPCproche, distance = ESX.Game.GetClosestPed({ 164 | x = Coords.x, 165 | y = Coords.y, 166 | z = Coords.z 167 | }, {Joueur}) 168 | 169 | 170 | if distance == -1 then 171 | 172 | local success, NPC = GetClosestPed(Coords.x, Coords.y, Coords.z, 5.0, 1, 0, 0, 0, 26) 173 | 174 | if DoesEntityExist(NPC) then 175 | local NPCcoords = GetEntityCoords(NPC) 176 | NPCproche = NPC 177 | distance = GetDistanceBetweenCoords(Coords.x, Coords.y, Coords.z, NPCcoords.x, NPCcoords.y, NPCcoords.z, true) 178 | end 179 | 180 | end 181 | 182 | -- NPC assez proche du joueur pour continuer ? 183 | 184 | if distance <= 3 and NPCproche ~= Joueur then 185 | 186 | ------------------------------------ 187 | -- Conditions Autorisant la Vente -- 188 | ------------------------------------ 189 | 190 | -- NPC blacklisté ? 191 | local NPCblacklister = false 192 | 193 | for i=1, #BlacklistNPC, 1 do if BlacklistNPC[i] == NPCproche then NPCblacklister = true end end 194 | if NPCblacklister then ESX.ShowAdvancedNotification('[ Action Impossible ]', '~o~[ '..Notif4..' ]', nil , 'CHAR_BLOCKED', 0) else 195 | 196 | -- Joueur ou NPC en voiture ? 197 | if IsPedInAnyVehicle(Joueur) or IsPedInAnyVehicle(NPCproche) then 198 | ESX.ShowAdvancedNotification('[ Action Impossible ]', '~o~[ '..Notif3..' ]', nil , 'CHAR_BLOCKED', 0) SortirVoiture() 199 | else 200 | 201 | -- NPC Humain ? 202 | if GetPedType(NPCproche) ~= 28 then 203 | 204 | -- NPC mort ? 205 | if not IsPedDeadOrDying(NPCproche, 1) then 206 | 207 | -- Item Illégal ? + Alerte Police 208 | if illegal(itemlegal) then 209 | 210 | local Prix = itemPrix * ( math.random(90,110) / 100 ) 211 | Prix = math.floor(Prix) 212 | Combien = math.random(1,4) 213 | TriggerServerEvent("seln_SellItem:VendreItem", item, Prix, Notif1, Combien, itemsale) 214 | table.insert( BlacklistNPC , NPCproche ) 215 | 216 | else table.insert( BlacklistNPC , NPCproche ) 217 | end 218 | else ESX.ShowAdvancedNotification('[ Action Impossible ]', '~o~[ '..Notif4..' ]', nil , 'CHAR_BLOCKED', 0) 219 | end -- Mort 220 | else ESX.ShowAdvancedNotification('[ Action Impossible ]', '~o~[ '..Notif4..' ]', nil , 'CHAR_BLOCKED', 0) 221 | end -- Humain 222 | end -- Voiture 223 | end -- Blacklist 224 | 225 | else ESX.ShowAdvancedNotification('[ Action Impossible ]', '~o~[ '..Notif2..' ]', nil , 'CHAR_BLOCKED', 0) 226 | 227 | end 228 | 229 | ouvreInventaire() 230 | 231 | end 232 | 233 | function illegal(legal) 234 | 235 | if legal then retour = true 236 | 237 | else 238 | 239 | local random = math.random(1,4) 240 | if random == 1 then 241 | 242 | 243 | ESX.ShowAdvancedNotification('[ Action Impossible ]', '~o~[ '..Notif5..' ]', nil , 'CHAR_BLOCKED', 0) 244 | local serverid = GetPlayerServerId(PlayerId()) 245 | TriggerServerEvent('seln_SellItem:AlertePolice', serverid) 246 | retour = false 247 | 248 | else retour = true 249 | end 250 | end 251 | return retour 252 | end 253 | 254 | 255 | 256 | function blipscrimescene(gx, gy, gz) 257 | PlayerData = ESX.GetPlayerData() 258 | if PlayerData.job ~= nil and PlayerData.job.name == 'police' then 259 | local transG = 1500 260 | AlreadyPressed = false 261 | local Blip = AddBlipForCoord(gx, gy, gz) 262 | SetBlipSprite(Blip, 161) 263 | SetBlipColour(Blip, 47) 264 | SetBlipAlpha(Blip, transG) 265 | SetBlipAsShortRange(Blip, 1) 266 | 267 | while transG ~= 0 do 268 | local AlreadyBlipActive = false 269 | Wait(10) 270 | 271 | if AlreadyPressed == false then 272 | ESX.ShowHelpNotification('~INPUT_CONTEXT~ Mettre le GPS sur l\'Appel') 273 | if IsControlJustReleased(0, 38) and GetLastInputMethod( 0 ) then 274 | AlreadyBlipActive = true 275 | AlreadyPressed = true 276 | SetBlipRoute(Blip, true) 277 | 278 | Ppos = GetEntityCoords(GetPlayerPed(-1)) 279 | while AlreadyBlipActive == true do 280 | Wait(10) 281 | ESX.ShowHelpNotification('~INPUT_VEH_DROP_PROJECTILE~ Enlever le GPS') 282 | if IsControlJustReleased(0, 73) and GetLastInputMethod( 0 ) then 283 | SetBlipRoute(Blip, false) 284 | AlreadyBlipActive = false 285 | transG = 10 286 | end 287 | end 288 | 289 | end 290 | end 291 | 292 | transG = transG - 1 293 | SetBlipAlpha(Blip, transG) 294 | if transG == 0 then 295 | SetBlipSprite(Blip, 2) 296 | return 297 | end 298 | end 299 | 300 | end 301 | end 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | --------------------------------------------------------------------------------