· 7 years ago · Feb 21, 2019, 02:02 PM
1-- a basic garage implementation
2
3-- vehicle db
4MySQL.createCommand("vRP/vehicles_table", [[
5CREATE TABLE IF NOT EXISTS vrp_user_vehicles(
6 user_id INTEGER,
7 vehicle VARCHAR(255),
8 wait_time text NOT NULL,
9 is_out BOOLEAN,
10 garage_id BIGINT,
11 fuel INTEGER,
12 CONSTRAINT pk_user_vehicles PRIMARY KEY(user_id,vehicle),
13 CONSTRAINT fk_user_vehicles_users FOREIGN KEY(user_id) REFERENCES vrp_users(id) ON DELETE CASCADE
14);
15]])
16
17MySQL.createCommand("vRP/add_technical_ctrl", "ALTER TABLE vrp_user_vehicles ADD tech_ctrl TEXT")
18--delete request
19MySQL.createCommand("vRP/delete_technical_ctrl", "ALTER TABLE vrp_user_vehicles DROP COLUMN tech_ctrl")
20
21MySQL.createCommand("vRP/add_vehicle","INSERT IGNORE INTO vrp_user_vehicles(user_id,vehicle,fuel) VALUES(@user_id,@vehicle,30)")
22MySQL.createCommand("vRP/remove_vehicle","DELETE FROM vrp_user_vehicles WHERE user_id = @user_id AND vehicle = @vehicle")
23MySQL.createCommand("vRP/remove_allvehicle","DELETE FROM vrp_user_vehicles WHERE user_id = @user_id")
24MySQL.createCommand("vRP/get_vehicles","SELECT vehicle,pound_price,fuel,engine FROM vrp_user_vehicles WHERE user_id = @user_id")
25MySQL.createCommand("vRP/get_vehicle","SELECT vehicle FROM vrp_user_vehicles WHERE user_id = @user_id AND vehicle = @vehicle")
26MySQL.createCommand("vRP/change_garage","UPDATE vrp_user_vehicles SET is_out = @state, garage_id= @gar_id WHERE user_id = @user_id AND vehicle = @model")
27MySQL.createCommand("vRP/delete_destoyedveh","DELETE FROM vrp_user_vehicles WHERE user_id = @user_id AND vehicle = @model")
28MySQL.createCommand("vRP/update_garage","UPDATE vrp_user_vehicles SET is_out = @state WHERE user_id = @user_id AND vehicle = @model")
29MySQL.createCommand("vRP/activate_cd","UPDATE vrp_user_vehicles SET is_out = @state, wait_time= @cd WHERE user_id = @user_id AND vehicle = @model")
30MySQL.createCommand("vRP/disable_cd","UPDATE vrp_user_vehicles SET wait_time= @cd WHERE user_id = @user_id AND vehicle = @model")
31MySQL.createCommand("vRP/get_out_vehicles","SELECT * FROM vrp_user_vehicles WHERE is_out = 1")
32MySQL.createCommand("vRP/reset_cd","UPDATE vrp_user_vehicles SET wait_time= @cd, is_out = 0 WHERE is_out = 1 or wait_time != @cd")
33MySQL.createCommand("vRP/set_pound","UPDATE vrp_user_vehicles SET pound_price= @price, pound_info = @data WHERE vehicle LIKE @model AND user_id = @id")
34MySQL.createCommand("vRP/check_pound","SELECT * FROM vrp_user_vehicles WHERE user_id= @id AND pound_price!= 0")
35MySQL.createCommand("vRP/update_fuel","UPDATE vrp_user_vehicles SET fuel= @car_fuel WHERE vehicle LIKE @model AND user_id = @id")
36-- technical control
37MySQL.createCommand("vRP/set_tech_ctrl","UPDATE vrp_user_vehicles SET tech_ctrl = @date_tc WHERE vehicle LIKE @model AND vehicle_plate = @plate")
38MySQL.createCommand("vRP/get_tech_ctrl","SELECT * FROM vrp_user_vehicles WHERE vehicle LIKE @model AND vehicle_plate = @plate")
39-- Engine update
40MySQL.createCommand("vRP/update_engine","UPDATE vrp_user_vehicles SET engine = @engine WHERE vehicle = @model AND user_id = @id")
41-- init
42--MySQL.query("vRP/add_technical_ctrl")
43--MySQL.query("vRP/delete_technical_ctrl")
44MySQL.query("vRP/vehicles_table")
45
46-- load config
47
48local cfg = module("cfg/garages")
49local cfg_base = module("cfg/base")
50local cfg_inventory = module("cfg/inventory")
51local vehicle_groups = cfg.garage_types
52local vehicle_showroom = cfg.showroom
53local lang = vRP.lang
54
55local garages = cfg.garages
56
57local server_vehicles = {}
58local server_dead_vehicles = {}
59local freezed_vehicles = {}
60
61local out_vehicle_cd = 900 -- 15 minutes in seconds
62
63-- garage menus
64
65local garage_menus = {}
66
67for group,vehicles in pairs(vehicle_groups) do
68 local veh_type = vehicles._config.vtype or "default"
69
70 local menu = {
71 name=lang.garage.title({group}),
72 css={top = "75px", header_color="rgba(255,125,0,0.75)"}
73 }
74 garage_menus[group] = menu
75 if group ~= "Vente" then
76 menu[lang.garage.owned.title()] = {function(player,choice)
77 local user_id = vRP.getUserId(player)
78 if user_id ~= nil then
79 -- init tmpdata for rents
80 local tmpdata = vRP.getUserTmpTable(user_id)
81 if tmpdata.rent_vehicles == nil then
82 tmpdata.rent_vehicles = {}
83 end
84
85
86 -- build nested menu
87 local kitems = {}
88
89 local submenu = {name=lang.garage.title({lang.garage.owned.title()}), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
90
91 submenu.onclose = function()
92 vRP.openMenu(player,menu)
93 end
94
95 local pound = {}
96 local fuels = {}
97 local engine = {}
98 local choose = function(player, choice)
99 local vname = kitems[choice]
100 if vname then
101 -- spawn vehicle
102 local vehicle = vehicles[vname]
103 if vehicle then
104 vRP.closeMenu(player)
105 if group ~= "Vente" then
106 if pound[choice] == 0 or pound[choice] == nil then
107 -- if vRP.checkDeadVehicle(player,user_id,vname) then
108 vRPclient.spawnGarageVehicle(player,{veh_type,vname,fuels[choice],engine[choice]})
109 -- end
110 else
111 vRPclient.notify(player,{"~g~Ce véhicule est en fourriere"})
112 end
113 end
114 end
115 end
116 end
117
118 -- get player owned vehicles
119 MySQL.query("vRP/get_vehicles", {user_id = user_id}, function(pvehicles, affected)
120 -- add rents to whitelist
121 for k,v in pairs(tmpdata.rent_vehicles) do
122 if v then -- check true, prevent future neolua issues
123 table.insert(pvehicles,{vehicle = k})
124 end
125 end
126
127 for k,v in pairs(pvehicles) do
128 local vehicle = vehicles[v.vehicle]
129 if vehicle then
130 pound[vehicle[1]] = v.pound_price
131 fuels[vehicle[1]] = v.fuel
132 submenu[vehicle[1]] = {choose,vehicle[3]}
133 kitems[vehicle[1]] = v.vehicle
134 engine[vehicle[1]] = v.engine
135 end
136 end
137
138 vRP.openMenu(player,submenu)
139 end)
140 end
141 end,lang.garage.owned.description()}
142 end
143 if group ~= "Vente" then
144 menu[lang.garage.buy.title()] = {function(player,choice)
145 local user_id = vRP.getUserId(player)
146 if user_id ~= nil then
147
148 -- build nested menu
149 local kitems = {}
150 local submenu = {name=lang.garage.title({lang.garage.buy.title()}), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
151 submenu.onclose = function()
152 vRP.openMenu(player,menu)
153 end
154
155 local choose = function(player, choice)
156 local vname = kitems[choice]
157 if vname then
158 -- buy vehicle
159 local vehicle = vehicles[vname]
160 if vehicle and vRP.tryPayment(user_id,vehicle[2]) then
161 if group ~= "Lising" and (vRP.hasGroup(user_id,"Police") or vRP.hasGroup(user_id,"Ambulancier") or vRP.hasGroup(user_id,"Fbi") or
162 vRP.hasGroup(user_id,"Sheriff") or vRP.hasGroup(user_id,"Juge")) then
163 -- for gov salaries, they need Government approval for vehicle bought !! --ladis : except for bicycle, etc...
164 TriggerEvent("governor:GovBoughtRequest",player,"vehicule",vname,vehicle[1])
165 vRPclient.notify(player,{lang.gov.request()})
166 vRP.closeMenu(player)
167 else
168 MySQL.query("vRP/add_vehicle", {user_id = user_id, vehicle = vname})
169
170 vRPclient.notify(player,{lang.money.paid({vehicle[2]})})
171 vRP.closeMenu(player)
172 end
173 else
174 vRPclient.notify(player,{lang.money.not_enough()})
175 end
176 end
177 end
178
179 -- get player owned vehicles (indexed by vehicle type name in lower case)
180 MySQL.query("vRP/get_vehicles", {user_id = user_id}, function(_pvehicles, affected)
181 local pvehicles = {}
182 local rank = vRP.getRank(user_id)
183 for k,v in pairs(_pvehicles) do
184 pvehicles[string.lower(v.vehicle)] = true
185 end
186
187 -- for each existing vehicle in the garage group
188 for k,v in pairs(vehicles) do
189 if k ~= "_config" and pvehicles[string.lower(k)] == nil then -- not already owned
190 if not v[4] or v[4] <= rank then
191 submenu[v[1]] = {choose,lang.garage.buy.info({v[2],v[3]})}
192 kitems[v[1]] = k
193 end
194 end
195 end
196
197 vRP.openMenu(player,submenu)
198 end)
199 end
200 end,lang.garage.buy.description()} end
201
202 menu[lang.garage.sell.title()] = {function(player,choice)
203 -- Added by bloopis
204 if group == "Vente" then
205 -- this process is only for showroom vehicle in special shop !
206 -- fill vehicles array with showromm vehicles
207 for k,v in pairs(vehicle_showroom) do
208 if k ~= "véhicules" then
209 -- remove useless entry
210 vehicles["empty"] = nil
211 for name,veh in pairs(v.buttons) do
212 -- for each vehicles we fill array
213 vehicles[veh.model] = {veh.name,veh.costs,"",veh.vtype}
214 end
215 end
216 end
217 end
218
219 local user_id = vRP.getUserId(player)
220 if user_id ~= nil then
221
222 -- build nested menu
223 local kitems = {}
224 local submenu = {name=lang.garage.title({lang.garage.sell.title()}), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
225 submenu.onclose = function()
226 vRP.openMenu(player,menu)
227 end
228
229 local choose = function(player, choice)
230 local vname = kitems[choice]
231 if vname then
232
233 -- sell vehicle
234 local vehicle = vehicles[vname]
235 if vehicle then
236 local price = math.ceil(vehicle[2]*cfg.sell_factor)
237
238 MySQL.query("vRP/get_vehicle", {user_id = user_id, vehicle = vname}, function(rows, affected)
239 if #rows > 0 then -- has vehicle
240 vRP.giveMoney(user_id,price)
241 MySQL.query("vRP/remove_vehicle", {user_id = user_id, vehicle = vname})
242
243 vRPclient.notify(player,{lang.money.received({price})})
244 vRP.closeMenu(player)
245 if group == "Vente" then
246 -- vRPclient.despawnGarageVehicle(player,{vehicle[4],15,nil})
247 vRPclient.despawnGarageVehicle(player,{vehicle[4],15})
248 TriggerClientEvent('ply_garages:forceUpdate', player)
249 else
250 -- vRPclient.despawnGarageVehicle(player,{veh_type,15,nil})
251 vRPclient.despawnGarageVehicle(player,{veh_type,15})
252 end
253
254 if vRP.hasGroup(user_id,"Police") or vRP.hasGroup(user_id,"Ambulancier") or vRP.hasGroup(user_id,"Fbi") or
255 vRP.hasGroup(user_id,"Sheriff") or vRP.hasGroup(user_id,"Juge") and group ~= "Vente" then
256 vRP.sellGovProduct("vehicule",vname)
257 end
258 else
259 vRPclient.notify(player,{lang.common.not_found()})
260 end
261 end)
262 end
263 end
264 end
265
266 -- get player owned vehicles (indexed by vehicle type name in lower case)
267 MySQL.query("vRP/get_vehicles", {user_id = user_id}, function(_pvehicles, affected)
268 local pvehicles = {}
269 for k,v in pairs(_pvehicles) do
270 pvehicles[string.lower(v.vehicle)] = true
271 end
272
273 -- for each existing vehicle in the garage group
274 for k,v in pairs(pvehicles) do
275 local vehicle = vehicles[k]
276 if vehicle then -- not already owned
277 local price = math.ceil(vehicle[2]*cfg.sell_factor)
278 submenu[vehicle[1]] = {choose,lang.garage.buy.info({price,vehicle[3]})}
279 kitems[vehicle[1]] = k
280 end
281 end
282
283 vRP.openMenu(player,submenu)
284 end)
285 end
286 end,lang.garage.sell.description()}
287 if group ~= "Vente" then
288 menu[lang.garage.rent.title()] = {function(player,choice)
289 local user_id = vRP.getUserId(player)
290 if user_id ~= nil then
291 if vRP.hasGroup(user_id,"Police") or vRP.hasGroup(user_id,"Ambulancier") or vRP.hasGroup(user_id,"Fbi") or vRP.hasGroup(user_id,"Sheriff") or vRP.hasGroup(user_id,"Juge") then
292 vRPclient.notify(player,{lang.gov.gov_rent()})
293 else
294 -- init tmpdata for rents
295 local tmpdata = vRP.getUserTmpTable(user_id)
296 if tmpdata.rent_vehicles == nil then
297 tmpdata.rent_vehicles = {}
298 end
299
300 -- build nested menu
301 local kitems = {}
302 local submenu = {name=lang.garage.title({lang.garage.rent.title()}), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
303 submenu.onclose = function()
304 vRP.openMenu(player,menu)
305 end
306
307 local choose = function(player, choice)
308 local vname = kitems[choice]
309 if vname then
310 -- rent vehicle
311 local vehicle = vehicles[vname]
312 if vehicle then
313 local price = math.ceil(vehicle[2]*cfg.rent_factor)
314 if vRP.tryPayment(user_id,price) then
315 -- add vehicle to rent tmp data
316 tmpdata.rent_vehicles[vname] = true
317
318 vRPclient.notify(player,{lang.money.paid({price})})
319 vRP.closeMenu(player)
320 else
321 vRPclient.notify(player,{lang.money.not_enough()})
322 end
323 end
324 end
325 end
326
327 -- get player owned vehicles (indexed by vehicle type name in lower case)
328 MySQL.query("vRP/get_vehicles", {user_id = user_id}, function(_pvehicles, affected)
329 local pvehicles = {}
330 for k,v in pairs(_pvehicles) do
331 pvehicles[string.lower(v.vehicle)] = true
332 end
333
334 -- add rents to blacklist
335 for k,v in pairs(tmpdata.rent_vehicles) do
336 pvehicles[string.lower(k)] = true
337 end
338
339 -- for each existing vehicle in the garage group
340 for k,v in pairs(vehicles) do
341 if k ~= "_config" and pvehicles[string.lower(k)] == nil then -- not already owned
342 local price = math.ceil(v[2]*cfg.rent_factor)
343 submenu[v[1]] = {choose,lang.garage.buy.info({price,v[3]})}
344 kitems[v[1]] = k
345 end
346 end
347
348 vRP.openMenu(player,submenu)
349 end)
350 end
351 end
352 end,lang.garage.rent.description()}
353 end
354
355 if group ~= "Vente" then
356 menu[lang.garage.store.title()] = {function(player,choice)
357 --[[local gar_id = nil
358 if garages[group] then
359 -- get the current garage ID
360 gar_id = garages[group].garage_ID
361 end
362
363 vRPclient.despawnGarageVehicle(player,{veh_type,15,gar_id}) ]]
364 vRPclient.despawnGarageVehicle(player,{veh_type,15})
365 end, lang.garage.store.description()}
366 end
367end
368
369function vRP.GovVehicleBought(player,user_id,vname)
370 MySQL.query("vRP/add_vehicle", {user_id = user_id, vehicle = vname})
371 vRPclient.notify(player,{lang.gov.request_accepted()})
372end
373
374function build_client_garages(source)
375 local user_id = vRP.getUserId(source)
376 if user_id ~= nil then
377 for k,v in pairs(garages) do
378 local gtype,x,y,z = table.unpack(v)
379
380 local group = vehicle_groups[gtype]
381 if group then
382 local gcfg = group._config
383
384 -- enter
385 local garage_enter = function(player,area)
386 local user_id = vRP.getUserId(source)
387 if user_id ~= nil and vRP.hasPermissions(user_id,gcfg.permissions or {}) then
388 local menu = garage_menus[gtype]
389 if menu then
390 vRP.openMenu(player,menu)
391 end
392 end
393 end
394
395 -- leave
396 local garage_leave = function(player,area)
397 vRP.closeMenu(player)
398 end
399
400 vRPclient.addBlip(source,{x,y,z,gcfg.blipid,gcfg.blipcolor,lang.garage.title({gtype})})
401 vRPclient.addMarker(source,{x,y,z-1,0.7,0.7,0.5,0,255,125,125,150})
402
403 vRP.setArea(source,"vRP:garage"..k,x,y,z,1,1.5,garage_enter,garage_leave)
404 end
405 end
406 end
407end
408
409
410-- VEHICLE MENU
411
412-- define vehicle actions
413-- action => {cb(user_id,player,veh_group,veh_name),desc}
414local veh_actions = {}
415
416-- open trunk
417veh_actions[lang.vehicle.trunk.title()] = {function(user_id,player,vtype,name)
418 local chestname = "u"..user_id.."veh_"..string.lower(name)
419 local max_weight = cfg_inventory.vehicle_chest_weights[string.lower(name)] or cfg_inventory.default_vehicle_chest_weight
420
421 vRPclient.getUserVehicle(player,{vtype},function(veh, allow_chest)
422 if veh then -- check if vehicle exist
423 if allow_chest then
424 -- open chest
425 vRPclient.vc_openDoor(player, {vtype,5})
426 vRP.openChest(player, chestname, max_weight, function()
427 vRPclient.vc_closeDoor(player, {vtype,5})
428 end)
429 else
430 -- car is dead we need to clean chest !!
431 vRP.clearDeadChest(chestname)
432 vRPclient.notify(player,{lang.vehicle.no_extract_items()})
433 end
434 end
435 end)
436end, lang.vehicle.trunk.description()}
437
438-- detach trailer
439veh_actions[lang.vehicle.detach_trailer.title()] = {function(user_id,player,vtype,name)
440 vRPclient.vc_detachTrailer(player, {vtype})
441end, lang.vehicle.detach_trailer.description()}
442
443-- detach towtruck
444veh_actions[lang.vehicle.detach_towtruck.title()] = {function(user_id,player,vtype,name)
445 vRPclient.vc_detachTowTruck(player, {vtype})
446end, lang.vehicle.detach_towtruck.description()}
447-- detach cargobob
448veh_actions[lang.vehicle.detach_cargobob.title()] = {function(user_id,player,vtype,name)
449 vRPclient.vc_detachCargobob(player, {vtype})
450end, lang.vehicle.detach_cargobob.description()}
451
452-- lock/unlock
453veh_actions[lang.vehicle.lock.title()] = {function(user_id,player,vtype,name)
454 vRPclient.vc_toggleLock(player, {vtype})
455end, lang.vehicle.lock.description()}
456
457-- engine on/off
458veh_actions[lang.vehicle.engine.title()] = {function(user_id,player,vtype,name)
459 vRPclient.vc_toggleEngine(player, {vtype})
460end, lang.vehicle.engine.description()}
461
462-- Check the technical control date
463local function ch_check_tech_ctrl(player)
464 vRPclient.getNearestVehiclePound(player,{5},function(plate,model)
465 -- checking plate
466 if plate then
467 local model_src = "%"..model.."%"
468 -- the plate exist on the server -> belongs to a player
469 MySQL.query("vRP/get_tech_ctrl", {model=model_src, plate=plate}, function(pvehicles, affected)
470 if #pvehicles > 0 then --get the first found vehicle
471 local last_ctrl_date = pvehicles[1].tech_ctrl
472 --print(last_ctrl_date)
473 if type(last_ctrl_date) == "string" then
474 vRPclient.notify(player,{"~g~Date du dernier controle : ~o~"..last_ctrl_date})
475 else
476 vRPclient.notify(player,{"~r~Aucun controle n'est enregistré sur ce véhicule"})
477 end
478 else
479 vRPclient.notify(player,{"~r~Ce vehicule est exempté de controle technique (pré-reforme plaques immatriculation)"})
480 end
481 end)
482 end
483 end)
484end
485
486-- set the technical control date
487local function ch_set_tech_ctrl(player)
488 vRPclient.getNearestVehiclePound(player,{5},function(plate,model)
489 -- checking plate
490 if plate then
491 if server_vehicles[plate] then
492 local model_src = "%"..model.."%"
493 local new_date = os.date("%d-%m-%Y")
494 -- the plate exist on the server -> belongs to a player
495 MySQL.query("vRP/set_tech_ctrl", {date_tc=new_date, model=model_src, plate=plate})
496 vRPclient.playAnim(player,{ false, {task="CODE_HUMAN_MEDIC_TIME_OF_DEATH"}, true })
497 vRPclient.notify(player,{"~b~Ecriture de la nouvelle date sur le controle.."})
498 Citizen.Wait(3000)
499 vRPclient.notify(player,{"~b~Vous avez indiqué la date suivante : "..new_date})
500 Citizen.Wait(1000)
501 TriggerEvent("anim:stopAnim")
502 end
503 end
504 end)
505end
506
507
508-- ask cop trunk (open other user car chest)
509local function ch_copasktrunk(player,choice)
510 vRPclient.getNearestVehiclePound(player,{10},function(plate,model)
511 local user_id = vRP.getUserId(player)
512 if (model ~= nil and plate ~= nil) then
513 vRP.getUserByRegistration(plate, function(nuser_id)
514 if nuser_id ~= nil then
515 local chestname = "u"..nuser_id.."veh_"..string.lower(model)
516 local max_weight = cfg_inventory.vehicle_chest_weights[string.lower(model)] or cfg_inventory.default_vehicle_chest_weight
517 local cb_out = function(idname,amount)
518 vRPclient.notify(player,{lang.inventory.give.given({vRP.getItemName(idname),amount})})
519 end
520 local cb_in = function(idname,amount)
521 vRPclient.notify(player,{lang.inventory.give.received({vRP.getItemName(idname),amount})})
522 end
523 vRP.openChest(player, chestname, max_weight, function()
524 end,cb_in,cb_out)
525 end
526 end)
527 end
528 end)
529end
530
531local function ch_open_other_trunk(player,nplayer,nuser_id)
532 vRPclient.getNearestOwnedVehicle(nplayer,{7},function(ok,vtype,name)
533 if ok then
534 local chestname = "u"..nuser_id.."veh_"..string.lower(name)
535 local max_weight = cfg_inventory.vehicle_chest_weights[string.lower(name)] or cfg_inventory.default_vehicle_chest_weight
536
537 -- open chest
538 local cb_out = function(idname,amount)
539 vRPclient.notify(nplayer,{lang.inventory.give.given({vRP.getItemName(idname),amount})})
540 end
541
542 local cb_in = function(idname,amount)
543 vRPclient.notify(nplayer,{lang.inventory.give.received({vRP.getItemName(idname),amount})})
544 end
545
546 vRPclient.getUserVehicle(nplayer,{vtype},function(veh, allow_chest)
547 if veh then
548 if allow_chest then
549 vRPclient.vc_openDoor(nplayer, {vtype,5})
550 vRP.openChest(player, chestname, max_weight, function()
551 vRPclient.vc_closeDoor(nplayer, {vtype,5})
552 end,cb_in,cb_out)
553 else
554 -- car is dead we need to clean chest !!
555 vRP.clearDeadChest(chestname)
556 vRPclient.notify(player,{lang.vehicle.no_extract_items()})
557 vRPclient.notify(nplayer,{lang.vehicle.no_extract_items()})
558 end
559 end
560 end)
561 else
562 vRPclient.notify(player,{lang.vehicle.no_owned_near()})
563 vRPclient.notify(nplayer,{lang.vehicle.no_owned_near()})
564 end
565 end)
566end
567
568-- ask trunk (open other user car chest)
569local function ch_asktrunk(player,choice)
570 vRPclient.getNearestPlayer(player,{10},function(nplayer)
571 local nuser_id = vRP.getUserId(nplayer)
572 local user_id = vRP.getUserId(player)
573 if nuser_id ~= nil then
574 vRPclient.notify(player,{lang.vehicle.asktrunk.asked()})
575 vRP.request(nplayer,lang.vehicle.asktrunk.request(),15,function(nplayer,ok)
576 if ok then -- request accepted, open trunk
577 ch_open_other_trunk(player,nplayer,nuser_id)
578 else
579 vRPclient.notify(player,{lang.common.request_refused()})
580 end
581 end)
582 else
583 vRPclient.notify(player,{lang.common.no_player_near()})
584 end
585 end)
586end
587
588
589local ch_force_free = {function(player, choice)
590 vRPclient.getNearestOwnedVehicle(player,{7},function(ok,vtype,name)
591 if ok then
592 local user_id = vRP.getUserId(player)
593 if user_id then
594 local chestname = "u"..user_id.."veh_"..string.lower(name)
595 vRP.forceFreeChest(player,chestname,true)
596 end
597 else
598 vRPclient.notify(player,{lang.vehicle.no_owned_near()})
599 end
600 end)
601end}
602
603local function ch_vehicle(player,choice)
604 local user_id = vRP.getUserId(player)
605 if user_id ~= nil then
606 -- check vehicle
607 vRPclient.getNearestOwnedVehicle(player,{7},function(ok,vtype,name)
608 -- build vehicle menu
609 local menu = {name=lang.vehicle.title(), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
610
611 menu[lang.common.object.clear().."(1m)"] = {function(player,choice) TriggerClientEvent("object:removeNear",player) end, lang.common.object.clear_near()}
612 if vRP.hasGroup(user_id,"admin") then
613 menu[lang.common.object.clear().."(20m)"] = {function(player,choice) TriggerClientEvent("object:removeLarge",player) end, lang.common.object.clear_large()}
614 end
615 -- add ask trunk
616 menu[lang.vehicle.asktrunk.title()] = {ch_asktrunk}
617
618 if vRP.hasGroup(user_id,"Police") then
619 menu["Police ouverture coffre"] = {ch_copasktrunk}
620 end
621 -- Set the technical control date
622
623 -- Check the technical control date
624 menu["Regarder le controle technique"] = {function(player,choice)
625 ch_check_tech_ctrl(player)
626 end, "Affiche la date du dernier controle"}
627
628 -- if mecano -> possibility to set the ctrl date
629 if vRP.hasPermission(user_id,"repair.set_tech_ctrl_date") then
630 menu["Faire le controle technique"] = {function(player,choice)
631
632 ch_set_tech_ctrl(player)
633 -- else
634 -- vRPclient.notify(player,{"~r~Tu n'a pas autorite a changer la date du controle technique !"})
635 -- end
636 end, "Mettre la date du jour sur le controle technique"}
637 end
638
639 if ok then
640 menu[lang.vehicle.free_trunk()] = ch_force_free
641
642
643 for k,v in pairs(veh_actions) do
644 menu[k] = {function(player,choice) v[1](user_id,player,vtype,name) end, v[2]}
645 end
646 else
647 vRPclient.notify(player,{lang.vehicle.no_owned_near()})
648 end
649
650 local _player = player
651 vRPclient.isInComa(_player,{}, function(in_coma)
652 if not in_coma then
653 vRP.openMenu(_player,menu)
654 end
655 end)
656 end)
657 end
658end
659
660local function set_pound(user_id,model,pound_price,pound_info)
661 model = "%"..model.."%"
662 MySQL.query("vRP/set_pound", {model = model, id = user_id, price = pound_price, data = pound_info})
663end
664
665local function ch_pound(player,choice)
666 local player_id = vRP.getUserId(player)
667
668 vRPclient.getNearestVehiclePound(player,{5},function(plate,model)
669
670 -- checking plate
671 if plate then
672 if server_vehicles[plate] then
673 for key,veh_table in pairs(server_vehicles[plate]) do
674 -- we look for the model of vehicle
675 -- (model depends on the vtype so while we are with 1 vehicle out max by vtype we are good !!)
676 if veh_table[7] == model then
677 -- get user_id
678 target_id = veh_table[3]
679 -- print("BUBU vehicle found for "..target_id.." | "..model)
680
681 -- SQL pound
682 if target_id then
683 if target_id == player_id then
684 vRPclient.notify(player,{"~r~ Tu ne peux pas mettre ton véhicule en fourrière idiot !"})
685 else
686 vRP.prompt(player,"Montant de la mise en fourrière","",function(player, amount)
687 local amount_val = tonumber(amount)
688 if amount_val and amount_val > 0 then
689 local _date = os.date("%d/%m/%Y %H:%M:%S")
690
691 vRP.getUserIdentity(player_id, function(identity)
692 local name = identity.name.." "..identity.firstname
693
694 vRP.getBussinessPlayer(player_id, function(busi)
695 if busi then
696 local data = json.encode({busi.busi_id,busi.busi_name,name,_date})
697 -- call SQL
698 set_pound(target_id,model,amount_val,data)
699 vRPclient.deleteCar(player,{9})
700 else
701 vRPclient.notify(player,{"Vous n'êtes pas autorisé à faire ceci !"})
702 end
703 end)
704
705 end)
706
707 else
708 vRPclient.notify(player,{"Montant incorrect"})
709 end
710 end)
711 end
712 end
713
714 break
715 end
716 end
717 end
718 end
719
720 end)
721end
722
723local function ch_pound_reduction(player,choice)
724 vRPclient.getNearestPlayer(player,{10},function(nplayer)
725 local nuser_id = vRP.getUserId(nplayer)
726 if nuser_id ~= nil then
727 vRP.prompt(player,"Pourcentage de la reduction","",function(player, amount)
728 local amount_val = tonumber(amount)
729 if amount_val and amount_val > 0 and amount_val <= 100 then
730 local data = vRP.getUserDataTable(nuser_id)
731 if data then
732 data.pound_reduce = amount_val
733 vRPclient.notify(player,{"~g~La réduction à été appliqué au joueur le plus proche!"})
734 vRPclient.notify(nplayer,{"~g~Vous avez recu une réduction pour votre vehicule en fourriere!"})
735 else
736 vRPclient.notify(player,{"Erreur lors de la récupération des informations du joueur !"})
737 end
738 else
739 vRPclient.notify(player,{"Nombre incorrect !"})
740 end
741 end)
742 else
743 vRPclient.notify(player,{lang.common.no_player_near()})
744 end
745 end)
746end
747
748
749-- repair nearest vehicle
750local function ch_repair(player,choice)
751 local user_id = vRP.getUserId(player)
752 if user_id ~= nil then
753 -- anim and repair
754 if vRP.tryGetInventoryItem(user_id,"repairkit",1,true) then
755 vRPclient.playAnim(player,{false,{task="world_human_vehicle_mechanic"},false})
756 SetTimeout(15000, function()
757 vRPclient.fixeNearestVehicle(player,{7})
758 vRP.varyExp(user_id,"physical","mechanist",8)
759 vRPclient.stopAnim(player,{false})
760 end)
761 end
762 end
763end
764-- lockpick nearest vehicle
765local function ch_lockpick(player,choice)
766 local user_id = vRP.getUserId(player)
767 if user_id ~= nil then
768 -- anim and lockpick
769 if vRP.tryGetInventoryItem(user_id,"lockpick",1,true) then
770 vRPclient.getNearestVehicle(player,{5},function(veh)
771 if veh then
772 vRPclient.playAnim(player,{false,{task="WORLD_HUMAN_WELDING"},false})
773 SetTimeout(15000, function()
774 vRPclient.vc_lockPick(player,{veh})
775 vRPclient.stopAnim(player,{false})
776 end)
777 end
778 end)
779 end
780 end
781end
782
783local function ch_refuel(player,choice)
784 local user_id = vRP.getUserId(player)
785 if user_id ~= nil then
786 -- anim and repair
787 if vRP.tryGetInventoryItem(user_id,"jerrycan",1,true) then
788 vRPclient.getNearestVehicle(player,{7},function(veh)
789 if veh then
790 vRPclient.playAnim(player,{false,{{"weapons@misc@jerrycan@","fire",1}},true})
791 TriggerClientEvent("essence:refuel", player, 20, veh)
792 SetTimeout(16000, function()
793 vRPclient.stopAnim(player,{false})
794 end)
795 end
796 end)
797 end
798 end
799end
800
801local function ch_freeze(player,choice)
802 local user_id = vRP.getUserId(player)
803 if user_id ~= nil then
804 vRPclient.playAnim(player,{false,{{"amb@medic@standing@kneel@base","base",1}},true})
805 SetTimeout(7000, function()
806 vRPclient.freezeNearestVehicle(player,{7,true})
807 vRPclient.stopAnim(player,{false})
808 end)
809 end
810end
811
812local function ch_unfreeze(player,choice)
813 local user_id = vRP.getUserId(player)
814 if user_id ~= nil then
815 vRPclient.playAnim(player,{false,{{"amb@medic@standing@kneel@base","base",1}},true})
816 SetTimeout(7000, function()
817 vRPclient.freezeNearestVehicle(player,{7,false})
818 vRPclient.stopAnim(player,{false})
819 end)
820 end
821end
822
823-- replace nearest vehicle
824local function ch_replace(player,choice)
825 vRPclient.replaceNearestVehicle(player,{7})
826end
827
828local function ch_tow(player,choice)
829 TriggerClientEvent("towVehicle", player)
830end
831
832local function ch_fix(player,choice)
833 TriggerClientEvent("towVehicle", player)
834end
835
836local function ch_repair_menu(player,choice)
837 local user_id = vRP.getUserId(player)
838 if user_id ~= nil then
839 -- build repair menu
840 local menu = {name=lang.vehicle.repair_menu(), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
841
842 -- add repair functions
843 if vRP.hasPermission(user_id, "vehicle.repair") then
844 menu[lang.vehicle.repair.title()] = {ch_repair, lang.vehicle.repair.description()}
845 end
846
847 if vRP.hasPermission(user_id, "vehicle.lock") then
848 menu[lang.vehicle.lock.title()] = {ch_lockpick, lang.vehicle.lock.description()}
849 end
850
851 if vRP.hasPermission(user_id, "vehicle.tow") then
852 menu[lang.vehicle.tow.title()] = {ch_tow, lang.vehicle.tow.description()}
853 end
854
855 if vRP.hasPermission(user_id, "vehicle.fix") then
856 menu[lang.vehicle.fix.title()] = {ch_fix, lang.vehicle.fix.description()}
857 end
858
859 if vRP.hasPermission(user_id, "vehicle.replace") then
860 menu[lang.vehicle.replace.title()] = {ch_replace, lang.vehicle.replace.description()}
861 end
862 --[[
863 if vRP.hasPermission(user_id, "vehicle.refuel") then
864 menu[lang.vehicle.refuel.title()] = {ch_refuel, lang.vehicle.refuel.description()}
865 end
866 ]]--
867 if vRP.hasPermission(user_id, "vehicle.pound") then
868 menu["Mise en fourrière"] = {ch_pound, "Permet de mettre le véhicule le plus proche en fourrière."}
869 end
870 if vRP.hasPermission(user_id, "vehicle.pound") then
871 menu["Appliquer une reduction"] = {ch_pound_reduction, "Met une réduction en pourcentage pour la sortie de la mise en fourriere"}
872 end
873
874 if vRP.hasPermission(user_id, "vehicle.freeze") then
875 menu[lang.vehicle.freeze.title()] = {ch_freeze, lang.vehicle.freeze.description()}
876 menu[lang.vehicle.freeze.titleR()] = {ch_unfreeze, lang.vehicle.freeze.descriptionR()}
877 end
878
879 local _player = player
880 vRPclient.isInComa(_player,{}, function(in_coma)
881 if not in_coma then
882 vRP.openMenu(_player,menu)
883 end
884 end)
885 end
886end
887
888vRP.registerMenuBuilder("main", function(add, data)
889 local user_id = vRP.getUserId(data.player)
890 if user_id ~= nil then
891 -- add vehicle entry
892 local choices = {}
893 choices[lang.vehicle.title()] = {ch_vehicle}
894
895 if vRP.hasGroup(user_id,"Mecano") then
896 choices[lang.vehicle.repair_menu()] = {ch_repair_menu}
897 end
898
899 add(choices)
900 end
901end)
902
903
904-- Added by Bloopis
905-- enable to receive user event to lock car
906RegisterServerEvent('car:lockCar')
907AddEventHandler('car:lockCar', function()
908
909 -- check vehicle
910 vRPclient.getNearestOwnedVehicle(source,{7},function(ok,vtype,name)
911 if vtype ~= "cycle" then
912 if ok then
913 -- if there is a vehicle then lock it !
914 vRPclient.vc_toggleLock(source, {vtype})
915 else
916 vRPclient.notify(source,{lang.vehicle.no_owned_near()})
917 end
918 else
919 vRPclient.notify(source,{lang.vehicle.not_lockable_veh()})
920 end
921 end)
922end)
923
924local function change_garage(id,vehicle,garage_id)
925 MySQL.query("vRP/change_garage", {state = false, gar_id = garage_id, user_id = id, model = vehicle})
926end
927
928local function delete_destoyedveh(id,vehicle)
929 if id ~= nil and vehicle ~= nil then
930 MySQL.query("vRP/get_vehicle", {user_id = id, vehicle = vehicle}, function(rows, affected)
931 if #rows > 0 then -- has vehicle
932 MySQL.query("vRP/delete_destoyedveh", {state = false, user_id = id, model = vehicle})
933 PerformHttpRequest('https://discordapp.com/api/webhooks/381176897003847690/Q1u_k2JWpVTH0y5jEo5jjI0hHc7bqKXbly6ZBdI8baAStH_3gwEq1ZHL5UBXy8U2abkc', function(err, text, headers) end, 'POST',
934 json.encode({username = "Car checker",
935 content = "@here ["..os.date("%H:%M:%S %d/%m/%Y").."] Le vehicule du joueur <"..tostring(id).." > a ete detruit et supprimee de la base de donnee ( "..tostring(vehicle).." )."}),
936 { ['Content-Type'] = 'application/json' })
937 end
938 end)
939 end
940end
941
942
943local function activate_cd(id,vehicle)
944 local time = tostring(os.time())
945 MySQL.query("vRP/activate_cd", {state = false, cd = time, user_id = id, model = vehicle})
946end
947
948local function disable_cd(id,vehicle)
949 MySQL.query("vRP/disable_cd", {cd = "", user_id = id, model = vehicle})
950end
951
952local function reset_cd()
953 MySQL.query("vRP/reset_cd", {cd = ""})
954end
955
956local function update_garage(id,vehicle)
957 MySQL.query("vRP/update_garage", {state = true, user_id = id, model = vehicle})
958end
959
960local function get_pounded_veh(user_id, cbr)
961 local task = Task(cbr, {{}})
962 local pvehicles = {}
963 MySQL.query("vRP/check_pound", {id = user_id}, function(pvehicles, affected)
964 if #pvehicles > 0 then
965 local final_array = {}
966 for k,v in ipairs(pvehicles) do
967 local data = json.decode(v.pound_info)
968 table.insert(final_array,{price = v.pound_price,model = v.vehicle,busi_id = data[1],busi = data[2],name = data[3],date = data[4]})
969 end
970 return task({final_array})
971 else
972 return task()
973 end
974 end)
975end
976
977local function show_time(time)
978 local hour = math.floor(time/3600)
979 local minutes = math.floor((time % 3600)/60)
980 local secondes = time - (60 * minutes) - (3600 * hour)
981 return hour.." heures, "..minutes.." mins et "..secondes.." sec"
982end
983
984function vRP.checkDeadVehicle(player,user_id,vehicle)
985 -- print("BUBU CHECK DEAD VEHICLE "..user_id.." "..vehicle)
986 if server_dead_vehicles[user_id] then
987 if server_dead_vehicles[user_id][vehicle] == false then
988 vRPclient.notify(player,{"~r~Votre véhicule est déjà sorti. Vous ne pouvez pas utiliser deux fois le même !"})
989 return false
990 else
991 -- vehicle dead or not referrenced in array then we allow user to get new one
992 return true
993 end
994 else
995 return true
996 end
997end
998
999function vRP.initDeadVehicle(user_id,vehicle)
1000 -- print("BUBU INIT DEAD VEHICLE "..user_id.." "..vehicle)
1001 if not server_dead_vehicles[user_id] then
1002 server_dead_vehicles[user_id] = {}
1003 end
1004
1005 -- init vehicle dead value
1006 server_dead_vehicles[user_id][vehicle] = false
1007 -- print("BUBU INIT DEAD VEHICLE "..tostring(server_dead_vehicles[user_id][vehicle]))
1008end
1009
1010function vRP.removeDeadVehicle(user_id,vehicle)
1011 if server_dead_vehicles[user_id] then
1012 -- remove dead state for concerned vehicle
1013 server_dead_vehicles[user_id][vehicle] = nil
1014 -- print("BUBU REMOVE DEAD VEHICLE "..user_id.." "..vehicle.." "..tostring(server_dead_vehicles[user_id][vehicle]))
1015 end
1016end
1017
1018function vRP.resetDeadVehicle(source,user_id)
1019 if server_dead_vehicles[user_id] then
1020 -- remove dead state for concerned vehicle
1021 server_dead_vehicles[user_id]= nil
1022 vRPclient.notify(source,{"~g~Limitation garrage reset pour le joueur "..user_id})
1023 end
1024end
1025
1026function vRP.DeleteAllVeh(user_id)
1027 MySQL.query("vRP/remove_allvehicle", {user_id = user_id})
1028end
1029
1030function vRP.updateDeadVehicle(user_id,vehicle,plate)
1031 -- add car to dead cars table
1032 -- this will enable to get out vehicle from garage, else player can't "duplicate car"
1033 if server_dead_vehicles[user_id] then
1034 if server_dead_vehicles[user_id][vehicle] == nil then
1035 PerformHttpRequest('https://discordapp.com/api/webhooks/381176897003847690/Q1u_k2JWpVTH0y5jEo5jjI0hHc7bqKXbly6ZBdI8baAStH_3gwEq1ZHL5UBXy8U2abkc', function(err, text, headers) end, 'POST',
1036 json.encode({username = "Car checker",
1037 content = "@here ["..os.date("%H:%M:%S %d/%m/%Y").."] Le véhicule du joueur <"..tostring(user_id).." > n'as jamais été initialisé sur le serveur. De ce fait un potentiel glitch a pu être utilisé."}),
1038 { ['Content-Type'] = 'application/json' })
1039 end
1040
1041 server_dead_vehicles[user_id][vehicle] = true
1042 -- print("BUBU SET DEAD VEHICLE "..tostring(server_dead_vehicles[user_id][vehicle]))
1043 else
1044 PerformHttpRequest('https://discordapp.com/api/webhooks/381176897003847690/Q1u_k2JWpVTH0y5jEo5jjI0hHc7bqKXbly6ZBdI8baAStH_3gwEq1ZHL5UBXy8U2abkc', function(err, text, headers) end, 'POST',
1045 json.encode({username = "Car checker",
1046 content = "@here ["..os.date("%H:%M:%S %d/%m/%Y").."] Une erreur est survenue lors du changement de state du vehicule <"..tostring(vehicle).." > appartenant normalement au joueur ( "..tostring(user_id).." ). Plaque : "..tostring(plate)}),
1047 { ['Content-Type'] = 'application/json' })
1048
1049 -- init dead vehicle for owner vehicle
1050 server_dead_vehicles[user_id] = {}
1051 server_dead_vehicles[user_id][vehicle] = true
1052 -- print("BUBU SET DEAD VEHICLE 2"..tostring(server_dead_vehicles[user_id][vehicle]))
1053 end
1054end
1055
1056function vRP.checkAllowedVehicle(user_id,player,vehicle,current_gar)
1057 -- here we need to check if user is allowed to get vehicle from the current garage
1058
1059 -- security check
1060 if vehicle.garage_id == current_gar then
1061 if vehicle.is_out then
1062 -- the vehicle is already out (destroyed/reboot)!!!
1063 -- user can get him out gain
1064 -- initialize CD to get vehicle
1065 activate_cd(user_id,vehicle.vehicle)
1066 vRPclient.notify(player,{"~o~Votre véhicule est actuellement en transit. Vous devez attendre "..show_time(out_vehicle_cd)})
1067 if cfg_base.is_server_prod then
1068
1069 local chestname = "u"..user_id.."veh_"..string.lower(vehicle.vehicle)
1070 local bubu = "NULL"
1071 vRP.getSData("chest:"..chestname, function(cdata)
1072 -- we need to check if chest exist in DB
1073 chest = json.decode(cdata) or nil
1074
1075 if chest then
1076 bubu = "{"
1077
1078 for k,v in pairs(chest) do
1079 bubu = bubu.." "..k..":"..v.amount..","
1080 end
1081
1082 bubu = bubu.. " }"
1083 end
1084
1085 vRP.getUserIdentity(user_id, function(identity)
1086 PerformHttpRequest('https://discordapp.com/api/webhooks/381176897003847690/Q1u_k2JWpVTH0y5jEo5jjI0hHc7bqKXbly6ZBdI8baAStH_3gwEq1ZHL5UBXy8U2abkc', function(err, text, headers) end, 'POST',
1087 json.encode({username = "Car checker",
1088 content = "["..os.date("%H:%M:%S %d/%m/%Y").."] Le joueur < "..identity.name.." "..identity.firstname.." > ( "..user_id.." ) a essayé de sortir son véhicule [ "..vehicle.vehicle.." ] bloqué du garage "..current_gar..". Contenu du coffre : "..bubu}),
1089 { ['Content-Type'] = 'application/json' })
1090 end)
1091 end)
1092 end
1093 return false
1094 else
1095 local time = -1
1096 if vehicle.wait_time ~= "" then
1097 time = tonumber(vehicle.wait_time)
1098 end
1099
1100 if time == -1 or ((os.time() - time) > out_vehicle_cd) then
1101 -- user allowed to use vehicle
1102
1103 if time ~= -1 then
1104 -- reset time
1105 disable_cd(user_id,vehicle.vehicle)
1106 end
1107
1108 return true
1109 else
1110 local value = out_vehicle_cd - (os.time() - time)
1111 vRPclient.notify(player,{"~o~Votre véhicule est actuellement en transit. Vous devez attendre "..show_time(value)})
1112 return false
1113 end
1114 end
1115 else
1116 vRPclient.notify(player,{"~r~Le véhicule demandé n'est pas dans ce garage !!"})
1117 return false
1118 end
1119end
1120
1121RegisterServerEvent('car:out_garage')
1122AddEventHandler('car:out_garage', function(name)
1123 local _source = source
1124 local _name = name
1125 local user_id = vRP.getUserId(_source)
1126
1127 if user_id then
1128 update_garage(user_id,_name)
1129 end
1130end)
1131
1132-- TODO A voir pour thread pour clean values tout les 4 heures (A VOIR)
1133
1134-- arrayy overwiew
1135-- server_vehicles
1136-- | PLATEA
1137-- | INDEXA + VEH_TABLE
1138-- | INDEXB + VEH_TABLE
1139-- | PLATEB
1140-- | INDEXA + VEH_TABLE
1141
1142
1143-- Added by Bloopis
1144-- enable to save in server vehicles table the spawned car
1145RegisterServerEvent('car:SaveCar')
1146AddEventHandler('car:SaveCar', function(plate,identity_number,vtype,name,model,nveh,fuel)
1147 --get user ID for user
1148
1149 local user_id = vRP.getUserId(source)
1150 local chestname = "u"..user_id.."veh_"..string.lower(name)
1151
1152 if server_vehicles[plate] then
1153 local index = 0
1154 local found = false
1155
1156 for key,veh_table in pairs(server_vehicles[plate]) do
1157 -- with this check we are sure to have always higher key value in table
1158 if key >= index then
1159 -- index receive key + 1 because key represente a "real" index then with
1160 -- that, we are sure to get index which represent unique value at end of table
1161 index = key+1
1162 end
1163 -- we look for the vtype
1164 if veh_table[1] == vtype then
1165 --Citizen.Trace("ENTRY FOUND "..tostring(key).." INDEX "..tostring(index).." "..model.." \n")
1166
1167 -- replace value because (for the moment) we can't spawn 2 vehicles of the same type (thanks god)
1168 server_vehicles[plate][key] = {vtype, source, user_id, chestname, identity_number, name, model, nveh,fuel}
1169 found = true
1170 break
1171 end
1172 end
1173
1174 if not found then
1175 --Citizen.Trace("ENTRY NOT FOUND SET NEW VALUE AT "..tostring(index).." "..model.." \n")
1176
1177 -- no result found for the vehicle then we add a new one
1178 server_vehicles[plate][index] = {vtype, source, user_id, chestname, identity_number, name, model, nveh,fuel}
1179 end
1180 else
1181 --Citizen.Trace("FIRST ENTRY "..model.." \n")
1182
1183 -- first car with this plate (it say that is the first car for user with )
1184 -- init a new array for this plate
1185 server_vehicles[plate] = {}
1186 server_vehicles[plate][0] = {vtype, source, user_id, chestname, identity_number, name, model, nveh,fuel}
1187 end
1188
1189 if user_id then
1190 vRP.initDeadVehicle(user_id,name)
1191 end
1192end)
1193
1194-- Added by Bloopis
1195-- enable to remove in server vehicles table the removed car
1196RegisterServerEvent('car:RemoveCar')
1197AddEventHandler('car:RemoveCar', function(plate,vtype,garage_id)
1198 local _source = source
1199 local _garage_id = garage_id
1200 local user_id = vRP.getUserId(_source)
1201
1202 if server_vehicles[plate] then
1203 for key,veh_table in pairs(server_vehicles[plate]) do
1204 --Citizen.Trace("KEY VALUES "..tostring(key).." \n")
1205
1206 -- we look for the
1207 if veh_table[1] == vtype then
1208 --Citizen.Trace("ENTRY FOUND REMOVE "..tostring(key).." \n")
1209 -- TriggerEvent('chest:storeClearChest',{_source, veh_table[6]})
1210 if _garage_id then
1211 -- change garage for vehicle
1212 change_garage(veh_table[3],veh_table[6],_garage_id)
1213 TriggerClientEvent('ply_garages:forceUpdate', _source)
1214 end
1215
1216 vRP.removeDeadVehicle(user_id,veh_table[6])
1217
1218 -- set to nil will remove entry from table
1219 server_vehicles[plate][key] = nil
1220 break
1221 end
1222 end
1223
1224 end
1225end)
1226
1227-- Added by Bloopis
1228-- enable to remove in server vehicles table the removed car
1229RegisterServerEvent('car:autoRemoveChest')
1230AddEventHandler('car:autoRemoveChest', function(veh_destroyed)
1231
1232 -- we will run over destroyed vehicles to get in server table
1233 for key,dest_veh_table in pairs(veh_destroyed) do
1234 -- checking plate
1235 if server_vehicles[dest_veh_table[1]] then
1236 for key,veh_table in pairs(server_vehicles[dest_veh_table[1]]) do
1237 --Citizen.Trace("PLATE FOUND CURRENT INDEX "..tostring(key).." \n")
1238 --Citizen.Trace(dest_veh_table[2].. " || "..veh_table[7] .." \n")
1239
1240 -- we look for the model of vehicle
1241 -- (model depends on the vtype so while we are with 1 vehicle out max by vtype we are good !!)
1242 if veh_table[7] == dest_veh_table[2] then
1243 --Citizen.Trace("VEHICLE FOUND READY TO RESET CHEST \n")
1244
1245 -- add car to dead cars table
1246 -- this will enable to get out vehicle from garage, else player can't "duplicate car"
1247 vRP.updateDeadVehicle(veh_table[3],veh_table[6],dest_veh_table[1])
1248
1249 -- deleting chest for this dead vehicle
1250 vRP.clearDeadChest(veh_table[4])
1251 delete_destoyedveh(veh_table[3],veh_table[6])
1252 break
1253 end
1254 end
1255
1256 end
1257 end
1258
1259end)
1260
1261-- Added by bloopis
1262-- get out vehicles for players
1263RegisterServerEvent('car:getCarAtSpawn')
1264AddEventHandler('car:getCarAtSpawn', function(plate)
1265 local _source = source
1266 local _plate = plate
1267
1268 -- when user come online we ask server if user vehicles are out (work with plates)
1269 if server_vehicles[_plate] then
1270 -- return table with vehicles
1271 TriggerClientEvent("car:initVehAtSpawn",_source, server_vehicles[_plate])
1272 end
1273
1274 -- load freezed vehicles
1275 TriggerClientEvent("car:initFreezedVehAtSpawn",_source, freezed_vehicles)
1276end)
1277
1278RegisterServerEvent('essence:badrefuel')
1279AddEventHandler('essence:badrefuel', function()
1280 local _source = source
1281 local user_id = vRP.getUserId(_source)
1282 vRPclient.stopAnim(_source,{false})
1283 vRPclient.notify(_source,{"~r~Le client doit être en dehors de son véhicule."})
1284 vRP.giveInventoryItem(user_id,"jerrycan",1,true)
1285end)
1286
1287RegisterServerEvent('car:setFreeze')
1288AddEventHandler('car:setFreeze', function(veh, state, id)
1289 local _veh = veh
1290 local _state = state
1291
1292 if state then
1293 -- fill array
1294 freezed_vehicles[id] = _veh
1295 else
1296 if freezed_vehicles[id] then
1297 -- clean array
1298 freezed_vehicles[id] = nil
1299 end
1300 end
1301 TriggerClientEvent("car:putfreeze",-1, _veh, _state)
1302end)
1303
1304-- Enable to get showromm cars
1305RegisterServerEvent('car:getShowroomCars')
1306AddEventHandler('car:getShowroomCars', function()
1307 local _source = source
1308 -- send showroom cars
1309 TriggerClientEvent("car:setShowroomCars",_source, vehicle_showroom)
1310end)
1311
1312RegisterServerEvent('car:resetAllCooldown')
1313AddEventHandler('car:resetAllCooldown', function(id)
1314 local user_id = id
1315 -- send reset in DB
1316 reset_cd()
1317
1318 if cfg_base.is_server_prod then
1319 vRP.getUserIdentity(user_id, function(identity)
1320 PerformHttpRequest('https://discordapp.com/api/webhooks/381176897003847690/Q1u_k2JWpVTH0y5jEo5jjI0hHc7bqKXbly6ZBdI8baAStH_3gwEq1ZHL5UBXy8U2abkc', function(err, text, headers) end, 'POST',
1321 json.encode({username = "Car checker",
1322 content = "["..os.date("%H:%M:%S %d/%m/%Y").."] RESET DES CD VEHICULES PAR l'ADMINITRASTEUR <"..identity.name.." "..identity.firstname.." > ( "..user_id.." )"}),
1323 { ['Content-Type'] = 'application/json' })
1324 end)
1325 end
1326end)
1327
1328
1329function check_vehicles()
1330 if cfg_base.is_server_prod then
1331 PerformHttpRequest('https://discordapp.com/api/webhooks/381176897003847690/Q1u_k2JWpVTH0y5jEo5jjI0hHc7bqKXbly6ZBdI8baAStH_3gwEq1ZHL5UBXy8U2abkc', function(err, text, headers) end, 'POST',
1332 json.encode({username = "Car checker", content = "=============VERIFICATION VEHICULES REDEMARAGE SERVER==============="}), { ['Content-Type'] = 'application/json' })
1333 Wait(500)
1334 PerformHttpRequest('https://discordapp.com/api/webhooks/381176897003847690/Q1u_k2JWpVTH0y5jEo5jjI0hHc7bqKXbly6ZBdI8baAStH_3gwEq1ZHL5UBXy8U2abkc', function(err, text, headers) end, 'POST',
1335 json.encode({username = "Car checker", content = " ================"..os.date("%H:%M:%S %d/%m/%Y").."==============="}), { ['Content-Type'] = 'application/json' })
1336 Wait(500)
1337
1338 MySQL.query("vRP/get_out_vehicles", {}, function(pvehicles, affected)
1339 if #pvehicles > 0 then
1340 for k,v in ipairs(pvehicles) do
1341
1342 local chestname = "u"..v.user_id.."veh_"..string.lower(v.vehicle)
1343 local bubu = "NULL"
1344 vRP.getSData("chest:"..chestname, function(cdata)
1345 -- we need to check if chest exist in DB
1346 chest = json.decode(cdata) or nil
1347
1348 if chest then
1349 bubu = "{"
1350
1351 for k,v in pairs(chest) do
1352 bubu = bubu.." "..k..":"..v.amount..","
1353 end
1354
1355 bubu = bubu.. " }"
1356 end
1357
1358 vRP.getUserIdentity(v.user_id, function(identity)
1359 PerformHttpRequest('https://discordapp.com/api/webhooks/381176897003847690/Q1u_k2JWpVTH0y5jEo5jjI0hHc7bqKXbly6ZBdI8baAStH_3gwEq1ZHL5UBXy8U2abkc', function(err, text, headers) end, 'POST',
1360 json.encode({username = "Car checker",
1361 content = "Le véhicule [ "..v.vehicle.." ] du joueur < "..identity.name.." "..identity.firstname.." > ( "..v.user_id.." ) été sorti au moment du restart SERVER. Contenu du coffre : "..bubu}),
1362 { ['Content-Type'] = 'application/json' })
1363 Wait(500)
1364 end)
1365 end)
1366
1367 end
1368 end
1369 end)
1370 end
1371end
1372SetTimeout(5000, check_vehicles)
1373
1374RegisterServerEvent('pound:OpenMenu')
1375AddEventHandler('pound:OpenMenu', function()
1376 local _source = source
1377 local user_id = vRP.getUserId(_source)
1378 if user_id then
1379 -- we need to get pounded cars
1380 get_pounded_veh(user_id, function(final_table)
1381 if final_table and #final_table > 0 then
1382 TriggerClientEvent("pound:activateMenu", _source, final_table)
1383 else
1384 vRPclient.notify(_source,{"~g~Pas de vehicule en fourriere."})
1385 end
1386 end)
1387 end
1388
1389end)
1390
1391RegisterServerEvent('fuel:saveFuel')
1392AddEventHandler('fuel:saveFuel', function(model_car, plate, fuel)
1393 local _source = source
1394 local _fuel = fuel
1395 local _plate = plate
1396 local _model = model_car
1397 local user_id = vRP.getUserId(_source)
1398
1399 Citizen.CreateThread(function()
1400
1401 if user_id then
1402 -- update server vehicle table
1403 if server_vehicles[_plate] then
1404 for key,veh_table in pairs(server_vehicles[_plate]) do
1405 -- we look for the model of vehicle
1406 if veh_table[7] == _model then
1407 -- print("FUEL VEHICLE REFRESH ".._model.." "..fuel)
1408 server_vehicles[_plate][key][9] = fuel
1409 -- print("FUEL VEHICLE REFRESH CHECK ".._model.." "..server_vehicles[_plate][key][9])
1410 break
1411 end
1412 end
1413 end
1414
1415 MySQL.query("vRP/update_fuel",{car_fuel = _fuel, model = _model,id = user_id})
1416 end
1417 end)
1418end)
1419
1420
1421RegisterServerEvent('pound:getCar')
1422AddEventHandler('pound:getCar', function(model,amount,busi_id,name)
1423 local _source = source
1424 local _model = model
1425 local _amount = amount
1426 local _busi_id = busi_id
1427 local _final_name = name
1428 local user_id = vRP.getUserId(_source)
1429
1430 if user_id then
1431 local amount_val = tonumber(_amount)
1432 if amount_val then
1433 -- apply RP reduction
1434 local data = vRP.getUserDataTable(user_id)
1435 if data then
1436 if data.pound_reduce ~= nil then
1437 if data.pound_reduce > 100 then
1438 data.pound_reduce = 100
1439 end
1440
1441 if data.pound_reduce < 0 then
1442 data.pound_reduce = 0
1443 end
1444
1445 if data.pound_reduce == 100 then
1446 amount_val = 0
1447 elseif data.pound_reduce == 0 then
1448 amount_val = amount_val
1449 else
1450 amount_val = amount_val - math.floor((amount_val * data.pound_reduce)/100)
1451 end
1452
1453 data.pound_reduce = nil
1454 end
1455
1456 if vRP.tryPayment(user_id,amount_val) then
1457 -- send taxe to town
1458 local pound_tax = vRP.getEarningValueByCat("pound_tax")
1459 if pound_tax > 30 then
1460 -- max 30 % of tax
1461 pound_tax = 30
1462 end
1463
1464 local tax_amount = math.floor((amount_val * pound_tax)/100)
1465
1466 if tax_amount > 0 then
1467 vRP.updateCityMoney(tax_amount)
1468 end
1469
1470 -- update final value
1471 if amount_val ~= 0 then
1472 amount_val = amount_val - tax_amount
1473 end
1474
1475 -- send money to business
1476 --if vRP.addBusiTreasury(_busi_id,amount_val) then
1477 if vRP.addMoneyBusiChest(_busi_id,amount_val) then --add new method
1478 -- add log for busi book
1479 vRP.addBookPound(_busi_id,amount_val,_final_name,user_id)
1480 end
1481
1482 local sqldata = json.encode({})
1483 -- call SQL
1484 set_pound(user_id,model,0,sqldata)
1485 vRPclient.notify(_source,{"~g~Votre véhicule est disponible dans son garage"})
1486 else
1487 vRPclient.notify(_source,{"~r~Vous n'avez pas assez d'argent sur vous !"})
1488 end
1489 end
1490 end
1491 end
1492end)
1493
1494RegisterServerEvent('save:engine')
1495AddEventHandler('save:engine', function(model,value)
1496 local _source = source
1497 local _model = model
1498 local _value = value
1499 local user_id = vRP.getUserId(_source)
1500 if user_id and _model ~= nil then
1501 MySQL.query("vRP/update_engine",{model = _model,id = user_id, engine = _value})
1502 end
1503end)
1504
1505-- ADD SELL VEHICULE TO OTHER PLAYER by DGVaniX
1506
1507MySQL.createCommand("vRP/sell_vehicle_player","UPDATE vrp_user_vehicles SET user_id = @user_id, vehicle_plate = @registration WHERE user_id = @oldUser AND vehicle = @vehicle")
1508
1509-- sell vehicle
1510veh_actions[lang.vehicle.sellTP.title()] = {function(playerID,player,vtype,name)
1511 if playerID ~= nil then
1512 vRPclient.getNearestPlayers(player,{15},function(nplayers)
1513 usrList = ""
1514 for k,v in pairs(nplayers) do
1515 usrList = usrList .. "[" .. vRP.getUserId(k) .. "]" .. GetPlayerName(k) .. " | "
1516 end
1517 if usrList ~= "" then
1518 vRP.prompt(player,"Players Nearby: " .. usrList .. "","",function(player,user_id)
1519 user_id = user_id
1520 if user_id ~= nil and user_id ~= "" then
1521 local target = vRP.getUserSource(tonumber(user_id))
1522 if target ~= nil then
1523 vRP.prompt(player,"Price $: ","",function(player,amount)
1524 if (tonumber(amount)) and (tonumber(amount) > 0) then
1525 MySQL.query("vRP/get_vehicle", {user_id = user_id, vehicle = name}, function(pvehicle, affected)
1526 if #pvehicle > 0 then
1527 vRPclient.notify(player,{"~r~The player already has this vehicle type."})
1528 else
1529 local tmpdata = vRP.getUserTmpTable(playerID)
1530 if tmpdata.rent_vehicles[name] == true then
1531 vRPclient.notify(player,{"~r~You cannot sell a rented vehicle!"})
1532 return
1533 else
1534 vRP.request(target,GetPlayerName(player).." wants to sell: " ..name.. " Price: $"..amount, 10, function(target,ok)
1535 if ok then
1536 local pID = vRP.getUserId(target)
1537 local money = vRP.getMoney(pID)
1538 if (tonumber(money) >= tonumber(amount)) then
1539 vRPclient.despawnGarageVehicle(player,{vtype,15})
1540 vRP.getUserIdentity(pID, function(identity)
1541 MySQL.execute("vRP/sell_vehicle_player", {user_id = user_id, registration = "P "..identity.registration, oldUser = playerID, vehicle = name})
1542 end)
1543 vRP.giveMoney(playerID, amount)
1544 vRP.setMoney(pID,money-amount)
1545 vRPclient.notify(player,{"~g~You have successfully sold the vehicle to ".. GetPlayerName(target).." for $"..amount.."!"})
1546 vRPclient.notify(target,{"~g~"..GetPlayerName(player).." has successfully sold you the car for $"..amount.."!"})
1547 else
1548 vRPclient.notify(player,{"~r~".. GetPlayerName(target).." doesn't have enough money!"})
1549 vRPclient.notify(target,{"~r~You don't have enough money!"})
1550 end
1551 else
1552 vRPclient.notify(player,{"~r~"..GetPlayerName(target).." has refused to buy the car."})
1553 vRPclient.notify(target,{"~r~You have refused to buy "..GetPlayerName(player).."'s car."})
1554 end
1555 end)
1556 end
1557 vRP.closeMenu(player)
1558 end
1559 end)
1560 else
1561 vRPclient.notify(player,{"~r~The price of the car has to be a number."})
1562 end
1563 end)
1564 else
1565 vRPclient.notify(player,{"~r~That ID seems invalid."})
1566 end
1567 else
1568 vRPclient.notify(player,{"~r~No player ID selected."})
1569 end
1570 end)
1571 else
1572 vRPclient.notify(player,{"~r~No player nearby."})
1573 end
1574 end)
1575 end
1576end, lang.vehicle.sellTP.description()}