Advertisement
Guest User

server.lua vrp_adv_garages

a guest
Apr 16th, 2018
298
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 40.29 KB | None | 0 0
  1. --[[
  2.     FiveM Scripts
  3.     Copyright C 2018  Sighmir
  4.  
  5.     This program is free software: you can redistribute it and/or modify
  6.     it under the terms of the GNU Affero General Public License as published
  7.     by the Free Software Foundation, either version 3 of the License, or
  8.     at your option any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU Affero General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU Affero General Public License
  16.     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17. ]]
  18.  
  19. -- vRP TUNNEL/PROXY
  20. MySQL = module("vrp_mysql", "MySQL")
  21. local Tunnel = module("vrp", "lib/Tunnel")
  22. local Proxy = module("vrp", "lib/Proxy")
  23. vRP = Proxy.getInterface("vRP")
  24. vRPclient = Tunnel.getInterface("vRP")
  25.  
  26. -- RESOURCE TUNNEL/PROXY
  27. vRPg = {}
  28. Tunnel.bindInterface("vrp_adv_garages",vRPg)
  29. Proxy.addInterface("vrp_adv_garages",vRPg)
  30. Gclient = Tunnel.getInterface("vrp_adv_garages")
  31.  
  32. -- MYSQL
  33. MySQL.createCommand("vRP/move_vehicle","UPDATE vrp_user_vehicles SET user_id = @tuser_id WHERE user_id = @user_id AND vehicle = @vehicle")
  34.  
  35. -- CFG
  36. local cfg = module("vrp_adv_garages", "cfg/garages")
  37. local cfg_inventory = module("vrp","cfg/inventory")
  38.  
  39. -- LANG
  40. Luang = module("vrp", "lib/Luang")
  41. Lang = Luang()
  42. Lang:loadLocale(cfg.lang, module("vrp", "cfg/lang/"..cfg.lang) or {})
  43. Lang:loadLocale(cfg.lang, module("vrp_adv_garages", "cfg/lang/"..cfg.lang) or {})
  44. lang = Lang.lang[cfg.lang]
  45.  
  46. local adv_garages = cfg.adv_garages
  47. local items = cfg.items
  48. local cooldown = {}
  49.  
  50. Citizen.CreateThread(function()
  51.   for k,v in pairs(items) do
  52.     vRP.defInventoryItem(k,v[1],v[2],v[3],v[4])
  53.   end
  54. end)
  55.  
  56. function vRPg.resetCooldown()
  57.   cooldown[source] = false
  58. end
  59. -- build garages menus
  60. function vRPg.openGarage(source, gid, pos)
  61.   local user_id = vRP.getUserId(source)
  62.   local vehicles = adv_garages[gid]
  63.   local veh_type = vehicles._config.vtype
  64.   local gtypes = vehicles._config.gtype
  65.   local gpay = vehicles._config.gpay
  66.   local mods = vehicles._shop
  67.   local menu = {
  68.     name=lang.garage.title({gid}),
  69.     css={top = "75px", header_color="rgba(255,125,0,0.75)"}
  70.   }
  71.  
  72.   for _,gtype in pairs(gtypes) do
  73.     if gtype == "showroom" then
  74.       menu[lang.garage.showroom.title()] = {function(player,choice)
  75.         local user_id = vRP.getUserId(source)
  76.         if user_id then
  77.           -- build nested menu
  78.           local kitems = {}
  79.           local bought = false
  80.           local submenu = {name=lang.garage.title({lang.garage.buy.title()}), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
  81.           submenu.onclose = function()
  82.             vRP.openMenu(source,menu)
  83.             if not bought then
  84.               Gclient.despawnShowroomVehicle(source)
  85.             end
  86.             Gclient.protectVehicle(source,false)
  87.           end
  88.      
  89.           local choose = function(player, choice, mod)
  90.             local vname = kitems[choice]
  91.             if vname then
  92.               -- buy vehicle
  93.               local vehicle = vehicles[vname]
  94.               if vehicle then
  95.                 if mod == 0 then
  96.                   local ok = vRP.request(source, lang.garage.buy.request(), 10)
  97.                   if ok then
  98.                     local price = vehicle[2]
  99.                     local item = vehicle[4]
  100.                     local payment = false
  101.                     if item then
  102.                       payment = vRP.tryGetInventoryItem(user_id,item,price,true)
  103.                     elseif gpay == "bank" then
  104.                       payment = vRP.tryFullPayment(user_id,price)
  105.                     elseif gpay == "wallet" then
  106.                       payment = vRP.tryPayment(user_id,price)
  107.                     end
  108.                     if payment then
  109.                       local name, custom = Gclient.getVehicleMods(source, veh_type)
  110.                       -- print("custom:u"..user_id.."veh_"..vname.." = " .. json.encode(custom)) -- uncomment to see data structure upon save
  111.                       vRP.setSData("custom:u"..user_id.."veh_"..vname, json.encode(custom))
  112.                       MySQL.execute("vRP/add_vehicle", {user_id = user_id, vehicle = vname})
  113.                       Gclient.despawnShowroomVehicle(source)
  114.                       if Gclient.spawnGarageVehicle(source,veh_type,vname,pos) then
  115.                         Gclient.setVehicleMods(source,custom)
  116.                       else
  117.                         vRPclient.notify(source,lang.garage.personal.out())
  118.                       end
  119.                       bought = true
  120.                       if not item and price > 0 then
  121.                         vRPclient.notify(source,lang.money.paid({price}))
  122.                       end
  123.                       vRP.closeMenu(source)
  124.                     else
  125.                       if not item then
  126.                         vRPclient.notify(source,lang.money.not_enough())
  127.                       end
  128.                     end
  129.                   else
  130.                     vRPclient.notify(source,lang.common.request_refused())
  131.                   end
  132.                 elseif not cooldown[source] then
  133.                   cooldown[source] = true
  134.                   if Gclient.spawnShowroomVehicle(source,vname, pos) then
  135.                     Gclient.protectVehicle(source,true)
  136.                   end
  137.                 end
  138.               end
  139.             end
  140.           end
  141.          
  142.           -- get player owned vehicles (indexed by vehicle type name in lower case)
  143.           local _pvehicles = MySQL.query("vRP/get_vehicles", {user_id = user_id})
  144.           local pvehicles = {}
  145.           for k,v in pairs(_pvehicles) do
  146.             pvehicles[string.lower(v.vehicle)] = true
  147.           end
  148.      
  149.           -- for each existing vehicle in the garage group
  150.           for k,v in pairs(vehicles) do
  151.             if k ~= "_config" and k ~= "_shop" and pvehicles[string.lower(k)] == nil then -- not already owned
  152.               local price = math.max(v[2],0)
  153.               if v[4] then
  154.                 submenu[v[1]] = {choose,lang.garage.buy.item({vRP.getItemName(v[4]),price,v[3]})}
  155.               else
  156.                 submenu[v[1]] = {choose,lang.garage.buy.info({price,v[3]})}
  157.               end
  158.               kitems[v[1]] = k
  159.             end
  160.           end
  161.      
  162.           vRP.openMenu(source,submenu)
  163.         end
  164.       end,lang.garage.showroom.description()}
  165.     elseif gtype == "personal" then
  166.       menu[lang.garage.owned.title()] = {function(player,choice)
  167.         local user_id = vRP.getUserId(source)
  168.         if user_id then
  169.           -- init tmpdata for rents
  170.           local tmpdata = vRP.getUserTmpTable(user_id)
  171.           if not tmpdata.rent_vehicles then
  172.             tmpdata.rent_vehicles = {}
  173.           end
  174.      
  175.      
  176.           -- build nested menu
  177.           local kitems = {}
  178.           local submenu = {name=lang.garage.title({lang.garage.owned.title()}), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
  179.           submenu.onclose = function()
  180.             vRP.openMenu(source,menu)
  181.           end
  182.          
  183.           -- get player owned vehicles
  184.           local pvehicles = MySQL.query("vRP/get_vehicles", {user_id = user_id})
  185.           -- add rents to whitelist
  186.           for k,v in pairs(tmpdata.rent_vehicles) do
  187.             if v then -- check true, prevent future neolua issues
  188.               table.insert(pvehicles,{vehicle = k})
  189.             end
  190.           end
  191.      
  192.           local choose = function(player, choice)
  193.             local vname = kitems[choice]
  194.             if vname then
  195.               -- spawn vehicle
  196.               vRP.closeMenu(source)
  197.               local data = vRP.getSData("custom:u"..user_id.."veh_"..vname)
  198.               local custom = json.decode(data)
  199.               if not cooldown[source] then
  200.                 cooldown[source] = true
  201.                 if Gclient.spawnGarageVehicle(source,veh_type,vname,pos) then
  202.                   Gclient.setVehicleMods(source,custom)
  203.                 else
  204.                   vRPclient.notify(source,lang.garage.personal.out())
  205.                 end
  206.               end
  207.             end
  208.           end
  209.          
  210.           for k,v in pairs(pvehicles) do
  211.             local vehicle
  212.             for x,garage in pairs(adv_garages) do
  213.               if garage._config.vtype == veh_type then
  214.                 vehicle = garage[v.vehicle]
  215.               end
  216.               if vehicle then break end
  217.             end
  218.            
  219.             if vehicle then
  220.               submenu[vehicle[1]] = {choose,vehicle[3]}
  221.               kitems[vehicle[1]] = v.vehicle
  222.             end
  223.           end
  224.      
  225.           vRP.openMenu(source,submenu)
  226.         end
  227.       end,lang.garage.owned.description()}
  228.      
  229.       menu[lang.garage.store.title()] = {function(player,choice)
  230.         if Gclient.despawnGarageVehicle(source,veh_type,15) then
  231.           vRPclient.notify(source,lang.garage.personal.stored())
  232.         else
  233.           vRPclient.notify(source,lang.garage.personal.toofar())
  234.         end
  235.       end, lang.garage.store.description()}
  236.     elseif gtype == "store" then
  237.       menu[lang.garage.buy.title()] = {function(player,choice)
  238.         local user_id = vRP.getUserId(source)
  239.         if user_id then
  240.           -- build nested menu
  241.           local kitems = {}
  242.           local submenu = {name=lang.garage.title({lang.garage.buy.title()}), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
  243.           submenu.onclose = function()
  244.             vRP.openMenu(source,menu)
  245.           end
  246.      
  247.           local choose = function(player, choice)
  248.             local vname = kitems[choice]
  249.             if vname then
  250.               -- buy vehicle
  251.               local vehicle = vehicles[vname]
  252.               if vehicle then
  253.                 local ok = vRP.request(source, lang.garage.buy.request(), 10)
  254.                 if ok then
  255.                   local price = vehicle[2]
  256.                   local item = vehicle[4]
  257.                   local payment = false
  258.                   if item then
  259.                     payment = vRP.tryGetInventoryItem(user_id,item,price,true)
  260.                   elseif gpay == "bank" then
  261.                     payment = vRP.tryFullPayment(user_id,price)
  262.                   elseif gpay == "wallet" then
  263.                     payment = vRP.tryPayment(user_id,price)
  264.                   end
  265.                   if payment then
  266.                     MySQL.execute("vRP/add_vehicle", {user_id = user_id, vehicle = vname})
  267.                     -- spawn vehicle
  268.                     if not Gclient.spawnGarageVehicle(source,veh_type,vname,pos) then
  269.                       vRPclient.notify(source,lang.garage.personal.out())
  270.                     end
  271.                    
  272.                     if not item and price > 0 then
  273.                       vRPclient.notify(source,lang.money.paid({price}))
  274.                     end
  275.                     vRP.closeMenu(source)
  276.                   else
  277.                     if not item then
  278.                       vRPclient.notify(source,lang.money.not_enough())
  279.                     end
  280.                   end
  281.                 else
  282.                   vRPclient.notify(source,lang.common.request_refused())
  283.                 end
  284.               end
  285.             end
  286.           end
  287.          
  288.           -- get player owned vehicles (indexed by vehicle type name in lower case)
  289.           local _pvehicles = MySQL.query("vRP/get_vehicles", {user_id = user_id})
  290.           local pvehicles = {}
  291.           for k,v in pairs(_pvehicles) do
  292.             pvehicles[string.lower(v.vehicle)] = true
  293.           end
  294.      
  295.           -- for each existing vehicle in the garage group
  296.           for k,v in pairs(vehicles) do
  297.             if k ~= "_config" and k ~= "_shop" and pvehicles[string.lower(k)] == nil then -- not already owned
  298.               local price = math.max(v[2],0)
  299.               if v[4] then
  300.                 submenu[v[1]] = {choose,lang.garage.buy.item({vRP.getItemName(v[4]),price,v[3]})}
  301.               else
  302.                 submenu[v[1]] = {choose,lang.garage.buy.info({price,v[3]})}
  303.               end
  304.               kitems[v[1]] = k
  305.             end
  306.           end
  307.      
  308.           vRP.openMenu(source,submenu)
  309.         end
  310.       end,lang.garage.buy.description()}
  311.      
  312.       menu[lang.garage.sell.title()] = {function(player,choice)
  313.         local user_id = vRP.getUserId(source)
  314.         if user_id then
  315.      
  316.           -- build nested menu
  317.           local kitems = {}
  318.           local submenu = {name=lang.garage.title({lang.garage.sell.title()}), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
  319.           submenu.onclose = function()
  320.             vRP.openMenu(source,menu)
  321.           end
  322.      
  323.           local choose = function(player, choice)
  324.             local vname = kitems[choice]
  325.             if vname then
  326.               -- sell vehicle
  327.               local vehicle = vehicles[vname]
  328.               if vehicle then      
  329.                 local rows = MySQL.query("vRP/get_vehicle", {user_id = user_id, vehicle = vname})
  330.                 if #rows > 0 then -- has vehicle
  331.                   local price = math.ceil(vehicle[2]*cfg.sell_factor)
  332.                   local item = vehicle[4]
  333.                   if item then
  334.                     vRP.giveInventoryItem(user_id,item,price,true)
  335.                   elseif gpay == "bank" then
  336.                     vRP.giveBankMoney(user_id,price)
  337.                   elseif gpay == "wallet" then
  338.                     vRP.giveMoney(user_id,price)
  339.                   end
  340.                   MySQL.execute("vRP/remove_vehicle", {user_id = user_id, vehicle = vname})
  341.                   vRP.setSData("custom:u"..user_id.."veh_"..vname, json.encode())
  342.                  
  343.                   if not item and price > 0 then
  344.                     vRPclient.notify(source,lang.money.received({price}))
  345.                   end
  346.                  
  347.                   local vtype, vehicle = Gclient.isOwnedVehicleOut(source, vname)
  348.                   if vtype and vehicle then
  349.                     if Gclient.despawnGarageVehicle(source,vtype,100000) then
  350.                       vRPclient.notify(source,lang.garage.personal.sold())
  351.                     end
  352.                   end
  353.      
  354.                   vRP.closeMenu(source)
  355.                 else
  356.                   vRPclient.notify(source,lang.common.not_found())
  357.                 end
  358.               end
  359.             end
  360.           end
  361.          
  362.           -- get player owned vehicles (indexed by vehicle type name in lower case)
  363.           local _pvehicles = MySQL.query("vRP/get_vehicles", {user_id = user_id})
  364.           local pvehicles = {}
  365.           for k,v in pairs(_pvehicles) do
  366.             pvehicles[string.lower(v.vehicle)] = true
  367.           end
  368.      
  369.           -- for each existing vehicle in the garage group
  370.           for k,v in pairs(pvehicles) do
  371.             local vehicle = vehicles[k]
  372.             if vehicle then -- not already owned
  373.               local price = math.ceil(vehicle[2]*cfg.sell_factor)
  374.               if vehicle[4] then
  375.                 submenu[vehicle[1]] = {choose,lang.garage.buy.item({vRP.getItemName(vehicle[4]),price,vehicle[3]})}
  376.               else
  377.                 submenu[vehicle[1]] = {choose,lang.garage.buy.info({price,vehicle[3]})}
  378.               end
  379.               kitems[vehicle[1]] = k
  380.             end
  381.           end
  382.      
  383.           vRP.openMenu(source,submenu)
  384.         end
  385.       end,lang.garage.sell.description()}
  386.     elseif gtype == "rental" then
  387.       menu[lang.garage.rent.title()] = {function(player,choice)
  388.         local user_id = vRP.getUserId(source)
  389.         if user_id then
  390.           -- init tmpdata for rents
  391.           local tmpdata = vRP.getUserTmpTable(user_id)
  392.           if tmpdata.rent_vehicles == nil then
  393.             tmpdata.rent_vehicles = {}
  394.           end
  395.      
  396.           -- build nested menu
  397.           local kitems = {}
  398.           local submenu = {name=lang.garage.title({lang.garage.rent.title()}), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
  399.           submenu.onclose = function()
  400.             vRP.openMenu(source,menu)
  401.           end
  402.      
  403.           local choose = function(player, choice)
  404.             local vname = kitems[choice]
  405.             if vname then
  406.               -- rent vehicle
  407.               local vehicle = vehicles[vname]
  408.               if vehicle then
  409.                 local price = math.ceil(vehicle[2]*cfg.rent_factor)
  410.                 local item = vehicle[4]
  411.                 local payment = false
  412.                 if item then
  413.                   payment = vRP.tryGetInventoryItem(user_id,item,price,true)
  414.                 elseif gpay == "bank" then
  415.                   payment = vRP.tryFullPayment(user_id,price)
  416.                 elseif gpay == "wallet" then
  417.                   payment = vRP.tryPayment(user_id,price)
  418.                 end
  419.                 if payment then
  420.                   -- add vehicle to rent tmp data
  421.                   tmpdata.rent_vehicles[vname] = true
  422.                   -- spawn vehicle
  423.                   if not Gclient.spawnGarageVehicle(source,veh_type,vname,pos) then
  424.                     vRPclient.notify(source,lang.garage.personal.out())
  425.                   end
  426.                  
  427.                   if not item and price > 0 then
  428.                     vRPclient.notify(source,lang.money.paid({price}))
  429.                   end
  430.      
  431.                   vRPclient.notify(source,lang.money.paid({price}))
  432.                   vRP.closeMenu(source)
  433.                 else
  434.                   if not item then
  435.                     vRPclient.notify(source,lang.money.not_enough())
  436.                   end
  437.                 end
  438.               end
  439.             end
  440.           end
  441.          
  442.           -- get player owned vehicles (indexed by vehicle type name in lower case)
  443.           local _pvehicles = MySQL.query("vRP/get_vehicles", {user_id = user_id})
  444.           local pvehicles = {}
  445.           for k,v in pairs(_pvehicles) do
  446.             pvehicles[string.lower(v.vehicle)] = true
  447.           end
  448.      
  449.           -- add rents to blacklist
  450.           for k,v in pairs(tmpdata.rent_vehicles) do
  451.             pvehicles[string.lower(k)] = true
  452.           end
  453.      
  454.           -- for each existing vehicle in the garage group
  455.           for k,v in pairs(vehicles) do
  456.             if k ~= "_config" and k ~= "_shop" and pvehicles[string.lower(k)] == nil then -- not already owned
  457.               local price = math.ceil(v[2]*cfg.rent_factor)
  458.               if v[4] then
  459.                 submenu[v[1]] = {choose,lang.garage.buy.item({vRP.getItemName(v[4]),price,v[3]})}
  460.               else
  461.                 submenu[v[1]] = {choose,lang.garage.buy.info({price,v[3]})}
  462.               end
  463.               kitems[v[1]] = k
  464.             end
  465.           end
  466.      
  467.           vRP.openMenu(source,submenu)
  468.         end
  469.       end,lang.garage.rent.description()}
  470.       menu[lang.garage.store.title()] = {function(player,choice)
  471.         if Gclient.despawnGarageVehicle(source,veh_type,15) then
  472.           vRPclient.notify(source,lang.garage.personal.stored())
  473.         else
  474.           vRPclient.notify(source,lang.garage.personal.toofar())
  475.         end
  476.       end, lang.garage.store.description()}
  477.     elseif gtype == "shop" then
  478.       menu[lang.garage.shop.title()] = {function(player,choice)
  479.         local user_id = vRP.getUserId(source)
  480.         local tosub = false
  481.         if user_id then
  482.           -- build nested menu
  483.           local submenu = {name=lang.garage.title({lang.garage.shop.title()}), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
  484.          
  485.           -- payment and saving
  486.           submenu.onclose = function()
  487.             if not tosub then
  488.               vRP.openMenu(source,menu)
  489.               Gclient.protectVehicle(source,false)
  490.             end
  491.           end
  492.          
  493.           local ch_color = function(player, choice)
  494.             local old_vname, old_custom = Gclient.getVehicleMods(source, veh_type)
  495.             local subsubmenu = {name=lang.garage.title({lang.garage.shop.colour.title()}), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
  496.             subsubmenu.onclose = function()
  497.               tosub = false
  498.               local vname, custom = Gclient.getVehicleMods(source, veh_type)
  499.               local price = 0
  500.               if custom then
  501.                 for k,v in pairs(custom.colour.custom.primary) do
  502.                   local old = old_custom.colour.custom.primary[k]
  503.                   if mod then
  504.                     if old ~= v then price = price + cfg.price.colour end -- modification
  505.                   end
  506.                 end
  507.                 for k,v in pairs(custom.colour.custom.secondary) do
  508.                   local old = old_custom.colour.custom.secondary[k]
  509.                   if mod then
  510.                     if old ~= v then price = price + cfg.price.colour end -- modification
  511.                   end
  512.                 end
  513.                 if custom.colour.primary ~= old_custom.colour.primary then price = price + cfg.price.colour end -- modification
  514.                 if custom.colour.secondary ~= old_custom.colour.secondary then price = price + cfg.price.colour end -- modification
  515.                 local payment = false
  516.                 if gpay == "bank" then
  517.                   payment = vRP.tryFullPayment(user_id,price)
  518.                 elseif gpay == "wallet" then
  519.                   payment = vRP.tryPayment(user_id,price)
  520.                 end
  521.                 if payment then
  522.                   if vname then
  523.                     -- print("custom:u"..user_id.."veh_"..vname.." = " .. json.encode(custom)) -- uncomment to see data structure upon save
  524.                     vRP.setSData("custom:u"..user_id.."veh_"..vname, json.encode(custom))
  525.                     if price > 0 then
  526.                       vRPclient.notify(source,lang.money.paid({price}))
  527.                     end
  528.                   end
  529.                 else
  530.                   Gclient.setVehicleMods(source,old_custom)
  531.                   vRPclient.notify(source,lang.money.not_enough())
  532.                 end
  533.               end
  534.               vRP.openMenu(source,submenu)
  535.             end
  536.            
  537.             local ch_pcolor = function(player, choice, mod)
  538.               Gclient.scrollVehiclePrimaryColour(source,mod)
  539.             end
  540.             local ch_scolor = function(player, choice, mod)
  541.               Gclient.scrollVehicleSecondaryColour(source,mod)
  542.             end
  543.             local ch_cpcolor = function(player, choice)
  544.               local rgb = vRP.prompt(source,"RGB Color(255 255 255):","")
  545.               rgb = sanitizeString(rgb,"\"[]{}+=?!_()#@%/\\|,.",false)
  546.               local r,g,b = table.unpack(splitString(rgb, " "))
  547.               Gclient.setCustomPrimaryColour(source,tonumber(r),tonumber(g),tonumber(b))
  548.             end
  549.             local ch_cscolor = function(player, choice)
  550.               local rgb = vRP.prompt(source,"RGB Color(255 255 255):","")
  551.               rgb = sanitizeString(rgb,"\"[]{}+=?!_()#@%/\\|,.",false)
  552.               local r,g,b = table.unpack(splitString(rgb, " "))
  553.               Gclient.setCustomSecondaryColour(source,tonumber(r),tonumber(g),tonumber(b))
  554.             end
  555.            
  556.             subsubmenu[lang.garage.shop.colour.primary()] = {ch_pcolor,""}
  557.             subsubmenu[lang.garage.shop.colour.secondary()] = {ch_scolor,""}
  558.             subsubmenu[lang.garage.shop.colour.custom.primary()] = {ch_cpcolor,""}
  559.             subsubmenu[lang.garage.shop.colour.custom.secondary()] = {ch_cscolor,""}
  560.            
  561.             tosub = true
  562.             vRP.openMenu(source,subsubmenu)
  563.           end
  564.           submenu[lang.garage.shop.colour.title()] = {ch_color,lang.garage.shop.colour.info({})}
  565.          
  566.           local ch_extracolor = function(player, choice)
  567.             local old_vname, old_custom = Gclient.getVehicleMods(source, veh_type)
  568.             local subsubmenu = {name=lang.garage.title({lang.garage.shop.colour.extra.title()}), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
  569.             subsubmenu.onclose = function()
  570.               tosub = false
  571.               local vname, custom = Gclient.getVehicleMods(source, veh_type)
  572.               local price = 0
  573.               if custom then
  574.                 for k,v in pairs(custom.colour.smoke) do
  575.                   local old = old_custom.colour.smoke[k]
  576.                   if mod then
  577.                     if old ~= v then price = price + cfg.price.extra end -- modification
  578.                   end
  579.                 end
  580.                 if custom.colour.pearlescent ~= old_custom.colour.pearlescent then price = price + cfg.price.extra end -- modification
  581.                 if custom.colour.wheel ~= old_custom.colour.wheel then price = price + cfg.price.extra end -- modification
  582.                 local payment = false
  583.                 if gpay == "bank" then
  584.                   payment = vRP.tryFullPayment(user_id,price)
  585.                 elseif gpay == "wallet" then
  586.                   payment = vRP.tryPayment(user_id,price)
  587.                 end
  588.                 if payment then
  589.                   if vname then
  590.                     -- print("custom:u"..user_id.."veh_"..vname.." = " .. json.encode(custom)) -- uncomment to see data structure upon save
  591.                     vRP.setSData("custom:u"..user_id.."veh_"..vname, json.encode(custom))
  592.                   end
  593.                   if price > 0 then
  594.                     vRPclient.notify(source,lang.money.paid({price}))
  595.                   end
  596.                 else
  597.                   Gclient.setVehicleMods(source,old_custom)
  598.                   vRPclient.notify(source,lang.money.not_enough())
  599.                 end
  600.               end
  601.               vRP.openMenu(source,submenu)
  602.             end
  603.            
  604.             local ch_pcolor = function(player, choice, mod)
  605.               Gclient.scrollVehiclePearlescentColour(source,mod)
  606.             end
  607.             local ch_wcolor = function(player, choice, mod)
  608.               Gclient.scrollVehicleWheelColour(source,mod)
  609.             end
  610.             local ch_scolor = function(player, choice)
  611.               local rgb = vRP.prompt(source,"RGB Color(255 255 255):","")
  612.               rgb = sanitizeString(rgb,"\"[]{}+=?!_()#@%/\\|,.",false)
  613.               local r,g,b = table.unpack(splitString(rgb, " "))
  614.               Gclient.setSmokeColour(source,tonumber(r),tonumber(g),tonumber(b))
  615.             end
  616.            
  617.             subsubmenu[lang.garage.shop.colour.extra.pearlescent()] = {ch_pcolor,""}
  618.             subsubmenu[lang.garage.shop.colour.extra.wheel()] = {ch_wcolor,""}
  619.             subsubmenu[lang.garage.shop.colour.extra.smoke()] = {ch_scolor,""}
  620.            
  621.             tosub = true
  622.             vRP.openMenu(source,subsubmenu)
  623.           end
  624.           submenu[lang.garage.shop.colour.extra.title()] = {ch_extracolor,lang.garage.shop.colour.extra.info({})}
  625.          
  626.           local ch_neon = function(player, choice)
  627.             local old_vname, old_custom = Gclient.getVehicleMods(source, veh_type)
  628.             local subsubmenu = {name=lang.garage.title({lang.garage.shop.neon.title()}), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
  629.             subsubmenu.onclose = function()
  630.               tosub = false
  631.               local vname, custom = Gclient.getVehicleMods(source, veh_type)
  632.               local price = 0
  633.               if custom then
  634.                 for k,v in pairs(custom.neon) do
  635.                   local old = old_custom.neon[k]
  636.                   if mod then
  637.                     if old ~= v then price = price + cfg.price.neon end -- modification
  638.                   end
  639.                 end
  640.                 for k,v in pairs(custom.colour.neon) do
  641.                   local old = old_custom.colour.neon[k]
  642.                   if mod then
  643.                     if old ~= v then price = price + cfg.price.neon end -- modification
  644.                   end
  645.                 end
  646.                 local payment = false
  647.                 if gpay == "bank" then
  648.                   payment = vRP.tryFullPayment(user_id,price)
  649.                 elseif gpay == "wallet" then
  650.                   payment = vRP.tryPayment(user_id,price)
  651.                 end
  652.                 if payment then
  653.                   if vname then
  654.                     -- print("custom:u"..user_id.."veh_"..vname.." = " .. json.encode(custom)) -- uncomment to see data structure upon save
  655.                     vRP.setSData("custom:u"..user_id.."veh_"..vname, json.encode(custom))
  656.                   end
  657.                   if price > 0 then
  658.                     vRPclient.notify(source,lang.money.paid({price}))
  659.                   end
  660.                 else
  661.                   Gclient.setVehicleMods(source,old_custom)
  662.                   vRPclient.notify(source,lang.money.not_enough())
  663.                 end
  664.               end
  665.               vRP.openMenu(source,submenu)
  666.             end
  667.            
  668.             local ch_nleft = function(player, choice)
  669.               Gclient.toggleNeon(source,0)
  670.             end
  671.             local ch_nright = function(player, choice)
  672.               Gclient.toggleNeon(source,1)
  673.             end
  674.             local ch_nfront = function(player, choice)
  675.               Gclient.toggleNeon(source,2)
  676.             end
  677.             local ch_nback = function(player, choice)
  678.               Gclient.toggleNeon(source,3)
  679.             end
  680.             local ch_ncolor = function(player, choice)
  681.               local rgb = vRP.prompt(source,"RGB Color(255 255 255):","")
  682.               rgb = sanitizeString(rgb,"\"[]{}+=?!_()#@%/\\|,.",false)
  683.               local r,g,b = table.unpack(splitString(rgb, " "))
  684.               Gclient.setNeonColour(source,tonumber(r),tonumber(g),tonumber(b))
  685.             end
  686.            
  687.             subsubmenu[lang.garage.shop.neon.back()] = {ch_nback,""}
  688.             subsubmenu[lang.garage.shop.neon.front()] = {ch_nfront,""}
  689.             subsubmenu[lang.garage.shop.neon.left()] = {ch_nleft,""}
  690.             subsubmenu[lang.garage.shop.neon.right()] = {ch_nright,""}
  691.             subsubmenu[lang.garage.shop.neon.colour()] = {ch_ncolor,""}
  692.            
  693.             tosub = true
  694.             vRP.openMenu(source,subsubmenu)
  695.           end
  696.           submenu[lang.garage.shop.neon.title()] = {ch_neon,lang.garage.shop.neon.info({})}
  697.          
  698.           local ch_mods = function(player, choice)
  699.             local kitems = {}
  700.             local old_vname, old_custom = Gclient.getVehicleMods(source, veh_type)
  701.             local subsubmenu = {name=lang.garage.title({lang.garage.shop.mods.title()}), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
  702.             subsubmenu.onclose = function()
  703.               tosub = false
  704.               local vname, custom = Gclient.getVehicleMods(source, veh_type)
  705.               local price = 0
  706.               local items = {}
  707.               if custom then
  708.                 for k,v in pairs(custom.mods) do
  709.                   local old = old_custom.mods[k]
  710.                   local mod = mods[k]
  711.                   if mod then
  712.                     if old ~= v then
  713.                       if mod[4] then
  714.                         items[k] = {mod[4],mod[2]} -- item prices
  715.                       else price = price + mod[2] end -- modification
  716.                     end
  717.                   end
  718.                 end
  719.                 local payment = false
  720.                 local payitems = false
  721.                 if not next(items) then
  722.                   payitems = true
  723.                 else
  724.                   for n,i in pairs(items) do
  725.                     payitems = vRP.tryGetInventoryItem(user_id,i[1],i[2],true)
  726.                     if not payitems then break end
  727.                   end
  728.                 end
  729.                 if payitems then
  730.                   if gpay == "bank" then
  731.                     payment = vRP.tryFullPayment(user_id,price)
  732.                   elseif gpay == "wallet" then
  733.                     payment = vRP.tryPayment(user_id,price)
  734.                   end
  735.                   if payment then
  736.                     if vname then
  737.                       -- print("custom:u"..user_id.."veh_"..vname.." = " .. json.encode(custom)) -- uncomment to see data structure upon save
  738.                       vRP.setSData("custom:u"..user_id.."veh_"..vname, json.encode(custom))
  739.                       if price > 0 then
  740.                         vRPclient.notify(source,lang.money.paid({price}))
  741.                       end
  742.                     end
  743.                   else
  744.                     Gclient.setVehicleMods(source,old_custom)
  745.                     vRPclient.notify(source,lang.money.not_enough())
  746.                   end
  747.                 end
  748.               end
  749.               vRP.openMenu(source,submenu)
  750.             end
  751.            
  752.             local ch_mod = function(player, choice, mod)
  753.               Gclient.scrollVehicleMods(source,kitems[choice],mod)         
  754.             end
  755.             -- for each existing vehicle in the garage group
  756.             for k,v in pairs(mods) do
  757.               local price = math.max(v[2],0)
  758.               if v[4] then
  759.                 subsubmenu[v[1]] = {ch_mod,lang.garage.buy.item({vRP.getItemName(v[4]),price,v[3]})}
  760.               else
  761.                 subsubmenu[v[1]] = {ch_mod,lang.garage.buy.info({price,v[3]})}
  762.               end
  763.               kitems[v[1]] = k
  764.             end
  765.             tosub = true
  766.             vRP.openMenu(source,subsubmenu)
  767.           end
  768.           submenu[lang.garage.shop.mods.title()] = {ch_mods,lang.garage.shop.mods.info({})}
  769.          
  770.           local ch_repair = function(player, choice)
  771.             local price = cfg.price.repair
  772.             local payment = false
  773.             if gpay == "bank" then
  774.               payment = vRP.tryFullPayment(user_id,price)
  775.             elseif gpay == "wallet" then
  776.               payment = vRP.tryPayment(user_id,price)
  777.             end
  778.             if payment then
  779.               if price > 0 then
  780.                 vRPclient.notify(source,lang.money.paid({price}))
  781.               end
  782.               Gclient.repairVehicle(source)
  783.             else
  784.               vRPclient.notify(source,lang.money.not_enough())
  785.             end
  786.           end
  787.           submenu[lang.garage.shop.repair.title()] = {ch_repair,lang.garage.shop.repair.info({})}
  788.          
  789.           vRP.openMenu(source,submenu)
  790.           Gclient.protectVehicle(source,true)
  791.         end
  792.       end,lang.garage.shop.description()}
  793.     end
  794.   end
  795.  
  796.  
  797.   vRP.openMenu(source,menu)
  798. end
  799.  
  800. local function build_client_garages(source)
  801.   local user_id = vRP.getUserId(source)
  802.   local address = vRP.getUserAddress(user_id)
  803.   if user_id then
  804.     for k,v in pairs(cfg.garages) do
  805.       local gid,x,y,z = table.unpack(v)
  806.       local vehicles = cfg.adv_garages[gid]
  807.  
  808.       if vehicles then
  809.         local gcfg = vehicles._config
  810.        
  811.         if not address then address = {} end
  812.         if not gcfg.ghome or gcfg.ghome == address.home then
  813.           -- enter
  814.           local garage_enter = function(player,area)
  815.             local user_id = vRP.getUserId(source)
  816.             if user_id and vRP.hasPermissions(user_id,gcfg.permissions or {}) then
  817.               vRPg.openGarage(source,gid,{x,y,z})
  818.             end
  819.           end
  820.          
  821.           -- leave
  822.           local garage_leave = function(player,area)
  823.             vRP.closeMenu(source)
  824.             vRP.closeMenu(source)
  825.             vRP.closeMenu(source)
  826.             vRP.closeMenu(source)
  827.             vRP.closeMenu(source)
  828.           end
  829.          
  830.           if gcfg.blipid then
  831.             vRPclient.addBlip(source,x,y,z,gcfg.blipid,gcfg.blipcolor,lang.garage.title({gid}))
  832.           end
  833.           vRPclient.addMarker(source,x,y,z-1,1.5,1.5,0.7,0,125,255,125,150)
  834.          
  835.           vRP.setArea(source,"vRP:garage"..k,x,y,z,2,2,garage_enter,garage_leave)
  836.         end
  837.       end
  838.     end
  839.   end
  840. end
  841.  
  842. AddEventHandler("vRP:playerSpawn",function(user_id,source,first_spawn)
  843.   if first_spawn then
  844.     build_client_garages(source)
  845.   end
  846. end)
  847.  
  848. -- VEHICLE MENU
  849.  
  850. -- define vehicle actions
  851. -- action => {cb(user_id,player,veh_group,veh_name),desc}
  852. local veh_actions = {}
  853.  
  854. -- open trunk
  855. veh_actions[lang.vehicle.trunk.title()] = {function(user_id,player,vtype,name)
  856.   local chestname = "u"..user_id.."veh_"..string.lower(name)
  857.   local max_weight = cfg_inventory.vehicle_chest_weights[string.lower(name)] or cfg_inventory.default_vehicle_chest_weight
  858.  
  859.   -- open chest
  860.   Gclient.vc_openDoor(player, vtype,5)
  861.   vRP.openChest(player, chestname, max_weight, function()
  862.     Gclient.vc_closeDoor(player, vtype,5)
  863.   end)
  864. end, lang.vehicle.trunk.description()}
  865.  
  866. -- detach trailer
  867. veh_actions[lang.vehicle.detach_trailer.title()] = {function(user_id,player,vtype,name)
  868.   Gclient.vc_detachTrailer(player, vtype)
  869. end, lang.vehicle.detach_trailer.description()}
  870.  
  871. -- detach towtruck
  872. veh_actions[lang.vehicle.detach_towtruck.title()] = {function(user_id,player,vtype,name)
  873.   Gclient.vc_detachTowTruck(player, vtype)
  874. end, lang.vehicle.detach_towtruck.description()}
  875.  
  876. -- detach cargobob
  877. veh_actions[lang.vehicle.detach_cargobob.title()] = {function(user_id,player,vtype,name)
  878.   Gclient.vc_detachCargobob(player, vtype)
  879. end, lang.vehicle.detach_cargobob.description()}
  880.  
  881. -- lock/unlock
  882. veh_actions[lang.vehicle.lock.title()] = {function(user_id,player,vtype,name)
  883.   Gclient.vc_toggleLock(player, vtype)
  884. end, lang.vehicle.lock.description()}
  885.  
  886. -- engine on/off
  887. veh_actions[lang.vehicle.engine.title()] = {function(user_id,player,vtype,name)
  888.   Gclient.vc_toggleEngine(player, vtype)
  889. end, lang.vehicle.engine.description()}
  890.  
  891. local function ch_vehicle(player,choice)
  892.   local user_id = vRP.getUserId(player)
  893.   if user_id then
  894.     -- build vehicle menu
  895.     -- check vehicle
  896.     local ok,vtype,name = Gclient.getNearestOwnedVehicle(player,7)
  897.     local menu = vRP.buildMenu("vehicle", {user_id = user_id, player = player, vtype = vtype, vname = name})
  898.     menu.name=lang.vehicle.title()
  899.     menu.css={top="75px",header_color="rgba(255,125,0,0.75)"}
  900.  
  901.     if ok then
  902.       for k,v in pairs(veh_actions) do
  903.         menu[k] = {function(player,choice) v[1](user_id,player,vtype,name) end, v[2]}
  904.       end
  905.     end
  906.    
  907.     local ch_keys = function(player,choice)
  908.       local user_id = vRP.getUserId(player)
  909.       if user_id then
  910.         local kitems = {}
  911.         local tosub = false
  912.         local submenu = {name=lang.garage.keys.title(), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
  913.         submenu.onclose = function()
  914.           if not tosub then
  915.             vRP.openMenu(player,menu)
  916.           end
  917.         end
  918.              
  919.         local choose = function(player, choice)
  920.           local vehicle = choice
  921.           local vname = kitems[vehicle]
  922.           local subsubmenu = {name=lang.garage.keys.key({vehicle}), css={top="75px",header_color="rgba(255,125,0,0.75)"}}
  923.           subsubmenu.onclose = function()
  924.             tosub = false
  925.             vRP.openMenu(player,submenu)
  926.           end
  927.          
  928.           local ch_sell = function(player, choice)
  929.             local nplayer = vRPclient.getNearestPlayer(player, 5)
  930.             if nplayer then
  931.               local tuser_id = vRP.getUserId(nplayer)
  932.               local owned = MySQL.query("vRP/get_vehicle", {user_id = tuser_id, vehicle = vname})
  933.               if #owned == 0 then
  934.                 local price = tonumber(sanitizeString(vRP.prompt(player,lang.garage.keys.sell.prompt(),""),"\"[]{}+=?!_()#@%/\\|,.",false))
  935.                 local ok = vRP.request(nplayer, lang.garage.keys.sell.request({vehicle,price}), 30)
  936.                 if ok then
  937.                   if vRP.tryFullPayment(tuser_id,price) then
  938.                     MySQL.execute("vRP/move_vehicle", {user_id = user_id, tuser_id = tuser_id, vehicle = vname})
  939.                     local data = vRP.getSData("custom:u"..user_id.."veh_"..vname)
  940.                     local custom = json.decode(data)
  941.                     vRP.setSData("custom:u"..tuser_id.."veh_"..vname, json.encode(custom))
  942.                     vRP.setSData("custom:u"..user_id.."veh_"..vname, json.encode())
  943.                     if price > 0 then
  944.                       vRP.giveBankMoney(user_id,price)
  945.                       vRPclient.notify(nplayer,lang.money.paid({price}))
  946.                       vRPclient.notify(player,lang.money.received({price}))
  947.                     end
  948.                     local vtype, vehicle = Gclient.isOwnedVehicleOut(player, vname)
  949.                     if vtype and vehicle then
  950.                     if Gclient.despawnGarageVehicle(player,vtype,999999) then
  951.                         if Gclient.spawnGarageVehicle(nplayer,vtype,vname,pos) then
  952.                             Gclient.setVehicleMods(nplayer,custom)
  953.                         else
  954.                             vRPclient.notify(nplayer,lang.garage.personal.out())
  955.                         end
  956.                     end
  957.                     else
  958.                         vRPclient.notify(nplayer,lang.garage.personal.bought())
  959.                     end
  960.                     vRPclient.notify(player,lang.garage.personal.sold())
  961.                   else
  962.                     vRPclient.notify(player,lang.money.not_enough())
  963.                     vRPclient.notify(nplayer,lang.money.not_enough())
  964.                   end
  965.                 else
  966.                   vRPclient.notify(player,lang.common.request_refused())
  967.                 end
  968.               else
  969.                 vRPclient.notify(nplayer,lang.garage.keys.sell.owned())
  970.                 vRPclient.notify(player,lang.garage.keys.sell.owned())
  971.               end
  972.             else
  973.               vRPclient.notify(player,lang.common.no_player_near())
  974.             end
  975.           end
  976.          
  977.           subsubmenu[lang.garage.keys.sell.title()] = {ch_sell,lang.garage.keys.sell.description()}
  978.          
  979.           tosub = true
  980.           vRP.openMenu(player,subsubmenu)
  981.         end
  982.          -- get player owned vehicles (indexed by vehicle type name in lower case)
  983.         local pvehicles = MySQL.query("vRP/get_vehicles", {user_id = user_id})
  984.         for k,v in pairs(pvehicles) do
  985.           local vehicle
  986.           for x,garage in pairs(adv_garages) do
  987.             vehicle = garage[v.vehicle]
  988.             if vehicle then break end
  989.           end
  990.        
  991.           if vehicle then
  992.             submenu[vehicle[1]] = {choose,vehicle[3]}
  993.             kitems[vehicle[1]] = v.vehicle
  994.           end
  995.         end
  996.    
  997.         vRP.openMenu(player,submenu)
  998.       end
  999.     end
  1000.    
  1001.     menu[lang.garage.keys.title()] = {ch_keys, lang.garage.keys.description()}
  1002.  
  1003.     vRP.openMenu(player,menu)
  1004.   end
  1005. end
  1006.  
  1007. -- ask trunk (open other user car chest)
  1008. local function ch_asktrunk(player,choice)
  1009.   local nplayer = vRPclient.getNearestPlayer(player,10)
  1010.   local nuser_id = vRP.getUserId(nplayer)
  1011.   if nuser_id then
  1012.     vRPclient.notify(player,lang.vehicle.asktrunk.asked())
  1013.     if vRP.request(nplayer,lang.vehicle.asktrunk.request(),15) then -- request accepted, open trunk
  1014.       local ok,vtype,name = Gclient.getNearestOwnedVehicle(nplayer,7)
  1015.       if ok then
  1016.         local chestname = "u"..nuser_id.."veh_"..string.lower(name)
  1017.         local max_weight = cfg_inventory.vehicle_chest_weights[string.lower(name)] or cfg_inventory.default_vehicle_chest_weight
  1018.  
  1019.         -- open chest
  1020.         local cb_out = function(idname,amount)
  1021.           vRPclient.notify(nplayer,lang.inventory.give.given({vRP.getItemName(idname),amount}))
  1022.         end
  1023.  
  1024.         local cb_in = function(idname,amount)
  1025.           vRPclient.notify(nplayer,lang.inventory.give.received({vRP.getItemName(idname),amount}))
  1026.         end
  1027.  
  1028.         Gclient.vc_openDoor(nplayer, vtype,5)
  1029.         vRP.openChest(player, chestname, max_weight, function()
  1030.           Gclient.vc_closeDoor(nplayer, vtype,5)
  1031.         end,cb_in,cb_out)
  1032.       else
  1033.         vRPclient.notify(player,lang.vehicle.no_owned_near())
  1034.         vRPclient.notify(nplayer,lang.vehicle.no_owned_near())
  1035.       end
  1036.     else
  1037.       vRPclient.notify(player,lang.common.request_refused())
  1038.     end
  1039.   else
  1040.     vRPclient.notify(player,lang.common.no_player_near())
  1041.   end
  1042. end
  1043.  
  1044. Citizen.CreateThread(function()
  1045.   vRP.registerMenuBuilder("main", function(add, data)
  1046.     Citizen.CreateThread(function()
  1047.       local user_id = vRP.getUserId(data.player)
  1048.       if user_id then
  1049.         -- add vehicle entry
  1050.         local choices = {}
  1051.         choices[lang.vehicle.title()] = {ch_vehicle}
  1052.      
  1053.         -- add ask trunk
  1054.         choices[lang.vehicle.asktrunk.title()] = {ch_asktrunk}
  1055.      
  1056.         add(choices)
  1057.       end
  1058.     end)
  1059.   end)
  1060. end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement