From 904774b6a849cef29d8452b6b51af976cb16eff8 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 30 Dec 2018 23:29:04 +0100 Subject: [PATCH] Implemented new vehicle garage, final commit v1.2.0 --- __resource.lua | 2 +- client/job.lua | 248 ++++++++++++++++++++++++++++++------------------ config.lua | 50 +++++++--- locales/br.lua | 4 +- locales/cs.lua | 4 +- locales/en.lua | 4 +- locales/es.lua | 4 +- locales/fi.lua | 4 +- locales/fr.lua | 4 +- locales/pl.lua | 4 +- locales/sv.lua | 4 +- server/main.lua | 16 +++- 12 files changed, 229 insertions(+), 119 deletions(-) diff --git a/__resource.lua b/__resource.lua index 5033c6cd..5c55606b 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ESX Ambulance Job' -version '1.1.1' +version '1.2.0' server_scripts { '@mysql-async/lib/MySQL.lua', diff --git a/client/job.lua b/client/job.lua index ba29aabd..62ab2a94 100644 --- a/client/job.lua +++ b/client/job.lua @@ -265,20 +265,6 @@ Citizen.CreateThread(function() end end - -- Vehicle Deleters - for k,v in ipairs(hospital.VehicleDeleters) do - local distance = GetDistanceBetweenCoords(playerCoords, v, true) - - if distance < Config.DrawDistance then - DrawMarker(Config.Marker.type, v, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.Marker.x, Config.Marker.y, Config.Marker.z, Config.Marker.r, Config.Marker.g, Config.Marker.b, Config.Marker.a, false, false, 2, Config.Marker.rotate, nil, nil, false) - canSleep = false - end - - if distance < Config.Marker.x then - isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'VehicleDeleter', k - end - end - -- Fast Travels for k,v in ipairs(hospital.FastTravels) do local distance = GetDistanceBetweenCoords(playerCoords, v.From, true) @@ -446,7 +432,6 @@ AddEventHandler('esx_ambulancejob:putInVehicle', function() end end) - function OpenCloakroomMenu() ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'cloakroom', { @@ -478,28 +463,164 @@ function OpenCloakroomMenu() end function OpenVehicleSpawnerMenu(hospital, partNum) + local playerCoords = GetEntityCoords(PlayerPedId()) + local elements = { + {label = _U('garage_storeditem'), action = 'garage'}, + {label = _U('garage_storeitem'), action = 'store_garage'}, + {label = _U('garage_buyitem'), action = 'buy_vehicle'} + } - ESX.UI.Menu.CloseAll() + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle', { + title = _U('garage_title'), + align = 'top-left', + elements = elements + }, function(data, menu) - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_spawner', - { - title = _U('garage_title'), - align = 'top-left', - elements = Config.AuthorizedVehicles - }, function(data, menu) - menu.close() + if data.current.action == 'buy_vehicle' then + local shopCoords = Config.Hospitals[hospital].Vehicles[partNum].InsideShop + local shopElements = {} - local foundSpawn, spawnPoint = GetAvailableVehicleSpawnPoint(hospital, 'Vehicles', partNum) + local authorizedVehicles = Config.AuthorizedVehicles[ESX.PlayerData.job.grade_name] - if foundSpawn then - ESX.Game.SpawnVehicle(data.current.model, spawnPoint.coords, spawnPoint.heading, function(vehicle) - local playerPed = PlayerPedId() - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - end) + if #authorizedVehicles > 0 then + for k,vehicle in ipairs(authorizedVehicles) do + table.insert(shopElements, { + label = ('%s - %s'):format(vehicle.label, _U('shop_item', ESX.Math.GroupDigits(vehicle.price))), + name = vehicle.label, + model = vehicle.model, + price = vehicle.price, + type = 'car' + }) + end + else + return end - end, function(data, menu) - menu.close() - end) + + OpenShopMenu(shopElements, playerCoords, shopCoords) + elseif data.current.action == 'garage' then + local garage = {} + + ESX.TriggerServerCallback('esx_vehicleshop:retrieveJobVehicles', function(jobVehicles) + if #jobVehicles > 0 then + for k,v in ipairs(jobVehicles) do + local props = json.decode(v.vehicle) + local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(props.model)) + local label = ('%s - %s: '):format(vehicleName, props.plate) + + if v.stored then + label = label .. ('%s'):format(_U('garage_stored')) + else + label = label .. ('%s'):format(_U('garage_notstored')) + end + + table.insert(garage, { + label = label, + stored = v.stored, + model = props.model, + vehicleProps = props + }) + end + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_garage', { + title = _U('garage_title'), + align = 'top-left', + elements = garage + }, function(data2, menu2) + if data2.current.stored then + local foundSpawn, spawnPoint = GetAvailableVehicleSpawnPoint(hospital, 'Vehicles', partNum) + + if foundSpawn then + menu2.close() + + ESX.Game.SpawnVehicle(data2.current.model, spawnPoint.coords, spawnPoint.heading, function(vehicle) + ESX.Game.SetVehicleProperties(vehicle, data2.current.vehicleProps) + + TriggerServerEvent('esx_vehicleshop:setJobVehicleState', data2.current.vehicleProps.plate, false) + ESX.ShowNotification(_U('garage_released')) + end) + end + else + ESX.ShowNotification(_U('garage_notavailable')) + end + end, function(data2, menu2) + menu2.close() + end) + + else + ESX.ShowNotification(_U('garage_empty')) + end + end, 'car') + + elseif data.current.action == 'store_garage' then + StoreNearbyVehicle(playerCoords) + end + + end, function(data, menu) + menu.close() + end) + +end + +function StoreNearbyVehicle(playerCoords) + local vehicles, vehiclePlates = ESX.Game.GetVehiclesInArea(playerCoords, 30.0), {} + + if #vehicles > 0 then + for k,v in ipairs(vehicles) do + + -- Make sure the vehicle we're saving is empty, or else it wont be deleted + if GetVehicleNumberOfPassengers(v) == 0 and IsVehicleSeatFree(v, -1) then + table.insert(vehiclePlates, { + vehicle = v, + plate = ESX.Math.Trim(GetVehicleNumberPlateText(v)) + }) + end + end + else + ESX.ShowNotification(_U('garage_store_nearby')) + return + end + + ESX.TriggerServerCallback('esx_ambulancejob:storeNearbyVehicle', function(storeSuccess, foundNum) + if storeSuccess then + local vehicleId = vehiclePlates[foundNum] + local attempts = 0 + ESX.Game.DeleteVehicle(vehicleId.vehicle) + IsBusy = true + + Citizen.CreateThread(function() + while IsBusy do + Citizen.Wait(0) + drawLoadingText(_U('garage_storing'), 255, 255, 255, 255) + end + end) + + -- Workaround for vehicle not deleting when other players are near it. + while DoesEntityExist(vehicleId.vehicle) do + Citizen.Wait(500) + attempts = attempts + 1 + + -- Give up + if attempts > 30 then + break + end + + vehicles = ESX.Game.GetVehiclesInArea(playerCoords, 30.0) + if #vehicles > 0 then + for k,v in ipairs(vehicles) do + if ESX.Math.Trim(GetVehicleNumberPlateText(v)) == vehicleId.plate then + ESX.Game.DeleteVehicle(v) + break + end + end + end + end + + IsBusy = false + ESX.ShowNotification(_U('garage_has_stored')) + else + ESX.ShowNotification(_U('garage_has_notstored')) + end + end, vehiclePlates) end function GetAvailableVehicleSpawnPoint(hospital, part, partNum) @@ -612,66 +733,7 @@ function OpenHelicopterSpawnerMenu(hospital, partNum) end, 'helicopter') elseif data.current.action == 'store_garage' then - local vehicles, vehiclePlates = ESX.Game.GetVehiclesInArea(playerCoords, 30.0), {} - - if #vehicles > 0 then - for k,v in ipairs(vehicles) do - - -- Make sure the vehicle we're saving is empty, or else it wont be deleted - if GetVehicleNumberOfPassengers(v) == 0 and IsVehicleSeatFree(v, -1) then - table.insert(vehiclePlates, { - vehicle = v, - plate = ESX.Math.Trim(GetVehicleNumberPlateText(v)) - }) - end - end - else - ESX.ShowNotification(_U('garage_store_nearby')) - return - end - - ESX.TriggerServerCallback('esx_ambulancejob:storeNearbyVehicle', function(storeSuccess, foundNum) - if storeSuccess then - local vehicleId = vehiclePlates[foundNum] - local attempts = 0 - ESX.Game.DeleteVehicle(vehicleId.vehicle) - IsBusy = true - - Citizen.CreateThread(function() - while IsBusy do - Citizen.Wait(0) - drawLoadingText(_U('garage_storing'), 255, 255, 255, 255) - end - end) - - -- Workaround for vehicle not deleting when other players are near it. - while DoesEntityExist(vehicleId.vehicle) do - Citizen.Wait(500) - attempts = attempts + 1 - - -- Give up - if attempts > 30 then - break - end - - vehicles = ESX.Game.GetVehiclesInArea(playerCoords, 30.0) - if #vehicles > 0 then - for k,v in ipairs(vehicles) do - if ESX.Math.Trim(GetVehicleNumberPlateText(v)) == vehicleId.plate then - ESX.Game.DeleteVehicle(v) - break - end - end - end - end - - IsBusy = false - ESX.ShowNotification(_U('garage_has_stored')) - else - ESX.ShowNotification(_U('garage_has_notstored')) - end - end, vehiclePlates) - + StoreNearbyVehicle(playerCoords) end end, function(data, menu) @@ -722,7 +784,7 @@ function OpenShopMenu(elements, restoreCoords, shopCoords) ESX.ShowNotification(_U('vehicleshop_money')) menu2.close() end - end, props) + end, props, data.current.type) else menu2.close() end diff --git a/config.lua b/config.lua index 9ace4628..59930ec6 100644 --- a/config.lua +++ b/config.lua @@ -49,6 +49,7 @@ Config.Hospitals = { Vehicles = { { Spawner = vector3(307.7, -1433.4, 30.0), + InsideShop = vector3(446.7, -1355.6, 43.5), Marker = { type = 36, x = 1.0, y = 1.0, z = 1.0, r = 100, g = 50, b = 200, a = 100, rotate = true }, SpawnPoints = { { coords = vector3(297.2, -1429.5, 29.8), heading = 227.6, radius = 4.0 }, @@ -70,10 +71,6 @@ Config.Hospitals = { } }, - VehicleDeleters = { - vector3(327.6, -1481.1, 28.8) - }, - FastTravels = { { From = vector3(294.7, -1448.1, 29.0), @@ -131,6 +128,42 @@ Config.Hospitals = { } } +Config.AuthorizedVehicles = { + + ambulance = { + { + model = 'ambulance', + label = 'Ambulance Van', + price = 5000 + } + }, + + doctor = { + { + model = 'ambulance', + label = 'Ambulance Van', + price = 4500 + } + }, + + chief_doctor = { + { + model = 'ambulance', + label = 'Ambulance Van', + price = 3000 + } + }, + + boss = { + { + model = 'ambulance', + label = 'Ambulance Van', + price = 2000 + } + } + +} + Config.AuthorizedHelicopters = { ambulance = {}, @@ -172,12 +205,3 @@ Config.AuthorizedHelicopters = { } } - -Config.AuthorizedVehicles = { - - { - model = 'ambulance', - label = 'Ambulance' - } - -} diff --git a/locales/br.lua b/locales/br.lua index 8e242216..be0dbc50 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -4,7 +4,6 @@ Locales['br'] = { ['ems_clothes_civil'] = 'Roupa Normal', ['ems_clothes_ems'] = 'Entrar como Socorrista', -- Vehicles - ['store_veh'] = 'press ~INPUT_CONTEXT~ to store the vehicle', ['ambulance'] = 'ambulance', ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', ['helicopter_buy'] = 'helicopter shop', @@ -25,6 +24,9 @@ Locales['br'] = { ['garage_empty'] = 'you dont have any vehicles in your garage.', ['garage_released'] = 'your vehicle has been released from the garage.', ['garage_store_nearby'] = 'there is no nearby vehicles.', + ['garage_storeditem'] = 'open garage', + ['garage_storeitem'] = 'store vehicle in garage', + ['garage_buyitem'] = 'vehicle shop', ['shop_item'] = '$%s', ['vehicleshop_title'] = 'vehicle Shop', ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', diff --git a/locales/cs.lua b/locales/cs.lua index 97830152..48dc7cc2 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -4,7 +4,6 @@ Locales['cs'] = { ['ems_clothes_civil'] = 'civilní oblečení', ['ems_clothes_ems'] = 'zdravotnické oblečení', -- Vehicles - ['store_veh'] = 'press ~INPUT_CONTEXT~ to store the vehicle', ['ambulance'] = 'ambulance', ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', ['helicopter_buy'] = 'helicopter shop', @@ -25,6 +24,9 @@ Locales['cs'] = { ['garage_empty'] = 'you dont have any vehicles in your garage.', ['garage_released'] = 'your vehicle has been released from the garage.', ['garage_store_nearby'] = 'there is no nearby vehicles.', + ['garage_storeditem'] = 'open garage', + ['garage_storeitem'] = 'store vehicle in garage', + ['garage_buyitem'] = 'vehicle shop', ['shop_item'] = '$%s', ['vehicleshop_title'] = 'vehicle Shop', ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', diff --git a/locales/en.lua b/locales/en.lua index 6630b045..b13f48fe 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -4,7 +4,6 @@ Locales['en'] = { ['ems_clothes_civil'] = 'civilian Clothes', ['ems_clothes_ems'] = 'EMS Clothes', -- Vehicles - ['store_veh'] = 'press ~INPUT_CONTEXT~ to store the vehicle', ['ambulance'] = 'ambulance', ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', ['helicopter_buy'] = 'helicopter shop', @@ -25,6 +24,9 @@ Locales['en'] = { ['garage_empty'] = 'you dont have any vehicles in your garage.', ['garage_released'] = 'your vehicle has been released from the garage.', ['garage_store_nearby'] = 'there is no nearby vehicles.', + ['garage_storeditem'] = 'open garage', + ['garage_storeitem'] = 'store vehicle in garage', + ['garage_buyitem'] = 'vehicle shop', ['shop_item'] = '$%s', ['vehicleshop_title'] = 'vehicle Shop', ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', diff --git a/locales/es.lua b/locales/es.lua index d5632333..5b1e4ecb 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -4,7 +4,6 @@ Locales['es'] = { ['ems_clothes_civil'] = 'Camiseta', ['ems_clothes_ems'] = 'Equipo de ambulancia', -- Vehicles - ['store_veh'] = 'press ~INPUT_CONTEXT~ to store the vehicle', ['ambulance'] = 'ambulance', ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', ['helicopter_buy'] = 'helicopter shop', @@ -25,6 +24,9 @@ Locales['es'] = { ['garage_empty'] = 'you dont have any vehicles in your garage.', ['garage_released'] = 'your vehicle has been released from the garage.', ['garage_store_nearby'] = 'there is no nearby vehicles.', + ['garage_storeditem'] = 'open garage', + ['garage_storeitem'] = 'store vehicle in garage', + ['garage_buyitem'] = 'vehicle shop', ['shop_item'] = '$%s', ['vehicleshop_title'] = 'vehicle Shop', ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', diff --git a/locales/fi.lua b/locales/fi.lua index 0d0d8e21..ac99fc65 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -4,7 +4,6 @@ Locales['fi'] = { ['ems_clothes_civil'] = 'Siviilikamppeet', ['ems_clothes_ems'] = 'Työkamppeet', -- Vehicles - ['store_veh'] = 'press ~INPUT_CONTEXT~ to store the vehicle', ['ambulance'] = 'ambulance', ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', ['helicopter_buy'] = 'helicopter shop', @@ -25,6 +24,9 @@ Locales['fi'] = { ['garage_empty'] = 'you dont have any vehicles in your garage.', ['garage_released'] = 'your vehicle has been released from the garage.', ['garage_store_nearby'] = 'there is no nearby vehicles.', + ['garage_storeditem'] = 'open garage', + ['garage_storeitem'] = 'store vehicle in garage', + ['garage_buyitem'] = 'vehicle shop', ['shop_item'] = '$%s', ['vehicleshop_title'] = 'vehicle Shop', ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', diff --git a/locales/fr.lua b/locales/fr.lua index 7e3615e6..5e4bf47e 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -4,7 +4,6 @@ Locales['fr'] = { ['ems_clothes_civil'] = 'Tenue Civil', ['ems_clothes_ems'] = 'Tenue Ambulancier', -- Vehicles - ['store_veh'] = 'press ~INPUT_CONTEXT~ to store the vehicle', ['ambulance'] = 'ambulance', ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', ['helicopter_buy'] = 'helicopter shop', @@ -25,6 +24,9 @@ Locales['fr'] = { ['garage_empty'] = 'you dont have any vehicles in your garage.', ['garage_released'] = 'your vehicle has been released from the garage.', ['garage_store_nearby'] = 'there is no nearby vehicles.', + ['garage_storeditem'] = 'open garage', + ['garage_storeitem'] = 'store vehicle in garage', + ['garage_buyitem'] = 'vehicle shop', ['shop_item'] = '$%s', ['vehicleshop_title'] = 'vehicle Shop', ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', diff --git a/locales/pl.lua b/locales/pl.lua index 4e9b36ce..61778ccc 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -4,7 +4,6 @@ Locales['pl'] = { ['ems_clothes_civil'] = 'ubrania cywilne', ['ems_clothes_ems'] = 'ubrania EMS', -- Vehicles - ['store_veh'] = 'press ~INPUT_CONTEXT~ to store the vehicle', ['ambulance'] = 'ambulance', ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', ['helicopter_buy'] = 'helicopter shop', @@ -25,6 +24,9 @@ Locales['pl'] = { ['garage_empty'] = 'you dont have any vehicles in your garage.', ['garage_released'] = 'your vehicle has been released from the garage.', ['garage_store_nearby'] = 'there is no nearby vehicles.', + ['garage_storeditem'] = 'open garage', + ['garage_storeitem'] = 'store vehicle in garage', + ['garage_buyitem'] = 'vehicle shop', ['shop_item'] = '$%s', ['vehicleshop_title'] = 'vehicle Shop', ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', diff --git a/locales/sv.lua b/locales/sv.lua index 851a8ccf..0693cfd1 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -4,7 +4,6 @@ Locales['sv'] = { ['ems_clothes_civil'] = 'civilkläder', ['ems_clothes_ems'] = 'ambulanskläder', -- Vehicles - ['store_veh'] = 'press ~INPUT_CONTEXT~ to store the vehicle', ['ambulance'] = 'ambulance', ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', ['helicopter_buy'] = 'helicopter shop', @@ -25,6 +24,9 @@ Locales['sv'] = { ['garage_empty'] = 'you dont have any vehicles in your garage.', ['garage_released'] = 'your vehicle has been released from the garage.', ['garage_store_nearby'] = 'there is no nearby vehicles.', + ['garage_storeditem'] = 'open garage', + ['garage_storeitem'] = 'store vehicle in garage', + ['garage_buyitem'] = 'vehicle shop', ['shop_item'] = '%s SEK', ['vehicleshop_title'] = 'vehicle Shop', ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', diff --git a/server/main.lua b/server/main.lua index 172b61dc..9dfa4d69 100644 --- a/server/main.lua +++ b/server/main.lua @@ -110,9 +110,9 @@ ESX.RegisterServerCallback('esx_ambulancejob:getItemAmount', function(source, cb cb(quantity) end) -ESX.RegisterServerCallback('esx_ambulancejob:buyJobVehicle', function(source, cb, vehicleProps) +ESX.RegisterServerCallback('esx_ambulancejob:buyJobVehicle', function(source, cb, vehicleProps, type) local xPlayer = ESX.GetPlayerFromId(source) - local price = getPriceFromHash(vehicleProps.model, xPlayer.job.grade_name, 'heli') + local price = getPriceFromHash(vehicleProps.model, xPlayer.job.grade_name, type) -- vehicle model not found if price == 0 then @@ -127,7 +127,7 @@ ESX.RegisterServerCallback('esx_ambulancejob:buyJobVehicle', function(source, cb ['@owner'] = xPlayer.identifier, ['@vehicle'] = json.encode(vehicleProps), ['@plate'] = vehicleProps.plate, - ['@type'] = 'helicopter', + ['@type'] = type, ['@job'] = xPlayer.job.name, ['@stored'] = true }, function (rowsChanged) @@ -175,9 +175,17 @@ ESX.RegisterServerCallback('esx_ambulancejob:storeNearbyVehicle', function(sourc end) function getPriceFromHash(hashKey, jobGrade, type) - if type == 'heli' then + if type == 'helicopter' then local vehicles = Config.AuthorizedHelicopters[jobGrade] + for k,v in ipairs(vehicles) do + if GetHashKey(v.model) == hashKey then + return v.price + end + end + elseif type == 'car' then + local vehicles = Config.AuthorizedVehicles[jobGrade] + for k,v in ipairs(vehicles) do if GetHashKey(v.model) == hashKey then return v.price