· 6 years ago · Jul 18, 2019, 01:12 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(100),
8 CONSTRAINT pk_user_vehicles PRIMARY KEY(user_id,vehicle),
9 CONSTRAINT fk_user_vehicles_users FOREIGN KEY(user_id) REFERENCES vrp_users(id) ON DELETE CASCADE
10);
11]])
12
13MySQL.createCommand("vRP/add_vehicle","INSERT IGNORE INTO vrp_user_vehicles(user_id,vehicle) VALUES(@user_id,@vehicle)")
14MySQL.createCommand("vRP/remove_vehicle","DELETE FROM vrp_user_vehicles WHERE user_id = @user_id AND vehicle = @vehicle")
15MySQL.createCommand("vRP/get_vehicles","SELECT vehicle FROM vrp_user_vehicles WHERE veh_confiscate = 0 AND user_id = @user_id")
16MySQL.createCommand("vRP/get_vehicle","SELECT vehicle FROM vrp_user_vehicles WHERE user_id = @user_id AND vehicle = @vehicle")
17MySQL.createCommand("vRP/sell_vehicle_player","UPDATE vrp_user_vehicles SET user_id = @user_id, vehicle_plate = @registration WHERE user_id = @oldUser AND vehicle = @vehicle")
18
19
20-- init
21MySQL.execute("vRP/vehicles_table")
22
23-- load config
24
25local cfg = module("cfg/garages")
26local cfg_inventory = module("cfg/inventory")
27local vehicle_groups = cfg.garage_types
28local lang = vRP.lang
29
30local garages = cfg.garages
31
32-- garage menus
33
34local garage_menus = {}
35
36for group,vehicles in pairs(vehicle_groups) do
37 local veh_type = vehicles._config.vtype or "default"
38
39 local menu = {
40 name=lang.garage.title({group}),
41 css={top = "75px", header_color="rgba(255,125,0,0.75)"}
42 }
43 garage_menus[group] = menu
44
45 menu[lang.garage.owned.title()] = {function(player,choice)
46 local user_id = vRP.getUserId(player)
47 if user_id ~= nil then
48 -- init tmpdata for rents
49 local tmpdata = vRP.getUserTmpTable(user_id)
50 if tmpdata.rent_vehicles == nil then
51 tmpdata.rent_vehicles = {}
52 end
53
54
55 -- build nested menu
56 local kitems = {}
57 local submenu = {name=lang.garage.title({lang.garage.owned.title()}), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
58 submenu.onclose = function()
59 vRP.openMenu(player,menu)
60 end
61
62 local choose = function(player, choice)
63 local vname = kitems[choice]
64 if vname then
65 -- spawn vehicle
66 local vehicle = vehicles[vname]
67 if vehicle then
68 vRP.closeMenu(player)
69 TriggerEvent('ply_garages:CheckForSpawnBasicVeh', user_id, vname)
70 end
71 end
72 end
73
74 -- get player owned vehicles
75 MySQL.query("vRP/get_vehicles", {user_id = user_id}, function(pvehicles, affected)
76 -- add rents to whitelist
77 for k,v in pairs(tmpdata.rent_vehicles) do
78 if v then -- check true, prevent future neolua issues
79 table.insert(pvehicles,{vehicle = k})
80 end
81 end
82
83 for k,v in pairs(pvehicles) do
84 local vehicle = vehicles[v.vehicle]
85 if vehicle then
86 submenu[vehicle[1]] = {choose,vehicle[3]}
87 kitems[vehicle[1]] = v.vehicle
88 end
89 end
90
91 vRP.openMenu(player,submenu)
92 end)
93 end
94 end,lang.garage.owned.description()}
95
96 --[[ menu[lang.garage.buy.title()] = {function(player,choice)
97 local user_id = vRP.getUserId(player)
98 if user_id ~= nil then
99
100 -- build nested menu
101 local kitems = {}
102 local submenu = {name=lang.garage.title({lang.garage.buy.title()}), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
103 submenu.onclose = function()
104 vRP.openMenu(player,menu)
105 end
106
107 local choose = function(player, choice)
108 local vname = kitems[choice]
109 if vname then
110 -- buy vehicle
111 local vehicle = vehicles[vname]
112 if vehicle and vRP.tryPayment(user_id,vehicle[2]) then
113 MySQL.execute("vRP/add_vehicle", {user_id = user_id, vehicle = vname})
114
115 vRPclient.notify(player,{lang.money.paid({vehicle[2]})})
116 vRP.closeMenu(player)
117 else
118 vRPclient.notify(player,{lang.money.not_enough()})
119 end
120 end
121 end
122
123 -- get player owned vehicles (indexed by vehicle type name in lower case)
124 MySQL.query("vRP/get_vehicles", {user_id = user_id}, function(_pvehicles, affected)
125 local pvehicles = {}
126 for k,v in pairs(_pvehicles) do
127 pvehicles[string.lower(v.vehicle)] = true
128 end
129
130 -- for each existing vehicle in the garage group
131 for k,v in pairs(vehicles) do
132 if k ~= "_config" and pvehicles[string.lower(k)] == nil then -- not already owned
133 ]]--submenu[v[1]] = {choose,lang.garage.buy.info({v[2],v[3]})}
134 --kitems[v[1]] = k
135 --[[end
136 end
137
138 vRP.openMenu(player,submenu)
139 end)
140 end
141 end,lang.garage.buy.description()}
142]]
143
144 --[[menu[lang.garage.sell.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.sell.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 -- sell vehicle
159 local vehicle = vehicles[vname]
160 if vehicle then
161 local price = math.ceil(vehicle[2]*cfg.sell_factor)
162
163 vRPclient.notify(source,{"Asteapta 15 secunde."})
164 vRPclient.notify(source,{"Alvin e de vina."})
165 SetTimeout(15000, function()
166 MySQL.query("vRP/get_vehicle", {user_id = user_id, vehicle = vname}, function(rows, affected)
167 if #rows > 0 then -- has vehicle
168 vRP.giveMoney(user_id,price)
169 MySQL.execute("vRP/remove_vehicle", {user_id = user_id, vehicle = vname})
170
171 vRPclient.notify(player,{lang.money.received({price})})
172 vRP.closeMenu(player)
173 else
174 vRPclient.notify(player,{lang.common.not_found()})
175 end
176 end)
177 end)
178 end
179 end
180 end
181
182 -- get player owned vehicles (indexed by vehicle type name in lower case)
183 MySQL.query("vRP/get_vehicles", {user_id = user_id}, function(_pvehicles, affected)
184 local pvehicles = {}
185 for k,v in pairs(_pvehicles) do
186 pvehicles[string.lower(v.vehicle)] = true
187 end
188
189 -- for each existing vehicle in the garage group
190 for k,v in pairs(pvehicles) do
191 local vehicle = vehicles[k]
192 if vehicle then -- not already owned
193 local price = math.ceil(vehicle[2]*cfg.sell_factor)
194 submenu[vehicle[1]] --= {choose,lang.garage.buy.info({price,vehicle[3]})}
195 --[[kitems[vehicle[1]] --= k
196 --end
197 --end
198
199 --vRP.openMenu(player,submenu)
200 --end)
201 --end
202 --end,lang.garage.sell.description()}
203
204 --[[menu[lang.garage.rent.title()] = {function(player,choice)
205 local user_id = vRP.getUserId(player)
206 if user_id ~= nil then
207 -- init tmpdata for rents
208 local tmpdata = vRP.getUserTmpTable(user_id)
209 if tmpdata.rent_vehicles == nil then
210 tmpdata.rent_vehicles = {}
211 end
212
213 -- build nested menu
214 local kitems = {}
215 local submenu = {name=lang.garage.title({lang.garage.rent.title()}), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
216 submenu.onclose = function()
217 vRP.openMenu(player,menu)
218 end
219
220 local choose = function(player, choice)
221 local vname = kitems[choice]
222 if vname then
223 -- rent vehicle
224 local vehicle = vehicles[vname]
225 if vehicle then
226 local price = math.ceil(vehicle[2]*cfg.rent_factor)
227 if vRP.tryPayment(user_id,price) then
228 -- add vehicle to rent tmp data
229 tmpdata.rent_vehicles[vname] = true
230
231 vRPclient.notify(player,{lang.money.paid({price})})
232 vRP.closeMenu(player)
233 else
234 vRPclient.notify(player,{lang.money.not_enough()})
235 end
236 end
237 end
238 end
239
240 -- get player owned vehicles (indexed by vehicle type name in lower case)
241 MySQL.query("vRP/get_vehicles", {user_id = user_id}, function(_pvehicles, affected)
242 local pvehicles = {}
243 for k,v in pairs(_pvehicles) do
244 pvehicles[string.lower(v.vehicle)] = true
245 end
246
247 -- add rents to blacklist
248 for k,v in pairs(tmpdata.rent_vehicles) do
249 pvehicles[string.lower(k)] = true
250 end
251
252 -- for each existing vehicle in the garage group
253 for k,v in pairs(vehicles) do
254 if k ~= "_config" and pvehicles[string.lower(k)] == nil then -- not already owned
255 local price = math.ceil(v[2]*cfg.rent_factor)
256 submenu[v[1]] --= {choose,lang.garage.buy.info({price,v[3]})}
257 --kitems[v[1]] = k
258 --end
259 --end
260
261 --vRP.openMenu(player,submenu)
262 --end)
263 --end
264 --end,lang.garage.rent.description()}
265
266 menu[lang.garage.store.title()] = {function(player,choice)
267 vRPclient.despawnGarageVehicle(player,{veh_type,15})
268 end, lang.garage.store.description()}
269end
270
271local function build_client_garages(source)
272 local user_id = vRP.getUserId(source)
273 if user_id ~= nil then
274 for k,v in pairs(garages) do
275 local gtype,x,y,z = table.unpack(v)
276
277 local group = vehicle_groups[gtype]
278 if group then
279 local gcfg = group._config
280
281 -- enter
282 local garage_enter = function(player,area)
283 local user_id = vRP.getUserId(source)
284 if user_id ~= nil and vRP.hasPermissions(user_id,gcfg.permissions or {}) then
285 local menu = garage_menus[gtype]
286 if menu then
287 vRP.openMenu(player,menu)
288 end
289 end
290 end
291
292 -- leave
293 local garage_leave = function(player,area)
294 vRP.closeMenu(player)
295 end
296
297 vRPclient.addBlip(source,{x,y,z,gcfg.blipid,gcfg.blipcolor,lang.garage.title({gtype})})
298 vRPclient.addMarker(source,{x,y,z-1,0.7,0.7,0.5,0,255,125,125,150})
299
300 vRP.setArea(source,"vRP:garage"..k,x,y,z,1,1.5,garage_enter,garage_leave)
301 end
302 end
303 end
304end
305
306AddEventHandler("vRP:playerSpawn",function(user_id,source,first_spawn)
307 if first_spawn then
308 build_client_garages(source)
309 end
310end)
311
312-- VEHICLE MENU
313
314-- define vehicle actions
315-- action => {cb(user_id,player,veh_group,veh_name),desc}
316local veh_actions = {}
317
318-- open trunk
319veh_actions[lang.vehicle.trunk.title()] = {function(user_id,player,vtype,name)
320 local chestname = "u"..user_id.."veh_"..string.lower(name)
321 local max_weight = cfg_inventory.vehicle_chest_weights[string.lower(name)] or cfg_inventory.default_vehicle_chest_weight
322
323 -- open chest
324 vRPclient.vc_openDoor(player, {vtype,5})
325 vRP.openChest(player, chestname, max_weight, function()
326 vRPclient.vc_closeDoor(player, {vtype,5})
327 end)
328end, lang.vehicle.trunk.description()}
329
330-- detach trailer
331veh_actions[lang.vehicle.detach_trailer.title()] = {function(user_id,player,vtype,name)
332 vRPclient.vc_detachTrailer(player, {vtype})
333end, lang.vehicle.detach_trailer.description()}
334
335-- detach towtruck
336veh_actions[lang.vehicle.detach_towtruck.title()] = {function(user_id,player,vtype,name)
337 vRPclient.vc_detachTowTruck(player, {vtype})
338end, lang.vehicle.detach_towtruck.description()}
339
340-- detach cargobob
341veh_actions[lang.vehicle.detach_cargobob.title()] = {function(user_id,player,vtype,name)
342 vRPclient.vc_detachCargobob(player, {vtype})
343end, lang.vehicle.detach_cargobob.description()}
344
345-- lock/unlock
346veh_actions[lang.vehicle.lock.title()] = {function(user_id,player,vtype,name)
347 vRPclient.vc_toggleLock(player, {vtype})
348end, lang.vehicle.lock.description()}
349
350-- engine on/off
351veh_actions[lang.vehicle.engine.title()] = {function(user_id,player,vtype,name)
352 vRPclient.vc_toggleEngine(player, {vtype})
353end, lang.vehicle.engine.description()}
354
355local function ch_vehicle(player,choice)
356 local user_id = vRP.getUserId(player)
357 if user_id ~= nil then
358 -- check vehicle
359 vRPclient.getNearestOwnedVehicle(player,{7},function(ok,vtype,name)
360 if ok then
361 -- build vehicle menu
362 vRP.buildMenu("vehicle", {user_id = user_id, player = player, vtype = vtype, vname = name}, function(menu)
363 menu.name=lang.vehicle.title()
364 menu.css={top="75px",header_color="rgba(255,125,0,0.75)"}
365
366 for k,v in pairs(veh_actions) do
367 menu[k] = {function(player,choice) v[1](user_id,player,vtype,name) end, v[2]}
368 end
369
370 vRP.openMenu(player,menu)
371 end)
372 else
373 vRPclient.notify(player,{lang.vehicle.no_owned_near()})
374 end
375 end)
376 end
377end
378
379-- ask trunk (open other user car chest)
380local function ch_asktrunk(player,choice)
381 vRPclient.getNearestPlayer(player,{10},function(nplayer)
382 local nuser_id = vRP.getUserId(nplayer)
383 if nuser_id ~= nil then
384 vRPclient.notify(player,{lang.vehicle.asktrunk.asked()})
385 vRP.request(nplayer,lang.vehicle.asktrunk.request(),15,function(nplayer,ok)
386 if ok then -- request accepted, open trunk
387 vRPclient.getNearestOwnedVehicle(nplayer,{7},function(ok,vtype,name)
388 if ok then
389 local chestname = "u"..nuser_id.."veh_"..string.lower(name)
390 local max_weight = cfg_inventory.vehicle_chest_weights[string.lower(name)] or cfg_inventory.default_vehicle_chest_weight
391
392 -- open chest
393 local cb_out = function(idname,amount)
394 vRPclient.notify(nplayer,{lang.inventory.give.given({vRP.getItemName(idname),amount})})
395 end
396
397 local cb_in = function(idname,amount)
398 vRPclient.notify(nplayer,{lang.inventory.give.received({vRP.getItemName(idname),amount})})
399 end
400
401 vRPclient.vc_openDoor(nplayer, {vtype,5})
402 vRP.openChest(player, chestname, max_weight, function()
403 vRPclient.vc_closeDoor(nplayer, {vtype,5})
404 end,cb_in,cb_out)
405 else
406 vRPclient.notify(player,{lang.vehicle.no_owned_near()})
407 vRPclient.notify(nplayer,{lang.vehicle.no_owned_near()})
408 end
409 end)
410 else
411 vRPclient.notify(player,{lang.common.request_refused()})
412 end
413 end)
414 else
415 vRPclient.notify(player,{lang.common.no_player_near()})
416 end
417 end)
418end
419
420-- repair nearest vehicle
421local function ch_repair(player,choice)
422 local user_id = vRP.getUserId(player)
423 if user_id ~= nil then
424 -- anim and repair
425 if vRP.tryGetInventoryItem(user_id,"repairkit",1,true) then
426 vRPclient.playAnim(player,{false,{task="WORLD_HUMAN_WELDING"},false})
427 SetTimeout(15000, function()
428 vRPclient.fixeNearestVehicle(player,{7})
429 vRPclient.stopAnim(player,{false})
430 end)
431 end
432 end
433end
434
435local function ch_call(player,choice)
436 vRP.prompt(player,"Player ID(scrie 'inchide' pentru a inchide apelul):","",function(player,target)
437 if not (target == "inchide") then
438 popei = vRP.getUserSource(tonumber(target))
439 --print("Server id : ," .. popei .. "vRP Id : " .. target)
440 else
441 popei = "inchide"
442 --print('Server id : ,'..popei..'vRP Id : ' .. target)
443 end
444 local player = source
445 TriggerEvent('dvcall',player,popei)
446 end)
447end
448
449-- replace nearest vehicle
450local function ch_replace(player,choice)
451 vRPclient.replaceNearestVehicle(player,{7})
452end
453
454vRP.registerMenuBuilder("main", function(add, data)
455 local user_id = vRP.getUserId(data.player)
456 if user_id ~= nil then
457 -- add vehicle entry
458 local choices = {}
459 choices[lang.vehicle.title()] = {ch_vehicle}
460
461 -- add ask trunk
462 choices[lang.vehicle.asktrunk.title()] = {ch_asktrunk}
463
464 -- add repair functions
465 if vRP.hasPermission(user_id, "vehicle.repair") then
466 choices[lang.vehicle.repair.title()] = {ch_repair, lang.vehicle.repair.description()}
467 end
468
469 if vRP.hasPermission(user_id, "vehicle.replace") then
470 choices[lang.vehicle.replace.title()] = {ch_replace, lang.vehicle.replace.description()}
471 end
472
473 choices["Apeleaza Jucator Voce"] = {ch_call}
474
475 add(choices)
476 end
477end)
478
479-- sell vehicle
480veh_actions[lang.vehicle.sellTP.title()] = {function(playerID,player,vtype,name)
481 if playerID ~= nil then
482 vRPclient.getNearestPlayers(player,{15},function(nplayers)
483 usrList = ""
484 for k,v in pairs(nplayers) do
485 usrList = usrList .. "[" .. vRP.getUserId(k) .. "]" .. GetPlayerName(k) .. " | "
486 end
487 if usrList ~= "" then
488 vRP.prompt(player,"Players Nearby: " .. usrList .. "","",function(player,user_id)
489 user_id = user_id
490 if user_id ~= nil and user_id ~= "" then
491 local target = vRP.getUserSource(tonumber(user_id))
492 if target ~= nil then
493 vRP.prompt(player,"Price $: ","",function(player,amount)
494 if (tonumber(amount)) and (tonumber(amount) > 0) then
495 MySQL.query("vRP/get_vehicle", {user_id = user_id, vehicle = name}, function(pvehicle, affected)
496 if #pvehicle > 0 then
497 vRPclient.notify(player,{"~r~The player already has this vehicle type."})
498 else
499 local tmpdata = vRP.getUserTmpTable(playerID)
500 if tmpdata.rent_vehicles[name] == true then
501 vRPclient.notify(player,{"~r~You cannot sell a rented vehicle!"})
502 return
503 else
504 vRP.request(target,GetPlayerName(player).." wants to sell: " ..name.. " Price: $"..amount, 10, function(target,ok)
505 if ok then
506 local pID = vRP.getUserId(target)
507 local money = vRP.getMoney(pID)
508 if (tonumber(money) >= tonumber(amount)) then
509 vRPclient.despawnGarageVehicle(player,{vtype,15})
510 vRP.getUserIdentity(pID, function(identity)
511 MySQL.execute("vRP/sell_vehicle_player", {user_id = user_id, registration = "P "..identity.registration, oldUser = playerID, vehicle = name})
512 end)
513 vRP.giveMoney(playerID, amount)
514 vRP.setMoney(pID,money-amount)
515 vRPclient.notify(player,{"~g~You have successfully sold the vehicle to ".. GetPlayerName(target).." for $"..amount.."!"})
516 vRPclient.notify(target,{"~g~"..GetPlayerName(player).." has successfully sold you the car for $"..amount.."!"})
517 else
518 vRPclient.notify(player,{"~r~".. GetPlayerName(target).." doesn't have enough money!"})
519 vRPclient.notify(target,{"~r~You don't have enough money!"})
520 end
521 else
522 vRPclient.notify(player,{"~r~"..GetPlayerName(target).." has refused to buy the car."})
523 vRPclient.notify(target,{"~r~You have refused to buy "..GetPlayerName(player).."'s car."})
524 end
525 end)
526 end
527 vRP.closeMenu(player)
528 end
529 end)
530 else
531 vRPclient.notify(player,{"~r~The price of the car has to be a number."})
532 end
533 end)
534 else
535 vRPclient.notify(player,{"~r~That ID seems invalid."})
536 end
537 else
538 vRPclient.notify(player,{"~r~No player ID selected."})
539 end
540 end)
541 else
542 vRPclient.notify(player,{"~r~No player nearby."})
543 end
544 end)
545 end
546end, lang.vehicle.sellTP.description()}