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