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