From e7eabab21285efbf14e21e2d1184f2cbce62b041 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 30 Dec 2018 23:05:04 +0100 Subject: [PATCH] New helicopter system, Config re-write --- README.md | 3 +- __resource.lua | 5 +- client/job.lua | 750 ++++++++++++++++++++++++++++++++++-------------- client/main.lua | 42 +-- config.lua | 269 +++++++++-------- locales/br.lua | 36 ++- locales/cs.lua | 36 ++- locales/en.lua | 34 ++- locales/es.lua | 36 ++- locales/fi.lua | 36 ++- locales/fr.lua | 34 ++- locales/pl.lua | 36 ++- locales/sv.lua | 36 ++- server/main.lua | 78 +++++ 14 files changed, 1032 insertions(+), 399 deletions(-) diff --git a/README.md b/README.md index 0cbb8348..f2c3b451 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,9 @@ * Auto mode - [esx_skin](https://github.com/ESX-Org/esx_skin) + - [esx_vehicleshop](https://github.com/ESX-Org/esx_vehicleshop) -* Player management (boss actions **There is no way to earn money for now**) +* Player management (boss actions) - [esx_society](https://github.com/ESX-Org/esx_society) ## Download & Installation diff --git a/__resource.lua b/__resource.lua index c6218a17..5033c6cd 100644 --- a/__resource.lua +++ b/__resource.lua @@ -34,4 +34,7 @@ client_scripts { 'client/job.lua' } -dependency 'es_extended' +dependencies { + 'es_extended', + 'esx_vehicleshop' +} \ No newline at end of file diff --git a/client/job.lua b/client/job.lua index b5cdc1ce..ba29aabd 100644 --- a/client/job.lua +++ b/client/job.lua @@ -1,5 +1,7 @@ -local HasAlreadyEnteredMarker, LastZone, CurrentAction, CurrentActionMsg, CurrentActionData = nil, nil, nil, '', {} +local CurrentAction, CurrentActionMsg, CurrentActionData = nil, '', {} +local HasAlreadyEnteredMarker, LastHospital, LastPart, LastPartNum local IsBusy = false +local spawnedVehicles, isInShopMenu = {}, false function OpenAmbulanceActionsMenu() local elements = { @@ -27,10 +29,6 @@ function OpenAmbulanceActionsMenu() end end, function(data, menu) menu.close() - - CurrentAction = 'ambulance_actions_menu' - CurrentActionMsg = _U('open_menu') - CurrentActionData = {} end) end @@ -179,184 +177,246 @@ function OpenMobileAmbulanceActionsMenu() end) end - -AddEventHandler('esx_ambulancejob:hasEnteredMarker', function(zone) - if zone == 'HospitalInteriorEntering1' then - TeleportFadeEffect(PlayerPedId(), Config.Zones.HospitalInteriorInside1.Pos) - elseif zone == 'HospitalInteriorExit1' then - TeleportFadeEffect(PlayerPedId(), Config.Zones.HospitalInteriorOutside1.Pos) - elseif zone == 'HospitalInteriorEntering2' then - local heli = Config.HelicopterSpawner - - if not IsAnyVehicleNearPoint(heli.SpawnPoint.x, heli.SpawnPoint.y, heli.SpawnPoint.z, 3.0) and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'ambulance' then - ESX.Game.SpawnVehicle('polmav', { - x = heli.SpawnPoint.x, - y = heli.SpawnPoint.y, - z = heli.SpawnPoint.z - }, heli.Heading, function(vehicle) - SetVehicleModKit(vehicle, 0) - SetVehicleLivery(vehicle, 1) - end) - end - TeleportFadeEffect(PlayerPedId(), Config.Zones.HospitalInteriorInside2.Pos) - elseif zone == 'HospitalInteriorExit2' then - TeleportFadeEffect(PlayerPedId(), Config.Zones.HospitalInteriorOutside2.Pos) - elseif zone == 'ParkingDoorGoOutInside' then - TeleportFadeEffect(PlayerPedId(), Config.Zones.ParkingDoorGoOutOutside.Pos) - elseif zone == 'ParkingDoorGoInOutside' then - TeleportFadeEffect(PlayerPedId(), Config.Zones.ParkingDoorGoInInside.Pos) - elseif zone == 'StairsGoTopBottom' then - CurrentAction = 'fast_travel_goto_top' - CurrentActionMsg = _U('fast_travel') - CurrentActionData = {pos = Config.Zones.StairsGoTopTop.Pos} - elseif zone == 'StairsGoBottomTop' then - CurrentAction = 'fast_travel_goto_bottom' - CurrentActionMsg = _U('fast_travel') - CurrentActionData = {pos = Config.Zones.StairsGoBottomBottom.Pos} - elseif zone == 'AmbulanceActions' then - CurrentAction = 'ambulance_actions_menu' - CurrentActionMsg = _U('open_menu') - CurrentActionData = {} - elseif zone == 'VehicleSpawner' then - CurrentAction = 'vehicle_spawner_menu' - CurrentActionMsg = _U('veh_spawn') - CurrentActionData = {} - elseif zone == 'Pharmacy' then - CurrentAction = 'pharmacy' - CurrentActionMsg = _U('open_pharmacy') - CurrentActionData = {} - elseif zone == 'VehicleDeleter' then - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - - if IsPedInAnyVehicle(playerPed, false) then - local vehicle, distance = ESX.Game.GetClosestVehicle({ - x = coords.x, - y = coords.y, - z = coords.z - }) - - if distance ~= -1 and distance <= 1.0 then - CurrentAction = 'delete_vehicle' - CurrentActionMsg = _U('store_veh') - CurrentActionData = {vehicle = vehicle} - end - end - end -end) - -function FastTravel(pos) - TeleportFadeEffect(PlayerPedId(), pos) +function FastTravel(coords, heading) + TeleportFadeEffect(PlayerPedId(), coords, heading) end -AddEventHandler('esx_ambulancejob:hasExitedMarker', function(zone) - ESX.UI.Menu.CloseAll() - CurrentAction = nil -end) +function TeleportFadeEffect(entity, coords, heading) + Citizen.CreateThread(function() + DoScreenFadeOut(800) --- Create blips -Citizen.CreateThread(function() - local blip = AddBlipForCoord(Config.Blip.Pos.x, Config.Blip.Pos.y, Config.Blip.Pos.z) + while not IsScreenFadedOut() do + Citizen.Wait(0) + end - SetBlipSprite(blip, Config.Blip.Sprite) - SetBlipDisplay(blip, Config.Blip.Display) - SetBlipScale(blip, Config.Blip.Scale) - SetBlipColour(blip, Config.Blip.Colour) - SetBlipAsShortRange(blip, true) + ESX.Game.Teleport(entity, coords, function() + DoScreenFadeIn(800) - BeginTextCommandSetBlipName("STRING") - AddTextComponentString(_U('hospital')) - EndTextCommandSetBlipName(blip) -end) + if heading then + SetEntityHeading(entity, heading) + end + end) + end) +end --- Display markers +-- Draw markers & Marker logic Citizen.CreateThread(function() while true do Citizen.Wait(0) + local playerCoords = GetEntityCoords(PlayerPedId()) + local canSleep, isInMarker, hasExited = true, false, false + local currentHospital, currentPart, currentPartNum - local coords = GetEntityCoords(PlayerPedId()) - for k,v in pairs(Config.Zones) do - if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then - if ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'ambulance' then - DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.MarkerSize.x, Config.MarkerSize.y, Config.MarkerSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) - elseif k ~= 'AmbulanceActions' and k ~= 'VehicleSpawner' and k ~= 'VehicleDeleter' and k ~= 'Pharmacy' and k ~= 'StairsGoTopBottom' and k ~= 'StairsGoBottomTop' then - DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.MarkerSize.x, Config.MarkerSize.y, Config.MarkerSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) + for hospitalNum,hospital in pairs(Config.Hospitals) do + + -- Ambulance Actions + for k,v in ipairs(hospital.AmbulanceActions) 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, 'AmbulanceActions', k end end + + -- Pharmacies + for k,v in ipairs(hospital.Pharmacies) 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, 'Pharmacy', k + end + end + + -- Vehicle Spawners + for k,v in ipairs(hospital.Vehicles) do + local distance = GetDistanceBetweenCoords(playerCoords, v.Spawner, true) + + if distance < Config.DrawDistance then + DrawMarker(v.Marker.type, v.Spawner, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) + canSleep = false + end + + if distance < v.Marker.x then + isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'Vehicles', k + end + end + + -- Helicopter Spawners + for k,v in ipairs(hospital.Helicopters) do + local distance = GetDistanceBetweenCoords(playerCoords, v.Spawner, true) + + if distance < Config.DrawDistance then + DrawMarker(v.Marker.type, v.Spawner, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) + canSleep = false + end + + if distance < v.Marker.x then + isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'Helicopters', k + 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) + + if distance < Config.DrawDistance then + DrawMarker(v.Marker.type, v.From, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) + canSleep = false + end + + + if distance < v.Marker.x then + FastTravel(v.To.coords, v.To.heading) + end + end + + -- Fast Travels (Prompt) + for k,v in ipairs(hospital.FastTravelsPrompt) do + local distance = GetDistanceBetweenCoords(playerCoords, v.From, true) + + if distance < Config.DrawDistance then + DrawMarker(v.Marker.type, v.From, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) + canSleep = false + end + + if distance < v.Marker.x then + isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'FastTravelsPrompt', k + end + end + + -- Logic for exiting & entering markers + if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastHospital ~= currentHospital or LastPart ~= currentPart or LastPartNum ~= currentPartNum)) then + + if + (LastHospital ~= nil and LastPart ~= nil and LastPartNum ~= nil) and + (LastHospital ~= currentHospital or LastPart ~= currentPart or LastPartNum ~= currentPartNum) + then + TriggerEvent('esx_ambulancejob:hasExitedMarker', LastHospital, LastPart, LastPartNum) + hasExited = true + end + + HasAlreadyEnteredMarker, LastHospital, LastPart, LastPartNum = true, currentHospital, currentPart, currentPartNum + + TriggerEvent('esx_ambulancejob:hasEnteredMarker', currentHospital, currentPart, currentPartNum) + + end + + if not hasExited and not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent('esx_ambulancejob:hasExitedMarker', LastHospital, LastPart, LastPartNum) + end + end end end) --- Activate menu when player is inside marker -Citizen.CreateThread(function() - while true do - Citizen.Wait(10) +AddEventHandler('esx_ambulancejob:hasEnteredMarker', function(hospital, part, partNum) + if part == 'AmbulanceActions' then + CurrentAction = part + CurrentActionMsg = _U('actions_prompt') + CurrentActionData = {} + elseif part == 'Pharmacy' then + CurrentAction = part + CurrentActionMsg = _U('open_pharmacy') + CurrentActionData = {} + elseif part == 'Vehicles' then + CurrentAction = part + CurrentActionMsg = _U('garage_prompt') + CurrentActionData = {hospital = hospital, partNum = partNum} + elseif part == 'Helicopters' then + CurrentAction = part + CurrentActionMsg = _U('helicopter_prompt') + CurrentActionData = {hospital = hospital, partNum = partNum} + elseif part == 'VehicleDeleter' then - local coords = GetEntityCoords(PlayerPedId()) - local isInMarker = false - local currentZone = nil + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) - for k,v in pairs(Config.Zones) do - if ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'ambulance' then - if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.MarkerSize.x) then - isInMarker = true - currentZone = k - end - elseif k ~= 'AmbulanceActions' and k ~= 'VehicleSpawner' and k ~= 'VehicleDeleter' and k ~= 'Pharmacy' and k ~= 'StairsGoTopBottom' and k ~= 'StairsGoBottomTop' then - if(GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.MarkerSize.x) then - isInMarker = true - currentZone = k - end + if IsPedInAnyVehicle(playerPed, false) then + local vehicle, distance = ESX.Game.GetClosestVehicle(coords) + + if distance ~= -1 and distance <= 1.0 then + CurrentAction = part + CurrentActionMsg = _U('store_veh') + CurrentActionData = {vehicle = vehicle} end end - if isInMarker and not hasAlreadyEnteredMarker then - hasAlreadyEnteredMarker = true - lastZone = currentZone - TriggerEvent('esx_ambulancejob:hasEnteredMarker', currentZone) - end + elseif part == 'FastTravelsPrompt' then + local travelItem = Config.Hospitals[hospital][part][partNum] - if not isInMarker and hasAlreadyEnteredMarker then - hasAlreadyEnteredMarker = false - TriggerEvent('esx_ambulancejob:hasExitedMarker', lastZone) - end + CurrentAction = part + CurrentActionMsg = travelItem.Prompt + CurrentActionData = {to = travelItem.To.coords, heading = travelItem.To.heading} end end) +AddEventHandler('esx_ambulancejob:hasExitedMarker', function(hospital, part, partNum) + if not isInShopMenu then + ESX.UI.Menu.CloseAll() + end + + CurrentAction = nil +end) + -- Key Controls Citizen.CreateThread(function() while true do - Citizen.Wait(10) + Citizen.Wait(0) - if CurrentAction ~= nil then + if CurrentAction then ESX.ShowHelpNotification(CurrentActionMsg) - if IsControlJustReleased(0, Keys['E']) and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'ambulance' then + if IsControlJustReleased(0, Keys['E']) then - if CurrentAction == 'ambulance_actions_menu' then + if CurrentAction == 'AmbulanceActions' then OpenAmbulanceActionsMenu() - elseif CurrentAction == 'vehicle_spawner_menu' then - OpenVehicleSpawnerMenu() - elseif CurrentAction == 'pharmacy' then + elseif CurrentAction == 'Pharmacy' then OpenPharmacyMenu() - elseif CurrentAction == 'fast_travel_goto_top' or CurrentAction == 'fast_travel_goto_bottom' then - FastTravel(CurrentActionData.pos) - elseif CurrentAction == 'delete_vehicle' then - if Config.EnableSocietyOwnedVehicles then - local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle) - TriggerServerEvent('esx_society:putVehicleInGarage', 'ambulance', vehicleProps) - end + elseif CurrentAction == 'Vehicles' then + OpenVehicleSpawnerMenu(CurrentActionData.hospital, CurrentActionData.partNum) + elseif CurrentAction == 'Helicopters' then + OpenHelicopterSpawnerMenu(CurrentActionData.hospital, CurrentActionData.partNum) + elseif CurrentAction == 'VehicleDeleter' then ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + elseif CurrentAction == 'FastTravelsPrompt' then + FastTravel(CurrentActionData.to, CurrentActionData.heading) end CurrentAction = nil end - end - - if IsControlJustReleased(0, Keys['F6']) and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'ambulance' and not IsDead then - OpenMobileAmbulanceActionsMenu() + elseif ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'ambulance' and not IsDead then + if IsControlJustReleased(0, Keys['F6']) then + OpenMobileAmbulanceActionsMenu() + end + else + Citizen.Wait(500) end end end) @@ -366,12 +426,11 @@ AddEventHandler('esx_ambulancejob:putInVehicle', function() local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) - if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then - local vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + if IsAnyVehicleNearPoint(coords, 5.0) then + local vehicle = GetClosestVehicle(coords, 5.0, 0, 71) if DoesEntityExist(vehicle) then - local maxSeats = GetVehicleMaxNumberOfPassengers(vehicle) - local freeSeat = nil + local maxSeats, freeSeat = GetVehicleMaxNumberOfPassengers(vehicle) for i=maxSeats - 1, 0, -1 do if IsVehicleSeatFree(vehicle, i) then @@ -380,7 +439,7 @@ AddEventHandler('esx_ambulancejob:putInVehicle', function() end end - if freeSeat ~= nil then + if freeSeat then TaskWarpPedIntoVehicle(playerPed, vehicle, freeSeat) end end @@ -413,75 +472,349 @@ function OpenCloakroomMenu() end menu.close() - CurrentAction = 'ambulance_actions_menu' - CurrentActionMsg = _U('open_menu') - CurrentActionData = {} end, function(data, menu) menu.close() end) end -function OpenVehicleSpawnerMenu() +function OpenVehicleSpawnerMenu(hospital, partNum) ESX.UI.Menu.CloseAll() - if Config.EnableSocietyOwnedVehicles then - - local elements = {} - - ESX.TriggerServerCallback('esx_society:getVehiclesInGarage', function(vehicles) - for i=1, #vehicles, 1 do - table.insert(elements, { - label = GetDisplayNameFromVehicleModel(vehicles[i].model) .. ' [' .. vehicles[i].plate .. ']', - value = vehicles[i] - }) - end - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_spawner', - { - title = _U('veh_menu'), - align = 'top-left', - elements = elements - }, function(data, menu) - menu.close() - - local vehicleProps = data.current.value - ESX.Game.SpawnVehicle(vehicleProps.model, Config.Zones.VehicleSpawnPoint.Pos, 230.0, function(vehicle) - ESX.Game.SetVehicleProperties(vehicle, vehicleProps) - local playerPed = PlayerPedId() - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - end) - TriggerServerEvent('esx_society:removeVehicleFromGarage', 'ambulance', vehicleProps) - end, function(data, menu) - menu.close() - CurrentAction = 'vehicle_spawner_menu' - CurrentActionMsg = _U('veh_spawn') - CurrentActionData = {} - end) - end, 'ambulance') - - else -- not society vehicles - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_spawner', { - title = _U('veh_menu'), - align = 'top-left', - elements = Config.AuthorizedVehicles + title = _U('garage_title'), + align = 'top-left', + elements = Config.AuthorizedVehicles }, function(data, menu) menu.close() - ESX.Game.SpawnVehicle(data.current.model, Config.Zones.VehicleSpawnPoint.Pos, 230.0, function(vehicle) - local playerPed = PlayerPedId() - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - end) + local foundSpawn, spawnPoint = GetAvailableVehicleSpawnPoint(hospital, 'Vehicles', partNum) + + if foundSpawn then + ESX.Game.SpawnVehicle(data.current.model, spawnPoint.coords, spawnPoint.heading, function(vehicle) + local playerPed = PlayerPedId() + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) + end end, function(data, menu) menu.close() - CurrentAction = 'vehicle_spawner_menu' - CurrentActionMsg = _U('veh_spawn') - CurrentActionData = {} + end) +end + +function GetAvailableVehicleSpawnPoint(hospital, part, partNum) + local spawnPoints = Config.Hospitals[hospital][part][partNum].SpawnPoints + local found, foundSpawnPoint = false, nil + + for i=1, #spawnPoints, 1 do + if ESX.Game.IsSpawnPointClear(spawnPoints[i].coords, spawnPoints[i].radius) then + found, foundSpawnPoint = true, spawnPoints[i] + break + end + end + + if found then + return true, foundSpawnPoint + else + ESX.ShowNotification(_U('garage_blocked')) + return false + end +end + +function OpenHelicopterSpawnerMenu(hospital, partNum) + local playerCoords = GetEntityCoords(PlayerPedId()) + local elements = { + {label = _U('helicopter_garage'), action = 'garage'}, + {label = _U('helicopter_store'), action = 'store_garage'}, + {label = _U('helicopter_buy'), action = 'buy_helicopter'} + } + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'helicopter_spawner', { + title = _U('helicopter_title'), + align = 'top-left', + elements = elements + }, function(data, menu) + + if data.current.action == 'buy_helicopter' then + local shopCoords = Config.Hospitals[hospital].Helicopters[partNum].InsideShop + local shopElements = {} + + local authorizedHelicopters = Config.AuthorizedHelicopters[ESX.PlayerData.job.grade_name] + + if #authorizedHelicopters > 0 then + for k,helicopter in ipairs(authorizedHelicopters) do + table.insert(shopElements, { + label = ('%s - %s'):format(helicopter.label, _U('shop_item', ESX.Math.GroupDigits(helicopter.price))), + name = helicopter.label, + model = helicopter.model, + price = helicopter.price, + type = 'helicopter' + }) + end + else + ESX.ShowNotification(_U('helicopter_notauthorized')) + return + 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(), 'helicopter_garage', { + title = _U('helicopter_garage_title'), + align = 'top-left', + elements = garage + }, function(data2, menu2) + if data2.current.stored then + local foundSpawn, spawnPoint = GetAvailableVehicleSpawnPoint(hospital, 'Helicopters', 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, '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) + + end + + end, function(data, menu) + menu.close() + end) + +end + +function OpenShopMenu(elements, restoreCoords, shopCoords) + local playerPed = PlayerPedId() + isInShopMenu = true + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop', { + title = _U('vehicleshop_title'), + align = 'top-left', + elements = elements + }, function(data, menu) + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop_confirm', + { + title = _U('vehicleshop_confirm', data.current.name, data.current.price), + align = 'top-left', + elements = { + { label = _U('confirm_no'), value = 'no' }, + { label = _U('confirm_yes'), value = 'yes' } + } + }, function(data2, menu2) + + if data2.current.value == 'yes' then + local newPlate = exports['esx_vehicleshop']:GeneratePlate() + local vehicle = GetVehiclePedIsIn(playerPed, false) + local props = ESX.Game.GetVehicleProperties(vehicle) + props.plate = newPlate + + ESX.TriggerServerCallback('esx_ambulancejob:buyJobVehicle', function (bought) + if bought then + ESX.ShowNotification(_U('vehicleshop_bought', data.current.name, ESX.Math.GroupDigits(data.current.price))) + + isInShopMenu = false + ESX.UI.Menu.CloseAll() + + DeleteSpawnedVehicles() + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) + + ESX.Game.Teleport(playerPed, restoreCoords) + else + ESX.ShowNotification(_U('vehicleshop_money')) + menu2.close() + end + end, props) + else + menu2.close() + end + + end, function(data2, menu2) + menu2.close() end) + end, function(data, menu) + isInShopMenu = false + ESX.UI.Menu.CloseAll() + + DeleteSpawnedVehicles() + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) + + ESX.Game.Teleport(playerPed, restoreCoords) + end, function(data, menu) + DeleteSpawnedVehicles() + + WaitForVehicleToLoad(data.current.model) + ESX.Game.SpawnLocalVehicle(data.current.model, shopCoords, 0.0, function(vehicle) + table.insert(spawnedVehicles, vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + FreezeEntityPosition(vehicle, true) + end) + end) + + WaitForVehicleToLoad(elements[1].model) + ESX.Game.SpawnLocalVehicle(elements[1].model, shopCoords, 0.0, function(vehicle) + table.insert(spawnedVehicles, vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + FreezeEntityPosition(vehicle, true) + end) +end + +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + + if isInShopMenu then + DisableControlAction(0, 75, true) -- Disable exit vehicle + DisableControlAction(27, 75, true) -- Disable exit vehicle + else + Citizen.Wait(500) + end end +end) + +function DeleteSpawnedVehicles() + while #spawnedVehicles > 0 do + local vehicle = spawnedVehicles[1] + ESX.Game.DeleteVehicle(vehicle) + table.remove(spawnedVehicles, 1) + end +end + +function WaitForVehicleToLoad(modelHash) + modelHash = (type(modelHash) == 'number' and modelHash or GetHashKey(modelHash)) + + if not HasModelLoaded(modelHash) then + RequestModel(modelHash) + + while not HasModelLoaded(modelHash) do + Citizen.Wait(0) + + DisableControlAction(0, Keys['TOP'], true) + DisableControlAction(0, Keys['DOWN'], true) + DisableControlAction(0, Keys['LEFT'], true) + DisableControlAction(0, Keys['RIGHT'], true) + DisableControlAction(0, 176, true) -- ENTER key + DisableControlAction(0, Keys['BACKSPACE'], true) + + drawLoadingText(_U('vehicleshop_awaiting_model'), 255, 255, 255, 255) + end + end +end + +function drawLoadingText(text, red, green, blue, alpha) + SetTextFont(4) + SetTextProportional(0) + SetTextScale(0.0, 0.5) + SetTextColour(red, green, blue, alpha) + SetTextDropShadow(0, 0, 0, 0, 255) + SetTextEdge(1, 0, 0, 0, 255) + SetTextDropShadow() + SetTextOutline() + SetTextCentre(true) + + BeginTextCommandDisplayText("STRING") + AddTextComponentSubstringPlayerName(text) + EndTextCommandDisplayText(0.5, 0.5) end function OpenPharmacyMenu() @@ -489,8 +822,8 @@ function OpenPharmacyMenu() ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'pharmacy', { - title = _U('pharmacy_menu_title'), - align = 'top-left', + title = _U('pharmacy_menu_title'), + align = 'top-left', elements = { {label = _U('pharmacy_take', _U('medikit')), value = 'medikit'}, {label = _U('pharmacy_take', _U('bandage')), value = 'bandage'} @@ -499,25 +832,16 @@ function OpenPharmacyMenu() TriggerServerEvent('esx_ambulancejob:giveItem', data.current.value) end, function(data, menu) menu.close() - - CurrentAction = 'pharmacy' - CurrentActionMsg = _U('open_pharmacy') - CurrentActionData = {} end) end function WarpPedInClosestVehicle(ped) local coords = GetEntityCoords(ped) - local vehicle, distance = ESX.Game.GetClosestVehicle({ - x = coords.x, - y = coords.y, - z = coords.z - }) + local vehicle, distance = ESX.Game.GetClosestVehicle(coords) if distance ~= -1 and distance <= 5.0 then - local maxSeats = GetVehicleMaxNumberOfPassengers(vehicle) - local freeSeat = nil + local maxSeats, freeSeat = GetVehicleMaxNumberOfPassengers(vehicle) for i=maxSeats - 1, 0, -1 do if IsVehicleSeatFree(vehicle, i) then @@ -526,7 +850,7 @@ function WarpPedInClosestVehicle(ped) end end - if freeSeat ~= nil then + if freeSeat then TaskWarpPedIntoVehicle(ped, vehicle, freeSeat) end else @@ -548,4 +872,4 @@ AddEventHandler('esx_ambulancejob:heal', function(healType) end ESX.ShowNotification(_U('healed')) -end) \ No newline at end of file +end) diff --git a/client/main.lua b/client/main.lua index f4f4e679..623e73b4 100644 --- a/client/main.lua +++ b/client/main.lua @@ -60,6 +60,22 @@ AddEventHandler('playerSpawned', function() end end) +-- Create blips +Citizen.CreateThread(function() + for k,v in pairs(Config.Hospitals) do + local blip = AddBlipForCoord(v.Blip.coords) + + SetBlipSprite(blip, v.Blip.sprite) + SetBlipScale(blip, v.Blip.scale) + SetBlipColour(blip, v.Blip.color) + SetBlipAsShortRange(blip, true) + + BeginTextCommandSetBlipName('STRING') + AddTextComponentSubstringPlayerName(_U('hospital')) + EndTextCommandSetBlipName(blip) + end +end) + -- Disable most inputs when dead Citizen.CreateThread(function() while true do @@ -108,6 +124,14 @@ function StartDistressSignal() if IsControlPressed(0, Keys['G']) then SendDistressSignal() + + Citizen.CreateThread(function() + Citizen.Wait(1000 * 60 * 5) + if IsDead then + StartDistressSignal() + end + end) + break end end @@ -116,7 +140,7 @@ end function SendDistressSignal() local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) + local coords = GetEntityCoords(playerPed) ESX.ShowNotification(_U('distress_sent')) TriggerServerEvent('esx_phone:send', 'ambulance', _U('distress_message'), false, { @@ -273,20 +297,6 @@ function RespawnPed(ped, coords) ESX.UI.Menu.CloseAll() end -function TeleportFadeEffect(entity, coords) - Citizen.CreateThread(function() - DoScreenFadeOut(800) - - while not IsScreenFadedOut() do - Citizen.Wait(0) - end - - ESX.Game.Teleport(entity, coords, function() - DoScreenFadeIn(800) - end) - end) -end - RegisterNetEvent('esx_phone:loaded') AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) local specialContact = { @@ -305,7 +315,7 @@ end) RegisterNetEvent('esx_ambulancejob:revive') AddEventHandler('esx_ambulancejob:revive', function() local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) + local coords = GetEntityCoords(playerPed) TriggerServerEvent('esx_ambulancejob:setDeathStatus', false) Citizen.CreateThread(function() diff --git a/config.lua b/config.lua index 9b71a678..9ace4628 100644 --- a/config.lua +++ b/config.lua @@ -1,11 +1,13 @@ Config = {} Config.DrawDistance = 100.0 -Config.MarkerColor = { r = 102, g = 0, b = 102 } -Config.MarkerSize = { x = 1.5, y = 1.5, z = 1.0 } + +Config.Marker = { type = 1, x = 1.5, y = 1.5, z = 1.0, r = 102, g = 0, b = 102, rotate = false } + Config.ReviveReward = 700 -- revive reward, set to 0 if you don't want it enabled Config.AntiCombatLog = true -- enable anti-combat logging? Config.LoadIpl = true -- disable if you're using fivem-ipl or other IPL loaders + Config.Locale = 'fr' local second = 1000 @@ -21,24 +23,156 @@ Config.RemoveWeaponsAfterRPDeath = true Config.RemoveCashAfterRPDeath = true Config.RemoveItemsAfterRPDeath = true --- Let the player pay for respawning early, if he can afford it. +-- Let the player pay for respawning early, only if he can afford it. Config.EarlyRespawnFine = false Config.EarlyRespawnFineAmount = 5000 -Config.Blip = { - Pos = { x = 307.76, y = -1433.47, z = 28.97 }, - Sprite = 61, - Display = 4, - Scale = 1.2, - Colour = 2 +Config.Hospitals = { + + CentralLosSantos = { + + Blip = { + coords = vector3(307.7, -1433.4, 28.9), + sprite = 61, + scale = 1.2, + color = 2 + }, + + AmbulanceActions = { + vector3(268.4, -1363.3, 23.5) + }, + + Pharmacies = { + vector3(230.1, -1366.1, 38.5) + }, + + Vehicles = { + { + Spawner = vector3(307.7, -1433.4, 30.0), + 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 }, + { coords = vector3(294.0, -1433.1, 29.8), heading = 227.6, radius = 4.0 }, + { coords = vector3(309.4, -1442.5, 29.8), heading = 227.6, radius = 6.0 } + } + } + }, + + Helicopters = { + { + Spawner = vector3(317.5, -1449.5, 46.5), + InsideShop = vector3(305.6, -1419.7, 41.5), + Marker = { type = 34, x = 1.5, y = 1.5, z = 1.5, r = 100, g = 150, b = 150, a = 100, rotate = true }, + SpawnPoints = { + { coords = vector3(313.5, -1465.1, 46.5), heading = 142.7, radius = 10.0 }, + { coords = vector3(299.5, -1453.2, 46.5), heading = 142.7, radius = 10.0 } + } + } + }, + + VehicleDeleters = { + vector3(327.6, -1481.1, 28.8) + }, + + FastTravels = { + { + From = vector3(294.7, -1448.1, 29.0), + To = { coords = vector3(272.8, -1358.8, 23.5), heading = 0.0 }, + Marker = { type = 1, x = 2.0, y = 2.0, z = 0.5, r = 102, g = 0, b = 102, rotate = false } + }, + + { + From = vector3(275.3, -1361, 23.5), + To = { coords = vector3(295.8, -1446.5, 28.9), heading = 0.0 }, + Marker = { type = 1, x = 2.0, y = 2.0, z = 0.5, r = 102, g = 0, b = 102, rotate = false } + }, + + { + From = vector3(247.3, -1371.5, 23.5), + To = { coords = vector3(333.1, -1434.9, 45.5), heading = 138.6 }, + Marker = { type = 1, x = 1.5, y = 1.5, z = 0.5, r = 102, g = 0, b = 102, rotate = false } + }, + + { + From = vector3(335.5, -1432.0, 45.50), + To = { coords = vector3(249.1, -1369.6, 23.5), heading = 0.0 }, + Marker = { type = 1, x = 2.0, y = 2.0, z = 0.5, r = 102, g = 0, b = 102, rotate = false } + }, + + { + From = vector3(234.5, -1373.7, 20.9), + To = { coords = vector3(320.9, -1478.6, 28.8), heading = 0.0 }, + Marker = { type = 1, x = 1.5, y = 1.5, z = 1.0, r = 102, g = 0, b = 102, rotate = false } + }, + + { + From = vector3(317.9, -1476.1, 28.9), + To = { coords = vector3(238.6, -1368.4, 23.5), heading = 0.0 }, + Marker = { type = 1, x = 1.5, y = 1.5, z = 1.0, r = 102, g = 0, b = 102, rotate = false } + } + }, + + FastTravelsPrompt = { + { + From = vector3(237.4, -1373.8, 26.0), + To = { coords = vector3(251.9, -1363.3, 38.5), heading = 0.0 }, + Marker = { type = 1, x = 1.5, y = 1.5, z = 0.5, r = 102, g = 0, b = 102, rotate = false }, + Prompt = _U('fast_travel') + }, + + { + From = vector3(256.5, -1357.7, 36.0), + To = { coords = vector3(235.4, -1372.8, 26.3), heading = 0.0 }, + Marker = { type = 1, x = 1.5, y = 1.5, z = 0.5, r = 102, g = 0, b = 102, rotate = false }, + Prompt = _U('fast_travel') + } + } + + } } -Config.HelicopterSpawner = { - SpawnPoint = { x = 313.33, y = -1465.2, z = 45.5 }, - Heading = 0.0 +Config.AuthorizedHelicopters = { + + ambulance = {}, + + doctor = { + { + model = 'buzzard2', + label = 'Nagasaki Buzzard', + price = 150000 + } + }, + + chief_doctor = { + { + model = 'buzzard2', + label = 'Nagasaki Buzzard', + price = 150000 + }, + + { + model = 'seasparrow', + label = 'Sea Sparrow', + price = 300000 + } + }, + + boss = { + { + model = 'buzzard2', + label = 'Nagasaki Buzzard', + price = 100000 + }, + + { + model = 'seasparrow', + label = 'Sea Sparrow', + price = 250000 + } + } + } --- https://wiki.rage.mp/index.php?title=Vehicles Config.AuthorizedVehicles = { { @@ -47,112 +181,3 @@ Config.AuthorizedVehicles = { } } - -Config.Zones = { - - HospitalInteriorEntering1 = { -- Main entrance - Pos = { x = 294.2, y = -1448.60, z = 29.0 }, - Type = 1 - }, - - HospitalInteriorInside1 = { - Pos = { x = 272.8, y = -1358.8, z = 23.5 }, - Type = -1 - }, - - HospitalInteriorOutside1 = { - Pos = { x = 295.8, y = -1446.5, z = 28.9 }, - Type = -1 - }, - - HospitalInteriorExit1 = { - Pos = { x = 275.7, y = -1361.5, z = 23.5 }, - Type = 1 - }, - - HospitalInteriorEntering2 = { -- Lift go to the roof - Pos = { x = 247.1, y = -1371.4, z = 23.5 }, - Type = 1 - }, - - HospitalInteriorInside2 = { -- Roof outlet - Pos = { x = 333.1, y = -1434.9, z = 45.5 }, - Type = -1 - }, - - HospitalInteriorOutside2 = { -- Lift back from roof - Pos = { x = 249.1, y = -1369.6, z = 23.5 }, - Type = -1 - }, - - HospitalInteriorExit2 = { -- Roof entrance - Pos = { x = 335.5, y = -1432.0, z = 45.5 }, - Type = 1 - }, - - AmbulanceActions = { -- Cloakroom - Pos = { x = 268.4, y = -1363.330, z = 23.5 }, - Type = 1 - }, - - VehicleSpawner = { - Pos = { x = 307.76, y = -1433.47, z = 28.97 }, - Type = 1 - }, - - VehicleSpawnPoint = { - Pos = { x = 304.87, y = -1437.69, z = 28.80 }, - Type = -1 - }, - - VehicleDeleter = { - Pos = { x = 327.67, y = -1481.1, z = 28.83 }, - Type = 1 - }, - - Pharmacy = { - Pos = { x = 230.13, y = -1366.18, z = 38.53 }, - Type = 1 - }, - - ParkingDoorGoOutInside = { - Pos = { x = 234.56, y = -1373.77, z = 20.97 }, - Type = 1 - }, - - ParkingDoorGoOutOutside = { - Pos = { x = 320.98, y = -1478.62, z = 28.81 }, - Type = -1 - }, - - ParkingDoorGoInInside = { - Pos = { x = 238.64, y = -1368.48, z = 23.53 }, - Type = -1 - }, - - ParkingDoorGoInOutside = { - Pos = { x = 317.97, y = -1476.13, z = 28.97 }, - Type = 1 - }, - - StairsGoTopTop = { - Pos = { x = 251.91, y = -1363.3, z = 38.53 }, - Type = -1 - }, - - StairsGoTopBottom = { - Pos = { x = 237.45, y = -1373.89, z = 26.30 }, - Type = -1 - }, - - StairsGoBottomTop = { - Pos = { x = 256.58, y = -1357.7, z = 37.30 }, - Type = -1 - }, - - StairsGoBottomBottom = { - Pos = { x = 235.45, y = -1372.89, z = 26.30 }, - Type = -1 - } - -} diff --git a/locales/br.lua b/locales/br.lua index f505145a..8e242216 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -4,11 +4,35 @@ Locales['br'] = { ['ems_clothes_civil'] = 'Roupa Normal', ['ems_clothes_ems'] = 'Entrar como Socorrista', -- Vehicles - ['veh_menu'] = 'véhicule', - ['veh_spawn'] = 'Aperte ~INPUT_CONTEXT~ para pegar veiculo', - ['store_veh'] = 'Aperte ~INPUT_CONTEXT~ para guardar Veiculo ', - ['ambulance'] = 'Ambulancia', - ['helicopter'] = 'Helicoptero', + ['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', + ['helicopter_garage'] = 'open garage', + ['helicopter_store'] = 'store helicopter in garage', + ['helicopter_garage_title'] = 'helicopter Garage', + ['helicopter_title'] = 'helicopter Actions', + ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', + ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', + ['garage_title'] = 'vehicle Actions', + ['garage_stored'] = 'stored', + ['garage_notstored'] = 'not in garage', + ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.', + ['garage_has_stored'] = 'the vehicle has been stored in your garage', + ['garage_has_notstored'] = 'no nearby owned vehicles were found', + ['garage_notavailable'] = 'your vehicle is not stored in the garage.', + ['garage_blocked'] = 'there\'s no available spawn points!', + ['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.', + ['shop_item'] = '$%s', + ['vehicleshop_title'] = 'vehicle Shop', + ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', + ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', + ['vehicleshop_money'] = 'you cannot afford that vehicle', + ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', + ['confirm_no'] = 'no', + ['confirm_yes'] = 'yes', -- Action Menu ['hospital'] = 'Hôspital', ['revive_inprogress'] = 'Reanimação em andamento', @@ -24,7 +48,7 @@ Locales['br'] = { ['boss_actions'] = 'Menu Administração', -- Misc ['invalid_amount'] = '~r~Quantidade inválida', - ['open_menu'] = 'Aperte ~INPUT_CONTEXT~ para abrir o menu', + ['actions_prompt'] = 'press ~INPUT_CONTEXT~ access the ~y~Ambulance Actions~s~.', ['deposit_amount'] = 'Quantidade inválida para deposito', ['money_withdraw'] = 'Quantidade a ser retirada', ['fast_travel'] = 'Aperte ~INPUT_CONTEXT~ para mover-se rapidamente.', diff --git a/locales/cs.lua b/locales/cs.lua index 525538de..97830152 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -4,11 +4,35 @@ Locales['cs'] = { ['ems_clothes_civil'] = 'civilní oblečení', ['ems_clothes_ems'] = 'zdravotnické oblečení', -- Vehicles - ['veh_menu'] = 'vozidlo', - ['veh_spawn'] = 'stiskněte ~INPUT_CONTEXT~ k vyzvednutí vozidla nebo helikoptéry', - ['store_veh'] = 'stiskněte ~INPUT_CONTEXT~ k vrácení vozidla', - ['ambulance'] = 'sanitka', - ['helicopter'] = 'helikoptéra', + ['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', + ['helicopter_garage'] = 'open garage', + ['helicopter_store'] = 'store helicopter in garage', + ['helicopter_garage_title'] = 'helicopter Garage', + ['helicopter_title'] = 'helicopter Actions', + ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', + ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', + ['garage_title'] = 'vehicle Actions', + ['garage_stored'] = 'stored', + ['garage_notstored'] = 'not in garage', + ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.', + ['garage_has_stored'] = 'the vehicle has been stored in your garage', + ['garage_has_notstored'] = 'no nearby owned vehicles were found', + ['garage_notavailable'] = 'your vehicle is not stored in the garage.', + ['garage_blocked'] = 'there\'s no available spawn points!', + ['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.', + ['shop_item'] = '$%s', + ['vehicleshop_title'] = 'vehicle Shop', + ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', + ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', + ['vehicleshop_money'] = 'you cannot afford that vehicle', + ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', + ['confirm_no'] = 'no', + ['confirm_yes'] = 'yes', -- Action Menu ['hospital'] = 'nemocnice', ['revive_inprogress'] = 'probíhá oživení!', @@ -24,7 +48,7 @@ Locales['cs'] = { ['boss_actions'] = 'akce šéfa', -- Misc ['invalid_amount'] = '~r~neplatná částka', - ['open_menu'] = 'stiskněte ~INPUT_CONTEXT~ k otevření menu', + ['actions_prompt'] = 'press ~INPUT_CONTEXT~ access the ~y~Ambulance Actions~s~.', ['deposit_amount'] = 'částka vkladu', ['money_withdraw'] = 'částka výběru', ['fast_travel'] = 'stiskněte ~INPUT_CONTEXT~ k rychlému odcestování.', diff --git a/locales/en.lua b/locales/en.lua index ca1b0d39..6630b045 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -4,11 +4,35 @@ Locales['en'] = { ['ems_clothes_civil'] = 'civilian Clothes', ['ems_clothes_ems'] = 'EMS Clothes', -- Vehicles - ['veh_menu'] = 'vehicle', - ['veh_spawn'] = 'press ~INPUT_CONTEXT~ to get a Vehicle or Helicopter', ['store_veh'] = 'press ~INPUT_CONTEXT~ to store the vehicle', ['ambulance'] = 'ambulance', - ['helicopter'] = 'helicopter', + ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', + ['helicopter_buy'] = 'helicopter shop', + ['helicopter_garage'] = 'open garage', + ['helicopter_store'] = 'store helicopter in garage', + ['helicopter_garage_title'] = 'helicopter Garage', + ['helicopter_title'] = 'helicopter Actions', + ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', + ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', + ['garage_title'] = 'vehicle Actions', + ['garage_stored'] = 'stored', + ['garage_notstored'] = 'not in garage', + ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.', + ['garage_has_stored'] = 'the vehicle has been stored in your garage', + ['garage_has_notstored'] = 'no nearby owned vehicles were found', + ['garage_notavailable'] = 'your vehicle is not stored in the garage.', + ['garage_blocked'] = 'there\'s no available spawn points!', + ['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.', + ['shop_item'] = '$%s', + ['vehicleshop_title'] = 'vehicle Shop', + ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', + ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', + ['vehicleshop_money'] = 'you cannot afford that vehicle', + ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', + ['confirm_no'] = 'no', + ['confirm_yes'] = 'yes', -- Action Menu ['hospital'] = 'hospital', ['revive_inprogress'] = 'a revive is in progress!', @@ -23,8 +47,8 @@ Locales['en'] = { -- Boss Menu ['boss_actions'] = 'boss Actions', -- Misc - ['invalid_amount'] = '~r~invalid amount', - ['open_menu'] = 'press ~INPUT_CONTEXT~ to open the menu', + ['invalid_amount'] = '~r~Invalid amount', + ['actions_prompt'] = 'press ~INPUT_CONTEXT~ access the ~y~Ambulance Actions~s~.', ['deposit_amount'] = 'deposit Amount', ['money_withdraw'] = 'amount withdrawn', ['fast_travel'] = 'press ~INPUT_CONTEXT~ to fast travel.', diff --git a/locales/es.lua b/locales/es.lua index aea37cb3..d5632333 100644 --- a/locales/es.lua +++ b/locales/es.lua @@ -4,11 +4,35 @@ Locales['es'] = { ['ems_clothes_civil'] = 'Camiseta', ['ems_clothes_ems'] = 'Equipo de ambulancia', -- Vehicles - ['veh_menu'] = 'vehículo', - ['veh_spawn'] = 'Presione ~INPUT_CONTEXT~ para sacar un vehículo', - ['store_veh'] = 'Presione ~INPUT_CONTEXT~ para alamcenar un vehículo', - ['ambulance'] = 'Ambulancia', - ['helicopter'] = 'helicóptero', + ['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', + ['helicopter_garage'] = 'open garage', + ['helicopter_store'] = 'store helicopter in garage', + ['helicopter_garage_title'] = 'helicopter Garage', + ['helicopter_title'] = 'helicopter Actions', + ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', + ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', + ['garage_title'] = 'vehicle Actions', + ['garage_stored'] = 'stored', + ['garage_notstored'] = 'not in garage', + ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.', + ['garage_has_stored'] = 'the vehicle has been stored in your garage', + ['garage_has_notstored'] = 'no nearby owned vehicles were found', + ['garage_notavailable'] = 'your vehicle is not stored in the garage.', + ['garage_blocked'] = 'there\'s no available spawn points!', + ['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.', + ['shop_item'] = '$%s', + ['vehicleshop_title'] = 'vehicle Shop', + ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', + ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', + ['vehicleshop_money'] = 'you cannot afford that vehicle', + ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', + ['confirm_no'] = 'no', + ['confirm_yes'] = 'yes', -- Action Menu ['hospital'] = 'hospital', ['revive_inprogress'] = 'reanimación en curso', @@ -24,7 +48,7 @@ Locales['es'] = { ['boss_actions'] = 'boss Actions', -- Misc ['invalid_amount'] = '~r~cantidad no válida', - ['open_menu'] = 'Presione ~INPUT_CONTEXT~ para abrir el menú', + ['actions_prompt'] = 'press ~INPUT_CONTEXT~ access the ~y~Ambulance Actions~s~.', ['deposit_amount'] = 'cantidad de fianza depositada', ['money_withdraw'] = 'cantidad de fianza retirada', ['fast_travel'] = 'Press ~INPUT_CONTEXT~ to fast travel.', diff --git a/locales/fi.lua b/locales/fi.lua index c98a53af..0d0d8e21 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -4,11 +4,35 @@ Locales['fi'] = { ['ems_clothes_civil'] = 'Siviilikamppeet', ['ems_clothes_ems'] = 'Työkamppeet', -- Vehicles - ['veh_menu'] = 'ajoneuvo', - ['veh_spawn'] = 'paina ~INPUT_CONTEXT~ otaaksesi ajoneuvon', - ['store_veh'] = 'paina ~INPUT_CONTEXT~ laittaaksesi auto säilöön', - ['ambulance'] = 'ambulanssi', - ['helicopter'] = 'helikopteri', + ['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', + ['helicopter_garage'] = 'open garage', + ['helicopter_store'] = 'store helicopter in garage', + ['helicopter_garage_title'] = 'helicopter Garage', + ['helicopter_title'] = 'helicopter Actions', + ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', + ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', + ['garage_title'] = 'vehicle Actions', + ['garage_stored'] = 'stored', + ['garage_notstored'] = 'not in garage', + ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.', + ['garage_has_stored'] = 'the vehicle has been stored in your garage', + ['garage_has_notstored'] = 'no nearby owned vehicles were found', + ['garage_notavailable'] = 'your vehicle is not stored in the garage.', + ['garage_blocked'] = 'there\'s no available spawn points!', + ['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.', + ['shop_item'] = '$%s', + ['vehicleshop_title'] = 'vehicle Shop', + ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', + ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', + ['vehicleshop_money'] = 'you cannot afford that vehicle', + ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', + ['confirm_no'] = 'no', + ['confirm_yes'] = 'yes', -- Action Menu ['hospital'] = 'sairaala', ['revive_inprogress'] = 'elvytys on menossa!', @@ -24,7 +48,7 @@ Locales['fi'] = { ['boss_actions'] = 'pomovalikko', -- Misc ['invalid_amount'] = '~r~Virheellinen summa', - ['open_menu'] = 'paina ~INPUT_CONTEXT~ avataksesi menun', + ['actions_prompt'] = 'press ~INPUT_CONTEXT~ access the ~y~Ambulance Actions~s~.', ['deposit_amount'] = 'talletettava summa', ['money_withdraw'] = 'nostettava summa', ['fast_travel'] = 'paina ~INPUT_CONTEXT~ liikkuaksesi nopeasti kerrosten välillä', diff --git a/locales/fr.lua b/locales/fr.lua index c5819c6d..7e3615e6 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -4,11 +4,35 @@ Locales['fr'] = { ['ems_clothes_civil'] = 'Tenue Civil', ['ems_clothes_ems'] = 'Tenue Ambulancier', -- Vehicles - ['veh_menu'] = 'véhicule', - ['veh_spawn'] = 'appuyez sur ~INPUT_CONTEXT~ pour sortir un véhicule', - ['store_veh'] = 'appuyez sur ~INPUT_CONTEXT~ pour ranger le véhicule', + ['store_veh'] = 'press ~INPUT_CONTEXT~ to store the vehicle', ['ambulance'] = 'ambulance', - ['helicopter'] = 'hélicoptère', + ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', + ['helicopter_buy'] = 'helicopter shop', + ['helicopter_garage'] = 'open garage', + ['helicopter_store'] = 'store helicopter in garage', + ['helicopter_garage_title'] = 'helicopter Garage', + ['helicopter_title'] = 'helicopter Actions', + ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', + ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', + ['garage_title'] = 'vehicle Actions', + ['garage_stored'] = 'stored', + ['garage_notstored'] = 'not in garage', + ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.', + ['garage_has_stored'] = 'the vehicle has been stored in your garage', + ['garage_has_notstored'] = 'no nearby owned vehicles were found', + ['garage_notavailable'] = 'your vehicle is not stored in the garage.', + ['garage_blocked'] = 'there\'s no available spawn points!', + ['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.', + ['shop_item'] = '$%s', + ['vehicleshop_title'] = 'vehicle Shop', + ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', + ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', + ['vehicleshop_money'] = 'you cannot afford that vehicle', + ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', + ['confirm_no'] = 'no', + ['confirm_yes'] = 'yes', -- Action Menu ['hospital'] = 'hôpital', ['revive_inprogress'] = 'réanimation en cours', @@ -24,7 +48,7 @@ Locales['fr'] = { ['boss_actions'] = 'action Patron', -- Misc ['invalid_amount'] = '~r~montant invalide', - ['open_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour ouvrir le menu', + ['actions_prompt'] = 'press ~INPUT_CONTEXT~ access the ~y~Ambulance Actions~s~.', ['deposit_amount'] = 'montant du dépôt', ['money_withdraw'] = 'montant du retrait', ['fast_travel'] = 'appuyez sur ~INPUT_CONTEXT~ pour vous déplacer rapidement.', diff --git a/locales/pl.lua b/locales/pl.lua index cbe9d438..4e9b36ce 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -4,11 +4,35 @@ Locales['pl'] = { ['ems_clothes_civil'] = 'ubrania cywilne', ['ems_clothes_ems'] = 'ubrania EMS', -- Vehicles - ['veh_menu'] = 'pojazdy', - ['veh_spawn'] = 'naciśnij ~INPUT_CONTEXT~ żeby wziąść Pojazd lub Helikopter', - ['store_veh'] = 'naciśnij ~INPUT_CONTEXT~ żeby przechować pojazd', - ['ambulance'] = 'ambulans', - ['helicopter'] = 'helikopter', + ['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', + ['helicopter_garage'] = 'open garage', + ['helicopter_store'] = 'store helicopter in garage', + ['helicopter_garage_title'] = 'helicopter Garage', + ['helicopter_title'] = 'helicopter Actions', + ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', + ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', + ['garage_title'] = 'vehicle Actions', + ['garage_stored'] = 'stored', + ['garage_notstored'] = 'not in garage', + ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.', + ['garage_has_stored'] = 'the vehicle has been stored in your garage', + ['garage_has_notstored'] = 'no nearby owned vehicles were found', + ['garage_notavailable'] = 'your vehicle is not stored in the garage.', + ['garage_blocked'] = 'there\'s no available spawn points!', + ['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.', + ['shop_item'] = '$%s', + ['vehicleshop_title'] = 'vehicle Shop', + ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', + ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', + ['vehicleshop_money'] = 'you cannot afford that vehicle', + ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', + ['confirm_no'] = 'no', + ['confirm_yes'] = 'yes', -- Action Menu ['hospital'] = 'szpital', ['revive_inprogress'] = 'trwa wskrzeszenie', @@ -24,7 +48,7 @@ Locales['pl'] = { ['boss_actions'] = 'akcje szefa', -- Misc ['invalid_amount'] = '~r~Nieprawidłowa kwota', - ['open_menu'] = 'naciśnij ~INPUT_CONTEXT~ aby otworzyc menu', + ['actions_prompt'] = 'press ~INPUT_CONTEXT~ access the ~y~Ambulance Actions~s~.', ['deposit_amount'] = 'kwota depozytu', ['money_withdraw'] = 'wycofana kwota', ['fast_travel'] = 'naciśnij na ~INPUT_CONTEXT~ do szybkiej podróży.', diff --git a/locales/sv.lua b/locales/sv.lua index ea7abf73..851a8ccf 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -4,11 +4,35 @@ Locales['sv'] = { ['ems_clothes_civil'] = 'civilkläder', ['ems_clothes_ems'] = 'ambulanskläder', -- Vehicles - ['veh_menu'] = 'fordon', - ['veh_spawn'] = 'tryck ~INPUT_CONTEXT~ för att öppna garaget.', - ['store_veh'] = 'tryck ~INPUT_CONTEXT~ för att lagra fordonet.', - ['ambulance'] = 'ambulans', - ['helicopter'] = 'helikopter', + ['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', + ['helicopter_garage'] = 'open garage', + ['helicopter_store'] = 'store helicopter in garage', + ['helicopter_garage_title'] = 'helicopter Garage', + ['helicopter_title'] = 'helicopter Actions', + ['helicopter_notauthorized'] = 'you\'re not authorized to buy helicopters.', + ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', + ['garage_title'] = 'vehicle Actions', + ['garage_stored'] = 'stored', + ['garage_notstored'] = 'not in garage', + ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.', + ['garage_has_stored'] = 'the vehicle has been stored in your garage', + ['garage_has_notstored'] = 'no nearby owned vehicles were found', + ['garage_notavailable'] = 'your vehicle is not stored in the garage.', + ['garage_blocked'] = 'there\'s no available spawn points!', + ['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.', + ['shop_item'] = '%s SEK', + ['vehicleshop_title'] = 'vehicle Shop', + ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', + ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', + ['vehicleshop_money'] = 'you cannot afford that vehicle', + ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', + ['confirm_no'] = 'no', + ['confirm_yes'] = 'yes', -- Action Menu ['hospital'] = 'sjukhus', ['revive_inprogress'] = 'en återupplivning har börjats', @@ -24,7 +48,7 @@ Locales['sv'] = { ['boss_actions'] = 'chef meny', -- Misc ['invalid_amount'] = '~r~Ogiltig mängd', - ['open_menu'] = 'tryck ~INPUT_CONTEXT~ för att öppna menyn.', + ['actions_prompt'] = 'tryck ~INPUT_CONTEXT~ för att öppna menyn.', ['deposit_amount'] = 'mängd att sätta in', ['money_withdraw'] = 'mängd att ta ut', ['fast_travel'] = 'tryck på ~INPUT_CONTEXT~ för att snabbresa.', diff --git a/server/main.lua b/server/main.lua index e2f86711..172b61dc 100644 --- a/server/main.lua +++ b/server/main.lua @@ -110,6 +110,84 @@ ESX.RegisterServerCallback('esx_ambulancejob:getItemAmount', function(source, cb cb(quantity) end) +ESX.RegisterServerCallback('esx_ambulancejob:buyJobVehicle', function(source, cb, vehicleProps) + local xPlayer = ESX.GetPlayerFromId(source) + local price = getPriceFromHash(vehicleProps.model, xPlayer.job.grade_name, 'heli') + + -- vehicle model not found + if price == 0 then + print(('esx_ambulancejob: %s attempted to exploit the shop! (invalid vehicle model)'):format(xPlayer.identifier)) + cb(false) + end + + if xPlayer.getMoney() >= price then + xPlayer.removeMoney(price) + + MySQL.Async.execute('INSERT INTO owned_vehicles (owner, vehicle, plate, type, job, stored) VALUES (@owner, @vehicle, @plate, @type, @job, @stored)', { + ['@owner'] = xPlayer.identifier, + ['@vehicle'] = json.encode(vehicleProps), + ['@plate'] = vehicleProps.plate, + ['@type'] = 'helicopter', + ['@job'] = xPlayer.job.name, + ['@stored'] = true + }, function (rowsChanged) + cb(true) + end) + else + cb(false) + end +end) + +ESX.RegisterServerCallback('esx_ambulancejob:storeNearbyVehicle', function(source, cb, nearbyVehicles) + local xPlayer = ESX.GetPlayerFromId(source) + local foundPlate, foundNum + + for k,v in ipairs(nearbyVehicles) do + local result = MySQL.Sync.fetchAll('SELECT plate FROM owned_vehicles WHERE owner = @owner AND plate = @plate AND job = @job', { + ['@owner'] = xPlayer.identifier, + ['@plate'] = v.plate, + ['@job'] = xPlayer.job.name + }) + + if result[1] then + foundPlate, foundNum = result[1].plate, k + break + end + end + + if not foundPlate then + cb(false) + else + MySQL.Async.execute('UPDATE owned_vehicles SET stored = true WHERE owner = @owner AND plate = @plate AND job = @job', { + ['@owner'] = xPlayer.identifier, + ['@plate'] = foundPlate, + ['@job'] = xPlayer.job.name + }, function (rowsChanged) + if rowsChanged == 0 then + print(('esx_ambulancejob: %s has exploited the garage!'):format(xPlayer.identifier)) + cb(false) + else + cb(true, foundNum) + end + end) + end + +end) + +function getPriceFromHash(hashKey, jobGrade, type) + if type == 'heli' then + local vehicles = Config.AuthorizedHelicopters[jobGrade] + + for k,v in ipairs(vehicles) do + if GetHashKey(v.model) == hashKey then + return v.price + end + end + end + + return 0 +end + RegisterServerEvent('esx_ambulancejob:removeItem') AddEventHandler('esx_ambulancejob:removeItem', function(item) local _source = source