local HasAlreadyEnteredMarker, LastZone, CurrentAction, CurrentActionMsg, CurrentActionData = nil, nil, nil, '', {} local IsBusy = 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() CurrentAction = 'ambulance_actions_menu' CurrentActionMsg = _U('open_menu') CurrentActionData = {} 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 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() ESX.ShowNotification(_U('revive_inprogress')) local lib, anim = 'mini@cpr@char_a@cpr_str', 'cpr_pumpchest' for i=1, 15, 1 do Citizen.Wait(900) ESX.Streaming.RequestAnimDict(lib, function() TaskPlayAnim(PlayerPedId(), lib, anim, 8.0, -8.0, -1, 0, 0, false, false, false) end) end TriggerServerEvent('esx_ambulancejob:removeItem', 'medikit') TriggerServerEvent('esx_ambulancejob:revive', GetPlayerServerId(closestPlayer)) -- Show revive award? if Config.ReviveReward > 0 then ESX.ShowNotification(_U('revive_complete_award', GetPlayerName(closestPlayer), Config.ReviveReward)) else ESX.ShowNotification(_U('revive_complete', GetPlayerName(closestPlayer))) end else ESX.ShowNotification(_U('player_not_unconscious')) end else ESX.ShowNotification(_U('not_enough_medikit')) end IsBusy = false end, 'medikit') 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 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) end AddEventHandler('esx_ambulancejob:hasExitedMarker', function(zone) ESX.UI.Menu.CloseAll() CurrentAction = nil end) -- Create blips Citizen.CreateThread(function() local blip = AddBlipForCoord(Config.Blip.Pos.x, Config.Blip.Pos.y, Config.Blip.Pos.z) SetBlipSprite(blip, Config.Blip.Sprite) SetBlipDisplay(blip, Config.Blip.Display) SetBlipScale(blip, Config.Blip.Scale) SetBlipColour(blip, Config.Blip.Colour) SetBlipAsShortRange(blip, true) BeginTextCommandSetBlipName("STRING") AddTextComponentString(_U('hospital')) EndTextCommandSetBlipName(blip) end) -- Display markers Citizen.CreateThread(function() while true do Citizen.Wait(0) 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) end end end end end) -- Activate menu when player is inside marker Citizen.CreateThread(function() while true do Citizen.Wait(10) local coords = GetEntityCoords(PlayerPedId()) local isInMarker = false local currentZone = nil 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 end end if isInMarker and not hasAlreadyEnteredMarker then hasAlreadyEnteredMarker = true lastZone = currentZone TriggerEvent('esx_ambulancejob:hasEnteredMarker', currentZone) end if not isInMarker and hasAlreadyEnteredMarker then hasAlreadyEnteredMarker = false TriggerEvent('esx_ambulancejob:hasExitedMarker', lastZone) end end end) -- Key Controls Citizen.CreateThread(function() while true do Citizen.Wait(10) if CurrentAction ~= nil then ESX.ShowHelpNotification(CurrentActionMsg) if IsControlJustReleased(0, Keys['E']) and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'ambulance' then if CurrentAction == 'ambulance_actions_menu' then OpenAmbulanceActionsMenu() elseif CurrentAction == 'vehicle_spawner_menu' then OpenVehicleSpawnerMenu() 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 ESX.Game.DeleteVehicle(CurrentActionData.vehicle) 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() end end end) RegisterNetEvent('esx_ambulancejob:putInVehicle') 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 DoesEntityExist(vehicle) then local maxSeats = GetVehicleMaxNumberOfPassengers(vehicle) local freeSeat = nil for i=maxSeats - 1, 0, -1 do if IsVehicleSeatFree(vehicle, i) then freeSeat = i break end end if freeSeat ~= nil 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) 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 end) end menu.close() CurrentAction = 'ambulance_actions_menu' CurrentActionMsg = _U('open_menu') CurrentActionData = {} end, function(data, menu) menu.close() end) end function OpenVehicleSpawnerMenu() 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 }, 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) end, function(data, menu) menu.close() CurrentAction = 'vehicle_spawner_menu' CurrentActionMsg = _U('veh_spawn') CurrentActionData = {} end) 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')), value = 'medikit'}, {label = _U('pharmacy_take', _U('bandage')), value = 'bandage'} } }, function(data, menu) 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 }) if distance ~= -1 and distance <= 5.0 then local maxSeats = GetVehicleMaxNumberOfPassengers(vehicle) local freeSeat = nil for i=maxSeats - 1, 0, -1 do if IsVehicleSeatFree(vehicle, i) then freeSeat = i break end end if freeSeat ~= nil then TaskWarpPedIntoVehicle(ped, vehicle, freeSeat) end else ESX.ShowNotification(_U('no_vehicles')) end end RegisterNetEvent('esx_ambulancejob:heal') AddEventHandler('esx_ambulancejob:heal', function(healType) 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 ESX.ShowNotification(_U('healed')) end)