├── fxmanifest.lua ├── locales ├── da.lua └── en.lua ├── server └── rentals_s.lua ├── README.md └── client └── rentals.lua /fxmanifest.lua: -------------------------------------------------------------------------------- 1 | fx_version 'cerulean' 2 | game 'gta5' 3 | 4 | author 'Carbon#1002' 5 | description 'qb-rentals' 6 | version '1.1.0' 7 | 8 | shared_scripts { 9 | '@qb-core/shared/locale.lua', 10 | 'locales/en.lua' 11 | } 12 | 13 | client_script 'client/main.lua' 14 | server_script 'server/main.lua' 15 | -------------------------------------------------------------------------------- /locales/da.lua: -------------------------------------------------------------------------------- 1 | local Translations = { 2 | info = { 3 | ["air_veh"] = "Fly Udlejning!", 4 | ["land_veh"] = "Bil Udlejning!", 5 | ["sea_veh"] = "Båd Udlejning!", 6 | }, 7 | error = { 8 | ["not_enough_space"] = "%{vehicle} er i vejen!", 9 | ["not_enough_money"] = "Du har ikke nok Penge!", 10 | ["no_vehicle"] = "Intet køretøj til returnering" 11 | }, 12 | task = { 13 | ["return_veh"] = "Giv køretøjet tilbage!", 14 | ['veh_returned'] = 'Køretøj returneret!' 15 | } 16 | } 17 | Lang = Locale:new({phrases = Translations, warnOnMissing = true}) 18 | -------------------------------------------------------------------------------- /locales/en.lua: -------------------------------------------------------------------------------- 1 | local Translations = { 2 | info = { 3 | ["air_veh"] = "Aircraft Rentals", 4 | ["land_veh"] = "Vehicle Rentals", 5 | ["sea_veh"] = "Boat Rentals", 6 | }, 7 | error = { 8 | ["not_enough_space"] = "%{vehicle} is in the way!", 9 | ["not_enough_money"] = "You do not have enough money!", 10 | ["no_vehicle"] = "No vehicle to return!" 11 | }, 12 | task = { 13 | ["return_veh"] = "Return your rented vehicle.", 14 | ['veh_returned'] = 'Vehicle Returned!' 15 | } 16 | } 17 | Lang = Locale:new({phrases = Translations, warnOnMissing = true}) -------------------------------------------------------------------------------- /server/rentals_s.lua: -------------------------------------------------------------------------------- 1 | local QBCore = exports['qb-core']:GetCoreObject() 2 | 3 | QBCore.Functions.CreateUseableItem("rentalpapers", function(source, item, plate) 4 | TriggerEvent("vehiclekeys:client:SetOwner", plate) 5 | end) 6 | 7 | RegisterServerEvent('qb-rental:server:rentalpapers', function(plate, model) 8 | local src = source 9 | local Player = QBCore.Functions.GetPlayer(src) 10 | local info = {} 11 | info.citizenid = Player.PlayerData.citizenid 12 | info.firstname = Player.PlayerData.charinfo.firstname 13 | info.lastname = Player.PlayerData.charinfo.lastname 14 | info.plate = plate 15 | info.model = model 16 | TriggerClientEvent('inventory:client:ItemBox', src, QBCore.Shared.Items["rentalpapers"], 'add') 17 | Player.Functions.AddItem('rentalpapers', 1, false, info) 18 | end) 19 | 20 | 21 | RegisterServerEvent('qb-rental:server:removepapers', function(plate, model) 22 | local src = source 23 | local Player = QBCore.Functions.GetPlayer(src) 24 | TriggerClientEvent('inventory:client:ItemBox', src, QBCore.Shared.Items["rentalpapers"], 'remove') 25 | Player.Functions.RemoveItem('rentalpapers', 1, false, info) 26 | end) 27 | 28 | QBCore.Functions.CreateCallback('qb-rental:server:CashCheck',function(source, cb, money) 29 | local src = source 30 | local Player = QBCore.Functions.GetPlayer(src) 31 | if Player.PlayerData.money.cash >= money then 32 | cb(true) 33 | Player.Functions.RemoveMoney('cash', money) 34 | else 35 | cb(false) 36 | end 37 | end) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # qb-rentals 2 | -Screenshots 3 | ![image](https://user-images.githubusercontent.com/69292814/159167938-d4487811-f93d-4bc0-bf8f-7e2920921710.png) 4 | ![image](https://user-images.githubusercontent.com/69292814/159167964-c886494d-3f79-4845-8d6c-e2b0eb5189f8.png) 5 | 6 | 7 | Configured For Qb-spawn 8 | where player can directly rent vehicle as soon as they first time spawn in the server <3 9 | These Resource is forked And Menus are Changed its For only "Car" and Not Planes / Boats 10 | Just Plug and Play <3 11 | 12 | # Dependencies 13 | - [qb-target](https://github.com/BerkieBb/qb-target) 14 | - [qb-menu](https://github.com/qbcore-framework/qb-menu) 15 | 16 | # Installation 17 | - qb-spawn > configh.lua > 18 | ```lua 19 | Apartments = {} 20 | 21 | Apartments.Starting = true 22 | 23 | Apartments.SpawnOffset = 30 24 | 25 | Apartments.Locations = { 26 | ["apartment1"] = { 27 | name = "apartment1", 28 | label = "South Rockford Drive", 29 | coords = { 30 | enter = vector4(-667.372, -1106.034, 14.629, 65.033), 31 | } 32 | }, 33 | ["apartment2"] = { 34 | name = "apartment2", 35 | label = "Morningwood Blvd", 36 | coords = { 37 | enter = vector4(-1288.046, -430.126, 35.077, 305.348), 38 | } 39 | }, 40 | ["apartment3"] = { 41 | name = "apartment3", 42 | label = "Pinkage Apartments", 43 | coords = { 44 | enter = vector4(325.0117, -229.5926, 54.2172, 342.6726), 45 | } 46 | }, 47 | -- ["apartment4"] = { 48 | -- name = "apartment4", 49 | -- label = "Tinsel Towers", 50 | -- coords = { 51 | -- enter = vector4(-621.016, 46.677, 43.591, 179.36), 52 | -- } 53 | -- }, 54 | -- ["apartment5"] = { 55 | -- name = "apartment5", 56 | -- label = "Fantastic Plaza", 57 | -- coords = { 58 | -- enter = vector4(291.517, -1078.674, 29.405, 270.75), 59 | -- } 60 | -- }, 61 | } 62 | ``` 63 | 64 | - Find this in qb-target/init.lua 65 | - Put this in "Config.TargetModels" (more reliable to always keep target models in config) 66 | ```lua 67 | -- QB Rental 68 | ["VehicleRental"] = { 69 | models = { 70 | `a_m_y_business_03`, 71 | }, 72 | options = { 73 | { 74 | type = "client", 75 | event = "qb-rental:client:openMenu", 76 | icon = "fas fa-car", 77 | label = "Rent Vehicle", 78 | MenuType = "vehicle" 79 | }, 80 | }, 81 | distance = 3.0 82 | }, 83 | ["AircraftRental"] = { 84 | models = { 85 | `s_m_y_airworker`, 86 | }, 87 | options = { 88 | { 89 | type = "client", 90 | event = "qb-rental:client:openMenu", 91 | icon = "fas fa-car", 92 | label = "Rent Vehicle", 93 | MenuType = "aircraft" 94 | }, 95 | }, 96 | distance = 3.0 97 | }, 98 | ["Boatrental"] = { 99 | models = { 100 | `mp_m_boatstaff_01`, 101 | }, 102 | options = { 103 | { 104 | type = "client", 105 | event = "qb-rental:client:openMenu", 106 | icon = "fas fa-car", 107 | label = "Rent Vehicle", 108 | MenuType = "boat" 109 | }, 110 | }, 111 | distance = 3.0 112 | }, 113 | ``` 114 | 115 | # Rental Papers Item 116 | 117 | ```lua 118 | ["rentalpapers"] = {["name"] = "rentalpapers", ["label"] = "Rental Papers", ["weight"] = 0, ["type"] = "item", ["image"] = "rentalpapers.png", ["unique"] = true, ["useable"] = false, ["shouldClose"] = false, ["combinable"] = nil, ["description"] = "Yea, this is my car i can prove it!"}, 119 | ``` 120 | # Rental Papers Item Description - qb-inventory/html/js/app.js (Line 577) 121 | 122 | ```lua 123 | } else if (itemData.name == "stickynote") { 124 | $(".item-info-title").html('

' + itemData.label + '

') 125 | $(".item-info-description").html('

' + itemData.info.label + '

'); 126 | } else if (itemData.name == "rentalpapers") { 127 | $(".item-info-title").html('

' + itemData.label + '

') 128 | $(".item-info-description").html('

Name: '+ itemData.info.firstname + '

Last Name: '+ itemData.info.lastname+ '

Plate: '+ itemData.info.plate + '

Model: '+ itemData.info.model +'

'); 129 | ``` 130 | qb-rentals (Enhanced & Forked) 131 | 132 | 133 | -------------------------------------------------------------------------------- /client/rentals.lua: -------------------------------------------------------------------------------- 1 | local QBCore = exports['qb-core']:GetCoreObject() 2 | local SpawnVehicle = false 3 | 4 | -- Config Options 5 | 6 | local blips = { 7 | -- {title= Lang:t("info.land_veh"), colour= 50, id= 56, x= -672.33, y= -1105.1, z= 14.57}, 8 | -- {title= Lang:t("info.land_veh"), colour= 50, id= 56, x= -1673.39, y= -3158.45, z= 13.99}, 9 | -- {title= Lang:t("info.land_veh"), colour= 50, id= 56, x= -753.55, y= -1512.24, z= 5.02}, 10 | 11 | } 12 | 13 | local vehicles = { 14 | land = { 15 | [1] = { 16 | model = 'panto', 17 | money = 800, 18 | }, 19 | [2] = { 20 | model = 'issi7', 21 | money = 5000, 22 | }, 23 | [3] = { 24 | model = 'faggio2', 25 | money = 500, 26 | }, 27 | }, 28 | air = { 29 | [1] = { 30 | model = 'panto', 31 | money = 800, 32 | }, 33 | [2] = { 34 | model = 'issi7', 35 | money = 1500, 36 | }, 37 | [3] = { 38 | model = 'faggio2', 39 | money = 500, 40 | }, 41 | }, 42 | sea = { 43 | [1] = { 44 | model = 'panto', 45 | money = 800, 46 | }, 47 | [2] = { 48 | model = 'issi7', 49 | money = 1500, 50 | }, 51 | [3] = { 52 | model = 'faggio2', 53 | money = 500, 54 | }, 55 | } 56 | } 57 | -- Vehicle Rentals 58 | local comma_value = function(n) -- credit http://richard.warburton.it 59 | local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$') 60 | return left..(num:reverse():gsub('(%d%d%d)','%1,'):reverse())..right 61 | end 62 | 63 | RegisterNetEvent('qb-rental:client:openMenu', function(data) 64 | menu = data.MenuType 65 | local vehMenu = { 66 | [1] = { 67 | header = "Rental Vehicles", 68 | isMenuHeader = true, 69 | }, 70 | [2] = { 71 | id = 1, 72 | header = "Return Vehicle ", 73 | txt = Lang:t("task.return_veh"), 74 | params = { 75 | event = "qb-rental:client:return", 76 | } 77 | } 78 | } 79 | 80 | if menu == "vehicle" then 81 | for k=1, #vehicles.land do 82 | local veh = QBCore.Shared.Vehicles[vehicles.land[k].model] 83 | local name = veh and ('%s %s'):format(veh.brand, veh.name) or vehicles.land[k].model:sub(1,1):upper()..vehicles.land[k].model:sub(2) 84 | vehMenu[#vehMenu+1] = { 85 | id = k+1, 86 | header = name, 87 | txt = ("$%s"):format(comma_value(vehicles.land[k].money)), 88 | params = { 89 | event = "qb-rental:client:spawncar", 90 | args = { 91 | model = vehicles.land[k].model, 92 | money = vehicles.land[k].money, 93 | } 94 | } 95 | } 96 | end 97 | elseif menu == "aircraft" then 98 | for k=1, #vehicles.air do 99 | local veh = QBCore.Shared.Vehicles[vehicles.air[k].model] 100 | local name = veh and ('%s %s'):format(veh.brand, veh.name) or vehicles.air[k].model:sub(1,1):upper()..vehicles.air[k].model:sub(2) 101 | vehMenu[#vehMenu+1] = { 102 | id = k+1, 103 | header = name, 104 | txt = ("$%s"):format(comma_value(vehicles.air[k].money)), 105 | params = { 106 | event = "qb-rental:client:spawncar", 107 | args = { 108 | model = vehicles.air[k].model, 109 | money = vehicles.air[k].money, 110 | } 111 | } 112 | } 113 | end 114 | elseif menu == "boat" then 115 | for k=1, #vehicles.sea do 116 | local veh = QBCore.Shared.Vehicles[vehicles.sea[k].model] 117 | local name = veh and ('%s %s'):format(veh.brand, veh.name) or vehicles.sea[k].model:sub(1,1):upper()..vehicles.sea[k].model:sub(2) 118 | vehMenu[#vehMenu+1] = { 119 | id = k+1, 120 | header = name, 121 | txt = ("$%s"):format(comma_value(vehicles.sea[k].money)), 122 | params = { 123 | event = "qb-rental:client:spawncar", 124 | args = { 125 | model = vehicles.sea[k].model, 126 | money = vehicles.sea[k].money, 127 | } 128 | } 129 | } 130 | end 131 | end 132 | exports['qb-menu']:openMenu(vehMenu) 133 | end) 134 | 135 | local CreateNPC = function() 136 | -- Vehicle Rentals 137 | created_ped = CreatePed(5, `a_m_y_business_03` , -672.3297, -1105.0951, 13.5697, 296.3398, false, true) 138 | FreezeEntityPosition(created_ped, true) 139 | SetEntityInvincible(created_ped, true) 140 | SetBlockingOfNonTemporaryEvents(created_ped, true) 141 | TaskStartScenarioInPlace(created_ped, 'WORLD_HUMAN_CLIPBOARD', 0, true) 142 | 143 | -- Aircraft Rentals 144 | created_ped = CreatePed(5, `s_m_y_airworker` , -1282.5922, -426.0650, 33.7438, 123.2127, false, true) 145 | FreezeEntityPosition(created_ped, true) 146 | SetEntityInvincible(created_ped, true) 147 | SetBlockingOfNonTemporaryEvents(created_ped, true) 148 | TaskStartScenarioInPlace(created_ped, 'WORLD_HUMAN_CLIPBOARD', 0, true) 149 | 150 | -- Boat Rentals 151 | created_ped = CreatePed(5, `mp_m_boatstaff_01` , 323.5210, -233.8525, 53.2172, 325.5685, false, true) 152 | FreezeEntityPosition(created_ped, true) 153 | SetEntityInvincible(created_ped, true) 154 | SetBlockingOfNonTemporaryEvents(created_ped, true) 155 | TaskStartScenarioInPlace(created_ped, 'WORLD_HUMAN_CLIPBOARD', 0, true) 156 | end 157 | 158 | local SpawnNPC = function() 159 | CreateThread(function() 160 | -- Vehicle Rentals 161 | RequestModel(`a_m_y_business_03`) 162 | while not HasModelLoaded(`a_m_y_business_03`) do 163 | Wait(1) 164 | end 165 | -- Aircraft Rentals 166 | RequestModel(`s_m_y_airworker`) 167 | while not HasModelLoaded(`s_m_y_airworker`) do 168 | Wait(1) 169 | end 170 | -- Aircraft Rentals 171 | RequestModel(`mp_m_boatstaff_01`) 172 | while not HasModelLoaded(`mp_m_boatstaff_01`) do 173 | Wait(1) 174 | end 175 | CreateNPC() 176 | end) 177 | end 178 | 179 | CreateThread(function() 180 | SpawnNPC() 181 | end) 182 | 183 | RegisterNetEvent('qb-rental:client:spawncar', function(data) 184 | local player = PlayerPedId() 185 | local money = data.money 186 | local model = data.model 187 | local label = Lang:t("error.not_enough_space", {vehicle = menu:sub(1,1):upper()..menu:sub(2)}) 188 | if menu == "vehicle" then 189 | if IsAnyVehicleNearPoint(-683.0463, -1112.9353, 14.5255, 27.3474) then 190 | QBCore.Functions.Notify(label, "error", 4500) 191 | return 192 | end 193 | elseif menu == "aircraft" then 194 | if IsAnyVehicleNearPoint(-1285.3888, -428.2505, 34.7648, 26.0737) then 195 | QBCore.Functions.Notify(label, "error", 4500) 196 | return 197 | end 198 | elseif menu == "boat" then 199 | if IsAnyVehicleNearPoint(0, 0 ,0 ,0) then 200 | QBCore.Functions.Notify(label, "error", 4500) 201 | return 202 | end 203 | end 204 | 205 | QBCore.Functions.TriggerCallback("qb-rental:server:CashCheck",function(money) 206 | if money then 207 | if menu == "vehicle" then 208 | QBCore.Functions.SpawnVehicle(model, function(vehicle) 209 | SetEntityHeading(vehicle, 340.0) 210 | TaskWarpPedIntoVehicle(player, vehicle, -1) 211 | TriggerEvent("vehiclekeys:client:SetOwner", GetVehicleNumberPlateText(vehicle)) 212 | SetVehicleEngineOn(vehicle, true, true) 213 | SetVehicleDirtLevel(vehicle, 0.0) 214 | exports['lj-fuel']:SetFuel(vehicle, 100) 215 | SpawnVehicle = true 216 | end, vector4(-683.0463, -1112.9353, 14.5255, 27.3474), true) 217 | elseif menu == "aircraft" then 218 | QBCore.Functions.SpawnVehicle(model, function(vehicle) 219 | SetEntityHeading(vehicle, 331.49) 220 | TaskWarpPedIntoVehicle(player, vehicle, -1) 221 | TriggerEvent("vehiclekeys:client:SetOwner", GetVehicleNumberPlateText(vehicle)) 222 | SetVehicleEngineOn(vehicle, true, true) 223 | SetVehicleDirtLevel(vehicle, 0.0) 224 | exports['lj-fuel']:SetFuel(vehicle, 100) 225 | SpawnVehicle = true 226 | end, vector4(-1285.4110, -428.4428, 34.7691, 213.5654), true) 227 | elseif menu == "boat" then 228 | QBCore.Functions.SpawnVehicle(model, function(vehicle) 229 | SetEntityHeading(vehicle, 107.79) 230 | TaskWarpPedIntoVehicle(player, vehicle, -1) 231 | TriggerEvent("vehiclekeys:client:SetOwner", GetVehicleNumberPlateText(vehicle)) 232 | SetVehicleEngineOn(vehicle, true, true) 233 | SetVehicleDirtLevel(vehicle, 0.0) 234 | exports['lj-fuel']:SetFuel(vehicle, 100) 235 | SpawnVehicle = true 236 | end, vector4(326.4486, -207.0242, 54.0866, 156.5508), true) 237 | end 238 | Wait(1000) 239 | local vehicle = GetVehiclePedIsIn(player, false) 240 | QBCore.Functions.Notify(Lang:t("To Return The Vehicle Please Go To The Man That Gave You nd Ask Him to Take It Back"), 'success', 10000) 241 | local vehicleLabel = GetDisplayNameFromVehicleModel(GetEntityModel(vehicle)) 242 | vehicleLabel = GetLabelText(vehicleLabel) 243 | local plate = GetVehicleNumberPlateText(vehicle) 244 | TriggerServerEvent('qb-rental:server:rentalpapers', plate, vehicleLabel) 245 | else 246 | QBCore.Functions.Notify(Lang:t("error.not_enough_money"), "error", 4500) 247 | end 248 | end, money) 249 | end) 250 | 251 | RegisterNetEvent('qb-rental:client:return', function() 252 | if SpawnVehicle then 253 | local Player = QBCore.Functions.GetPlayerData() 254 | QBCore.Functions.Notify(Lang:t("task.veh_returned"), 'success') 255 | TriggerServerEvent('qb-rental:server:removepapers') 256 | local car = GetVehiclePedIsIn(PlayerPedId(),true) 257 | NetworkFadeOutEntity(car, true,false) 258 | Citizen.Wait(2000) 259 | QBCore.Functions.DeleteVehicle(car) 260 | else 261 | QBCore.Functions.Notify(Lang:t("error.no_vehicle"), "error") 262 | end 263 | SpawnVehicle = false 264 | end) 265 | 266 | Citizen.CreateThread(function() 267 | for _, info in pairs(blips) do 268 | info.blip = AddBlipForCoord(info.x, info.y, info.z) 269 | SetBlipSprite(info.blip, info.id) 270 | SetBlipDisplay(info.blip, 4) 271 | SetBlipScale(info.blip, 0.65) 272 | SetBlipColour(info.blip, info.colour) 273 | SetBlipAsShortRange(info.blip, true) 274 | BeginTextCommandSetBlipName("STRING") 275 | AddTextComponentString(info.title) 276 | EndTextCommandSetBlipName(info.blip) 277 | end 278 | end) --------------------------------------------------------------------------------