local CurrentAction, CurrentActionMsg, CurrentActionData = nil, '', {} local HasAlreadyEnteredMarker, LastHospital, LastPart, LastPartNum local isBusy, deadPlayers, deadPlayerBlips, isOnDuty = false, {}, {}, false local spawnedVehicles, isInShopMenu = {}, false function OpenAmbulanceActionsMenu() local elements = { {label = _U('cloakroom'), value = 'cloakroom'} } if Config.EnablePlayerManagement and ESX.PlayerData.job.grade_name == 'boss' then table.insert(elements, {label = _U('boss_actions'), value = 'boss_actions'}) end ESX.UI.Menu.CloseAll() ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'ambulance_actions', { title = _U('ambulance'), align = 'top-left', elements = elements }, function(data, menu) if data.current.value == 'cloakroom' then OpenCloakroomMenu() elseif data.current.value == 'boss_actions' then TriggerEvent('esx_society:openBossMenu', 'ambulance', function(data, menu) menu.close() end, {wash = false}) end end, function(data, menu) menu.close() end) end function OpenMobileAmbulanceActionsMenu() ESX.UI.Menu.CloseAll() ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'mobile_ambulance_actions', { title = _U('ambulance'), align = 'top-left', elements = { {label = _U('ems_menu'), value = 'citizen_interaction'} }}, function(data, menu) if data.current.value == 'citizen_interaction' then ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', { title = _U('ems_menu_title'), align = 'top-left', elements = { {label = _U('ems_menu_revive'), value = 'revive'}, {label = _U('ems_menu_small'), value = 'small'}, {label = _U('ems_menu_big'), value = 'big'}, {label = _U('ems_menu_putincar'), value = 'put_in_vehicle'} }}, function(data, menu) if isBusy then return end local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() if closestPlayer == -1 or closestDistance > 1.0 then ESX.ShowNotification(_U('no_players')) else if data.current.value == 'revive' then revivePlayer(closestPlayer) elseif data.current.value == 'small' then ESX.TriggerServerCallback('esx_ambulancejob:getItemAmount', function(quantity) if quantity > 0 then local closestPlayerPed = GetPlayerPed(closestPlayer) local health = GetEntityHealth(closestPlayerPed) if health > 0 then local playerPed = PlayerPedId() isBusy = true ESX.ShowNotification(_U('heal_inprogress')) TaskStartScenarioInPlace(playerPed, 'CODE_HUMAN_MEDIC_TEND_TO_DEAD', 0, true) Citizen.Wait(10000) ClearPedTasks(playerPed) TriggerServerEvent('esx_ambulancejob:removeItem', 'bandage') TriggerServerEvent('esx_ambulancejob:heal', GetPlayerServerId(closestPlayer), 'small') ESX.ShowNotification(_U('heal_complete', GetPlayerName(closestPlayer))) isBusy = false else ESX.ShowNotification(_U('player_not_conscious')) end else ESX.ShowNotification(_U('not_enough_bandage')) end end, 'bandage') elseif data.current.value == 'big' then ESX.TriggerServerCallback('esx_ambulancejob:getItemAmount', function(quantity) if quantity > 0 then local closestPlayerPed = GetPlayerPed(closestPlayer) local health = GetEntityHealth(closestPlayerPed) if health > 0 then local playerPed = PlayerPedId() isBusy = true ESX.ShowNotification(_U('heal_inprogress')) TaskStartScenarioInPlace(playerPed, 'CODE_HUMAN_MEDIC_TEND_TO_DEAD', 0, true) Citizen.Wait(10000) ClearPedTasks(playerPed) TriggerServerEvent('esx_ambulancejob:removeItem', 'medikit') TriggerServerEvent('esx_ambulancejob:heal', GetPlayerServerId(closestPlayer), 'big') ESX.ShowNotification(_U('heal_complete', GetPlayerName(closestPlayer))) isBusy = false else ESX.ShowNotification(_U('player_not_conscious')) end else ESX.ShowNotification(_U('not_enough_medikit')) end end, 'medikit') elseif data.current.value == 'put_in_vehicle' then TriggerServerEvent('esx_ambulancejob:putInVehicle', GetPlayerServerId(closestPlayer)) end end end, function(data, menu) menu.close() end) end end, function(data, menu) menu.close() end) end function revivePlayer(closestPlayer) isBusy = true ESX.TriggerServerCallback('esx_ambulancejob:getItemAmount', function(quantity) if quantity > 0 then local closestPlayerPed = GetPlayerPed(closestPlayer) if IsPedDeadOrDying(closestPlayerPed, 1) then local playerPed = PlayerPedId() local lib, anim = 'mini@cpr@char_a@cpr_str', 'cpr_pumpchest' ESX.ShowNotification(_U('revive_inprogress')) for i=1, 15 do Citizen.Wait(900) ESX.Streaming.RequestAnimDict(lib, function() TaskPlayAnim(playerPed, lib, anim, 8.0, -8.0, -1, 0, 0.0, false, false, false) end) end TriggerServerEvent('esx_ambulancejob:removeItem', 'medikit') TriggerServerEvent('esx_ambulancejob:revive', GetPlayerServerId(closestPlayer)) else ESX.ShowNotification(_U('player_not_unconscious')) end else ESX.ShowNotification(_U('not_enough_medikit')) end isBusy = false end, 'medikit') end function FastTravel(coords, heading) local playerPed = PlayerPedId() DoScreenFadeOut(800) while not IsScreenFadedOut() do Citizen.Wait(500) end ESX.Game.Teleport(playerPed, coords, function() DoScreenFadeIn(800) if heading then SetEntityHeading(playerPed, heading) end end) end -- Draw markers & Marker logic Citizen.CreateThread(function() while true do Citizen.Wait(0) local playerCoords = GetEntityCoords(PlayerPedId()) local letSleep, isInMarker, hasExited = true, false, false local currentHospital, currentPart, currentPartNum for hospitalNum,hospital in pairs(Config.Hospitals) do -- Ambulance Actions for k,v in ipairs(hospital.AmbulanceActions) do local distance = #(playerCoords - v) 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) letSleep = 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 = #(playerCoords - v) 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) letSleep = 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 = #(playerCoords - v.Spawner) 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) letSleep = 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 = #(playerCoords - v.Spawner) 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) letSleep = false end if distance < v.Marker.x then isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'Helicopters', k end end -- Fast Travels for k,v in ipairs(hospital.FastTravels) do local distance = #(playerCoords - v.From) 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) letSleep = 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 = #(playerCoords - v.From) 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) letSleep = false end if distance < v.Marker.x then isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'FastTravelsPrompt', k end 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 if letSleep then Citizen.Wait(500) end end end) AddEventHandler('esx_ambulancejob:hasEnteredMarker', function(hospital, part, partNum) if ESX.PlayerData.job and ESX.PlayerData.job.name == 'ambulance' then 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 == 'FastTravelsPrompt' then local travelItem = Config.Hospitals[hospital][part][partNum] CurrentAction = part CurrentActionMsg = travelItem.Prompt CurrentActionData = {to = travelItem.To.coords, heading = travelItem.To.heading} end 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(0) if CurrentAction then ESX.ShowHelpNotification(CurrentActionMsg) if IsControlJustReleased(0, 38) then if CurrentAction == 'AmbulanceActions' then OpenAmbulanceActionsMenu() elseif CurrentAction == 'Pharmacy' then OpenPharmacyMenu() elseif CurrentAction == 'Vehicles' then OpenVehicleSpawnerMenu(CurrentActionData.hospital, CurrentActionData.partNum) elseif CurrentAction == 'Helicopters' then OpenHelicopterSpawnerMenu(CurrentActionData.hospital, CurrentActionData.partNum) elseif CurrentAction == 'FastTravelsPrompt' then FastTravel(CurrentActionData.to, CurrentActionData.heading) end CurrentAction = nil end elseif ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'ambulance' and not isDead then if IsControlJustReleased(0, 167) then OpenMobileAmbulanceActionsMenu() end else Citizen.Wait(500) end end end) RegisterNetEvent('esx_ambulancejob:putInVehicle') AddEventHandler('esx_ambulancejob:putInVehicle', function() local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) if IsAnyVehicleNearPoint(coords, 5.0) then local vehicle = GetClosestVehicle(coords, 5.0, 0, 71) if DoesEntityExist(vehicle) then local maxSeats, freeSeat = GetVehicleMaxNumberOfPassengers(vehicle) for i=maxSeats - 1, 0, -1 do if IsVehicleSeatFree(vehicle, i) then freeSeat = i break end end if freeSeat then TaskWarpPedIntoVehicle(playerPed, vehicle, freeSeat) end end end end) function OpenCloakroomMenu() ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'cloakroom', { title = _U('cloakroom'), align = 'top-left', elements = { {label = _U('ems_clothes_civil'), value = 'citizen_wear'}, {label = _U('ems_clothes_ems'), value = 'ambulance_wear'}, }}, function(data, menu) if data.current.value == 'citizen_wear' then ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) TriggerEvent('skinchanger:loadSkin', skin) isOnDuty = false for playerId,v in pairs(deadPlayerBlips) do RemoveBlip(v) deadPlayerBlips[playerId] = nil end end) elseif data.current.value == 'ambulance_wear' then ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) if skin.sex == 0 then TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_male) else TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_female) end isOnDuty = true end) end menu.close() end, function(data, menu) menu.close() end) 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.Open('default', GetCurrentResourceName(), 'vehicle', { title = _U('garage_title'), align = 'top-left', elements = elements }, function(data, menu) if data.current.action == 'buy_vehicle' then local shopCoords = Config.Hospitals[hospital].Vehicles[partNum].InsideShop local shopElements = {} local authorizedVehicles = Config.AuthorizedVehicles[ESX.PlayerData.job.grade_name] 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 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) 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()) ESX.PlayerData = ESX.GetPlayerData() 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 StoreNearbyVehicle(playerCoords) 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, data.current.type) 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) SetModelAsNoLongerNeeded(data.current.model) 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) SetModelAsNoLongerNeeded(elements[1].model) 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) BeginTextCommandBusyspinnerOn('STRING') AddTextComponentSubstringPlayerName(_U('vehicleshop_awaiting_model')) EndTextCommandBusyspinnerOn(4) while not HasModelLoaded(modelHash) do Citizen.Wait(0) DisableAllControlActions(0) end BusyspinnerOff() end end function OpenPharmacyMenu() ESX.UI.Menu.CloseAll() ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'pharmacy', { title = _U('pharmacy_menu_title'), align = 'top-left', elements = { {label = _U('pharmacy_take', _U('medikit')), item = 'medikit', type = 'slider', value = 1, min = 1, max = 100}, {label = _U('pharmacy_take', _U('bandage')), item = 'bandage', type = 'slider', value = 1, min = 1, max = 100} } }, function(data, menu) TriggerServerEvent('esx_ambulancejob:giveItem', data.current.item, data.current.value) end, function(data, menu) menu.close() end) end function WarpPedInClosestVehicle(ped) local coords = GetEntityCoords(ped) local vehicle, distance = ESX.Game.GetClosestVehicle(coords) if distance ~= -1 and distance <= 5.0 then local maxSeats, freeSeat = GetVehicleMaxNumberOfPassengers(vehicle) for i=maxSeats - 1, 0, -1 do if IsVehicleSeatFree(vehicle, i) then freeSeat = i break end end if freeSeat then TaskWarpPedIntoVehicle(ped, vehicle, freeSeat) end else ESX.ShowNotification(_U('no_vehicles')) end end RegisterNetEvent('esx_ambulancejob:heal') AddEventHandler('esx_ambulancejob:heal', function(healType, quiet) local playerPed = PlayerPedId() local maxHealth = GetEntityMaxHealth(playerPed) if healType == 'small' then local health = GetEntityHealth(playerPed) local newHealth = math.min(maxHealth, math.floor(health + maxHealth / 8)) SetEntityHealth(playerPed, newHealth) elseif healType == 'big' then SetEntityHealth(playerPed, maxHealth) end if not quiet then ESX.ShowNotification(_U('healed')) end end) RegisterNetEvent('esx_ambulancejob:setDeadPlayers') AddEventHandler('esx_ambulancejob:setDeadPlayers', function(_deadPlayers) deadPlayers = _deadPlayers if isOnDuty then for playerId,v in pairs(deadPlayerBlips) do RemoveBlip(v) deadPlayerBlips[playerId] = nil end for playerId,status in pairs(deadPlayers) do if status == 'distress' then local player = GetPlayerFromServerId(playerId) local playerPed = GetPlayerPed(player) local blip = AddBlipForEntity(playerPed) SetBlipSprite(blip, 303) SetBlipColour(blip, 1) SetBlipFlashes(blip, true) SetBlipCategory(blip, 7) BeginTextCommandSetBlipName('STRING') AddTextComponentSubstringPlayerName(_U('blip_dead')) EndTextCommandSetBlipName(blip) deadPlayerBlips[playerId] = blip end end end end)