Advertisement
Abracadoum

ambujob

Apr 8th, 2019
261
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 34.11 KB | None | 0 0
  1. local CurrentAction, CurrentActionMsg, CurrentActionData = nil, '', {}
  2. local HasAlreadyEnteredMarker, LastHospital, LastPart, LastPartNum
  3. local IsBusy = false
  4. local spawnedVehicles, isInShopMenu = {}, false
  5.  
  6. function OpenAmbulanceActionsMenu()
  7. local elements = {
  8. {label = _U('cloakroom'), value = 'cloakroom'}
  9. }
  10.  
  11. if Config.EnablePlayerManagement and ESX.PlayerData.job.grade_name == 'boss' then
  12. table.insert(elements, {label = _U('boss_actions'), value = 'boss_actions'})
  13. end
  14.  
  15. ESX.UI.Menu.CloseAll()
  16.  
  17. ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'ambulance_actions',
  18. {
  19. title = _U('ambulance'),
  20. align = 'top-left',
  21. elements = elements
  22. }, function(data, menu)
  23. if data.current.value == 'cloakroom' then
  24. OpenCloakroomMenu()
  25. elseif data.current.value == 'boss_actions' then
  26. TriggerEvent('esx_society:openBossMenu', 'ambulance', function(data, menu)
  27. menu.close()
  28. end, {wash = false})
  29. end
  30. end, function(data, menu)
  31. menu.close()
  32. end)
  33. end
  34.  
  35. function OpenMobileAmbulanceActionsMenu()
  36.  
  37. ESX.UI.Menu.CloseAll()
  38.  
  39. ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'mobile_ambulance_actions',
  40. {
  41. title = _U('ambulance'),
  42. align = 'top-left',
  43. elements = {
  44. {label = _U('ems_menu'), value = 'citizen_interaction'},
  45. {label = _U('object_spawner'), value = 'object_spawner'},
  46. {label = _U('billing'), value = 'billing' }
  47. }
  48. }, function(data, menu)
  49.  
  50. if data.current.value == 'billing' then
  51.  
  52. ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'billing', {
  53. title = _U('invoice_amount')
  54. }, function(data, menu)
  55.  
  56. local amount = tonumber(data.value)
  57. if amount == nil then
  58. ESX.ShowNotification(_U('amount_invalid'))
  59. else
  60. menu.close()
  61. local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer()
  62. if closestPlayer == -1 or closestDistance > 3.0 then
  63. ESX.ShowNotification(_U('no_players_near'))
  64. else
  65. TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_ambulance', 'Ambulance', amount)
  66. ESX.ShowNotification(_U('billing_sent'))
  67. end
  68.  
  69. end
  70.  
  71. end, function(data, menu)
  72. menu.close()
  73. end)
  74.  
  75. elseif data.current.value == 'object_spawner' then
  76. ESX.UI.Menu.Open(
  77. 'default', GetCurrentResourceName(), 'citizen_interaction',
  78. {
  79. title = _U('traffic_interaction'),
  80. align = 'top-left',
  81. elements = {
  82. {label = _U('cone'), value = 'prop_roadcone02a'},
  83. {label = _U('barrier'), value = 'prop_barrier_work05'}
  84. }
  85. }, function(data2, menu2)
  86. local model = data2.current.value
  87. local playerPed = PlayerPedId()
  88. local coords = GetEntityCoords(playerPed)
  89. local forward = GetEntityForwardVector(playerPed)
  90. local x, y, z = table.unpack(coords + forward * 1.0)
  91.  
  92. if model == 'prop_roadcone02a' then
  93. z = z - 2.0
  94. end
  95.  
  96. ESX.Game.SpawnObject(model, {
  97. x = x,
  98. y = y,
  99. z = z
  100. }, function(obj)
  101. SetEntityHeading(obj, GetEntityHeading(playerPed))
  102. PlaceObjectOnGroundProperly(obj)
  103. end)
  104.  
  105. end, function(data2, menu2)
  106. menu2.close()
  107. end)
  108. --end
  109.  
  110. elseif data.current.value == 'citizen_interaction' then
  111. ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction',
  112. {
  113. title = _U('ems_menu_title'),
  114. align = 'top-left',
  115. elements = {
  116. {label = _U('ems_menu_revive'), value = 'revive'},
  117. {label = _U('ems_menu_small'), value = 'small'},
  118. {label = _U('ems_menu_big'), value = 'big'},
  119. {label = _U('ems_menu_putincar'), value = 'put_in_vehicle'}
  120. }
  121. }, function(data, menu)
  122. if IsBusy then return end
  123.  
  124. local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer()
  125.  
  126. if closestPlayer == -1 or closestDistance > 1.0 then
  127. ESX.ShowNotification(_U('no_players'))
  128. else
  129.  
  130. if data.current.value == 'revive' then
  131.  
  132. IsBusy = true
  133.  
  134. ESX.TriggerServerCallback('esx_ambulancejob:getItemAmount', function(quantity)
  135. if quantity > 0 then
  136. local closestPlayerPed = GetPlayerPed(closestPlayer)
  137.  
  138. if IsPedDeadOrDying(closestPlayerPed, 1) then
  139. local playerPed = PlayerPedId()
  140.  
  141. ESX.ShowNotification(_U('revive_inprogress'))
  142.  
  143. local lib, anim = 'mini@cpr@char_a@cpr_str', 'cpr_pumpchest'
  144.  
  145. for i=1, 15, 1 do
  146. Citizen.Wait(900)
  147.  
  148. ESX.Streaming.RequestAnimDict(lib, function()
  149. TaskPlayAnim(PlayerPedId(), lib, anim, 8.0, -8.0, -1, 0, 0, false, false, false)
  150. end)
  151. end
  152.  
  153. TriggerServerEvent('esx_ambulancejob:removeItem', 'medikit')
  154. TriggerServerEvent('esx_ambulancejob:revive', GetPlayerServerId(closestPlayer))
  155.  
  156. -- Show revive award?
  157. if Config.ReviveReward > 0 then
  158. ESX.ShowNotification(_U('revive_complete_award', GetPlayerName(closestPlayer), Config.ReviveReward))
  159. else
  160. ESX.ShowNotification(_U('revive_complete', GetPlayerName(closestPlayer)))
  161. end
  162. else
  163. ESX.ShowNotification(_U('player_not_unconscious'))
  164. end
  165. else
  166. ESX.ShowNotification(_U('not_enough_medikit'))
  167. end
  168.  
  169. IsBusy = false
  170.  
  171. end, 'medikit')
  172.  
  173. elseif data.current.value == 'small' then
  174.  
  175. ESX.TriggerServerCallback('esx_ambulancejob:getItemAmount', function(quantity)
  176. if quantity > 0 then
  177. local closestPlayerPed = GetPlayerPed(closestPlayer)
  178. local health = GetEntityHealth(closestPlayerPed)
  179.  
  180. if health > 0 then
  181. local playerPed = PlayerPedId()
  182.  
  183. IsBusy = true
  184. ESX.ShowNotification(_U('heal_inprogress'))
  185. TaskStartScenarioInPlace(playerPed, 'CODE_HUMAN_MEDIC_TEND_TO_DEAD', 0, true)
  186. Citizen.Wait(10000)
  187. ClearPedTasks(playerPed)
  188.  
  189. TriggerServerEvent('esx_ambulancejob:removeItem', 'bandage')
  190. TriggerServerEvent('esx_ambulancejob:heal', GetPlayerServerId(closestPlayer), 'small')
  191. ESX.ShowNotification(_U('heal_complete', GetPlayerName(closestPlayer)))
  192. IsBusy = false
  193. else
  194. ESX.ShowNotification(_U('player_not_conscious'))
  195. end
  196. else
  197. ESX.ShowNotification(_U('not_enough_bandage'))
  198. end
  199. end, 'bandage')
  200.  
  201. elseif data.current.value == 'big' then
  202.  
  203. ESX.TriggerServerCallback('esx_ambulancejob:getItemAmount', function(quantity)
  204. if quantity > 0 then
  205. local closestPlayerPed = GetPlayerPed(closestPlayer)
  206. local health = GetEntityHealth(closestPlayerPed)
  207.  
  208. if health > 0 then
  209. local playerPed = PlayerPedId()
  210.  
  211. IsBusy = true
  212. ESX.ShowNotification(_U('heal_inprogress'))
  213. TaskStartScenarioInPlace(playerPed, 'CODE_HUMAN_MEDIC_TEND_TO_DEAD', 0, true)
  214. Citizen.Wait(10000)
  215. ClearPedTasks(playerPed)
  216. TriggerServerEvent('esx_ambulancejob:removeItem', 'medikit')
  217. TriggerServerEvent('esx_ambulancejob:heal', GetPlayerServerId(closestPlayer), 'big')
  218. ESX.ShowNotification(_U('heal_complete', GetPlayerName(closestPlayer)))
  219. IsBusy = false
  220. else
  221. ESX.ShowNotification(_U('player_not_conscious'))
  222. end
  223. else
  224. ESX.ShowNotification(_U('not_enough_medikit'))
  225. end
  226. end, 'medikit')
  227.  
  228. elseif data.current.value == 'put_in_vehicle' then
  229. TriggerServerEvent('esx_ambulancejob:putInVehicle', GetPlayerServerId(closestPlayer))
  230. end
  231.  
  232. end
  233. end, function(data, menu)
  234. menu.close()
  235. end)
  236. end
  237.  
  238. end, function(data, menu)
  239. menu.close()
  240. end)
  241. end
  242. --------------------------------------------------------------------------------------------------------------------------------------------------------
  243. AddEventHandler('esx_ambulancejob:hasEnteredEntityZone', function(entity)
  244. local playerPed = PlayerPedId()
  245.  
  246. if ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'ambulance' and IsPedOnFoot(playerPed) then
  247. CurrentAction = 'remove_entity'
  248. CurrentActionMsg = _U('remove_prop')
  249. CurrentActionData = {entity = entity}
  250. end
  251.  
  252. if GetEntityModel(entity) == GetHashKey('p_ld_stinger_s') then
  253. local playerPed = PlayerPedId()
  254. local coords = GetEntityCoords(playerPed)
  255.  
  256. if IsPedInAnyVehicle(playerPed, false) then
  257. local vehicle = GetVehiclePedIsIn(playerPed)
  258.  
  259. for i=0, 7, 1 do
  260. SetVehicleTyreBurst(vehicle, i, true, 1000)
  261. end
  262. end
  263. end
  264. end)
  265.  
  266. AddEventHandler('esx_ambulancejob:hasExitedEntityZone', function(entity)
  267. if CurrentAction == 'remove_entity' then
  268. CurrentAction = nil
  269. end
  270. end)
  271.  
  272. -- Enter / Exit entity zone events
  273. Citizen.CreateThread(function()
  274. local trackedEntities = {
  275. 'prop_roadcone02a',
  276. 'prop_barrier_work05'
  277. }
  278.  
  279. while true do
  280. Citizen.Wait(500)
  281.  
  282. local playerPed = PlayerPedId()
  283. local coords = GetEntityCoords(playerPed)
  284.  
  285. local closestDistance = -1
  286. local closestEntity = nil
  287.  
  288. for i=1, #trackedEntities, 1 do
  289. local object = GetClosestObjectOfType(coords, 3.0, GetHashKey(trackedEntities[i]), false, false, false)
  290.  
  291. if DoesEntityExist(object) then
  292. local objCoords = GetEntityCoords(object)
  293. local distance = GetDistanceBetweenCoords(coords, objCoords, true)
  294.  
  295. if closestDistance == -1 or closestDistance > distance then
  296. closestDistance = distance
  297. closestEntity = object
  298. end
  299. end
  300. end
  301.  
  302. if closestDistance ~= -1 and closestDistance <= 3.0 then
  303. if LastEntity ~= closestEntity then
  304. TriggerEvent('esx_ambulancejob:hasEnteredEntityZone', closestEntity)
  305. LastEntity = closestEntity
  306. end
  307. else
  308. if LastEntity ~= nil then
  309. TriggerEvent('esx_ambulancejob:hasExitedEntityZone', LastEntity)
  310. LastEntity = nil
  311. end
  312. end
  313. end
  314. end)
  315. -----------------------------------------------------------------------------------------------------------------------------------------
  316.  
  317. function FastTravel(coords, heading)
  318. TeleportFadeEffect(PlayerPedId(), coords, heading)
  319. end
  320.  
  321. function TeleportFadeEffect(entity, coords, heading)
  322. Citizen.CreateThread(function()
  323. DoScreenFadeOut(800)
  324.  
  325. while not IsScreenFadedOut() do
  326. Citizen.Wait(10)
  327. end
  328.  
  329. ESX.Game.Teleport(entity, coords, function()
  330. DoScreenFadeIn(800)
  331.  
  332. if heading then
  333. SetEntityHeading(entity, heading)
  334. end
  335. end)
  336. end)
  337. end
  338.  
  339. -- Draw markers & Marker logic
  340. Citizen.CreateThread(function()
  341. while true do
  342. Citizen.Wait(10)
  343. local playerCoords = GetEntityCoords(PlayerPedId())
  344. local canSleep, isInMarker, hasExited = true, false, false
  345. local currentHospital, currentPart, currentPartNum
  346.  
  347. for hospitalNum,hospital in pairs(Config.Hospitals) do
  348.  
  349. -- Ambulance Actions
  350. for k,v in ipairs(hospital.AmbulanceActions) do
  351. local distance = GetDistanceBetweenCoords(playerCoords, v, true)
  352.  
  353. if distance < Config.DrawDistance then
  354. 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)
  355. canSleep = false
  356. end
  357.  
  358. if distance < Config.Marker.x then
  359. isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'AmbulanceActions', k
  360. end
  361. end
  362.  
  363. -- Pharmacies
  364. for k,v in ipairs(hospital.Pharmacies) do
  365. local distance = GetDistanceBetweenCoords(playerCoords, v, true)
  366.  
  367. if distance < Config.DrawDistance then
  368. 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)
  369. canSleep = false
  370. end
  371.  
  372. if distance < Config.Marker.x then
  373. isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'Pharmacy', k
  374. end
  375. end
  376.  
  377. -- Vehicle Spawners
  378. for k,v in ipairs(hospital.Vehicles) do
  379. local distance = GetDistanceBetweenCoords(playerCoords, v.Spawner, true)
  380.  
  381. if distance < Config.DrawDistance then
  382. 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)
  383. canSleep = false
  384. end
  385.  
  386. if distance < v.Marker.x then
  387. isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'Vehicles', k
  388. end
  389. end
  390.  
  391. -- Helicopter Spawners
  392. for k,v in ipairs(hospital.Helicopters) do
  393. local distance = GetDistanceBetweenCoords(playerCoords, v.Spawner, true)
  394.  
  395. if distance < Config.DrawDistance then
  396. 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)
  397. canSleep = false
  398. end
  399.  
  400. if distance < v.Marker.x then
  401. isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'Helicopters', k
  402. end
  403. end
  404.  
  405. -- Fast Travels
  406. for k,v in ipairs(hospital.FastTravels) do
  407. local distance = GetDistanceBetweenCoords(playerCoords, v.From, true)
  408.  
  409. if distance < Config.DrawDistance then
  410. 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)
  411. canSleep = false
  412. end
  413.  
  414.  
  415. if distance < v.Marker.x then
  416. FastTravel(v.To.coords, v.To.heading)
  417. end
  418. end
  419.  
  420. -- Fast Travels (Prompt)
  421. for k,v in ipairs(hospital.FastTravelsPrompt) do
  422. local distance = GetDistanceBetweenCoords(playerCoords, v.From, true)
  423.  
  424. if distance < Config.DrawDistance then
  425. 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)
  426. canSleep = false
  427. end
  428.  
  429. if distance < v.Marker.x then
  430. isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, 'FastTravelsPrompt', k
  431. end
  432. end
  433.  
  434. -- Logic for exiting & entering markers
  435. if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastHospital ~= currentHospital or LastPart ~= currentPart or LastPartNum ~= currentPartNum)) then
  436.  
  437. if
  438. (LastHospital ~= nil and LastPart ~= nil and LastPartNum ~= nil) and
  439. (LastHospital ~= currentHospital or LastPart ~= currentPart or LastPartNum ~= currentPartNum)
  440. then
  441. TriggerEvent('esx_ambulancejob:hasExitedMarker', LastHospital, LastPart, LastPartNum)
  442. hasExited = true
  443. end
  444.  
  445. HasAlreadyEnteredMarker, LastHospital, LastPart, LastPartNum = true, currentHospital, currentPart, currentPartNum
  446.  
  447. TriggerEvent('esx_ambulancejob:hasEnteredMarker', currentHospital, currentPart, currentPartNum)
  448.  
  449. end
  450.  
  451. if not hasExited and not isInMarker and HasAlreadyEnteredMarker then
  452. HasAlreadyEnteredMarker = false
  453. TriggerEvent('esx_ambulancejob:hasExitedMarker', LastHospital, LastPart, LastPartNum)
  454. end
  455.  
  456. end
  457. end
  458. end)
  459.  
  460. AddEventHandler('esx_ambulancejob:hasEnteredMarker', function(hospital, part, partNum)
  461. if ESX.PlayerData.job and ESX.PlayerData.job.name == 'ambulance' then
  462. if part == 'AmbulanceActions' then
  463. CurrentAction = part
  464. CurrentActionMsg = _U('actions_prompt')
  465. CurrentActionData = {}
  466. elseif part == 'Pharmacy' then
  467. CurrentAction = part
  468. CurrentActionMsg = _U('open_pharmacy')
  469. CurrentActionData = {}
  470. elseif part == 'Vehicles' then
  471. CurrentAction = part
  472. CurrentActionMsg = _U('garage_prompt')
  473. CurrentActionData = {hospital = hospital, partNum = partNum}
  474. elseif part == 'Helicopters' then
  475. CurrentAction = part
  476. CurrentActionMsg = _U('helicopter_prompt')
  477. CurrentActionData = {hospital = hospital, partNum = partNum}
  478. elseif part == 'FastTravelsPrompt' then
  479. local travelItem = Config.Hospitals[hospital][part][partNum]
  480.  
  481. CurrentAction = part
  482. CurrentActionMsg = travelItem.Prompt
  483. CurrentActionData = {to = travelItem.To.coords, heading = travelItem.To.heading}
  484. end
  485. end
  486. end)
  487.  
  488. AddEventHandler('esx_ambulancejob:hasExitedMarker', function(hospital, part, partNum)
  489. if not isInShopMenu then
  490. ESX.UI.Menu.CloseAll()
  491. end
  492.  
  493. CurrentAction = nil
  494. end)
  495.  
  496. -- Key Controls
  497. Citizen.CreateThread(function()
  498. while true do
  499. Citizen.Wait(0)
  500.  
  501. if CurrentAction then
  502. ESX.ShowHelpNotification(CurrentActionMsg)
  503.  
  504. if IsControlJustReleased(0, Keys['E']) then
  505.  
  506. if CurrentAction == 'AmbulanceActions' then
  507. OpenAmbulanceActionsMenu()
  508. elseif CurrentAction == 'remove_entity' then
  509. DeleteEntity(CurrentActionData.entity)
  510. elseif CurrentAction == 'Pharmacy' then
  511. OpenPharmacyMenu()
  512. elseif CurrentAction == 'Vehicles' then
  513. OpenVehicleSpawnerMenu(CurrentActionData.hospital, CurrentActionData.partNum)
  514. elseif CurrentAction == 'Helicopters' then
  515. OpenHelicopterSpawnerMenu(CurrentActionData.hospital, CurrentActionData.partNum)
  516. elseif CurrentAction == 'FastTravelsPrompt' then
  517. FastTravel(CurrentActionData.to, CurrentActionData.heading)
  518. end
  519.  
  520. CurrentAction = nil
  521.  
  522. end
  523.  
  524. elseif ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'ambulance' and not IsDead then
  525. if IsControlJustReleased(0, Keys['F6']) then
  526. OpenMobileAmbulanceActionsMenu()
  527. end
  528. else
  529. Citizen.Wait(500)
  530. end
  531. end
  532. end)
  533.  
  534. RegisterNetEvent('esx_ambulancejob:putInVehicle')
  535. AddEventHandler('esx_ambulancejob:putInVehicle', function()
  536. local playerPed = PlayerPedId()
  537. local coords = GetEntityCoords(playerPed)
  538.  
  539. if IsAnyVehicleNearPoint(coords, 5.0) then
  540. local vehicle = GetClosestVehicle(coords, 5.0, 0, 71)
  541.  
  542. if DoesEntityExist(vehicle) then
  543. local maxSeats, freeSeat = GetVehicleMaxNumberOfPassengers(vehicle)
  544.  
  545. for i=maxSeats - 1, 0, -1 do
  546. if IsVehicleSeatFree(vehicle, i) then
  547. freeSeat = i
  548. break
  549. end
  550. end
  551.  
  552. if freeSeat then
  553. TaskWarpPedIntoVehicle(playerPed, vehicle, freeSeat)
  554. end
  555. end
  556. end
  557. end)
  558.  
  559. function OpenCloakroomMenu()
  560. ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'cloakroom',
  561. {
  562. title = _U('cloakroom'),
  563. align = 'top-left',
  564. elements = {
  565. {label = _U('ems_clothes_civil'), value = 'citizen_wear'},
  566. {label = _U('ems_clothes_ems'), value = 'ambulance_wear'},
  567. {label = 'Tenue perso', value = 'open_skin'},
  568. }
  569. }, function(data, menu)
  570. if data.current.value == 'citizen_wear' then
  571. ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin)
  572. TriggerEvent('skinchanger:loadSkin', skin)
  573. end)
  574. elseif data.current.value == 'ambulance_wear' then
  575. ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin)
  576. if skin.sex == 0 then
  577. TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_male)
  578. else
  579. TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_female)
  580. end
  581. end)
  582. elseif data.current.value == 'open_skin' then
  583. ESX.TriggerServerCallback('esx_property:getPlayerDressing', function(dressing)
  584. local elements3 = {}
  585.  
  586. for i=1, #dressing, 1 do
  587. table.insert(elements3, {
  588. label = dressing[i],
  589. value = i
  590. })
  591. end
  592.  
  593. ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'menuperso_skin',
  594. {
  595. title = 'Habits',
  596. align = 'top-left',
  597. elements = elements3
  598. },
  599. function(data3, menu3)
  600. TriggerEvent('skinchanger:getSkin', function(skin)
  601. ESX.TriggerServerCallback('esx_property:getPlayerOutfit', function(clothes)
  602. TriggerEvent('skinchanger:loadClothes', skin, clothes)
  603. TriggerEvent('esx_skin:setLastSkin', skin)
  604.  
  605. TriggerEvent('skinchanger:getSkin', function(skin)
  606. TriggerServerEvent('esx_skin:save', skin)
  607. end)
  608. end, data3.current.value)
  609. end)
  610.  
  611. end,
  612. function(data3, menu3)
  613. menu3.close()
  614. end)
  615. end)
  616. end
  617.  
  618. menu.close()
  619. end, function(data, menu)
  620. menu.close()
  621. end)
  622. end
  623.  
  624. function OpenVehicleSpawnerMenu(hospital, partNum)
  625. local playerCoords = GetEntityCoords(PlayerPedId())
  626. local elements = {
  627. {label = _U('garage_storeditem'), action = 'garage'},
  628. {label = _U('garage_storeitem'), action = 'store_garage'},
  629. {label = _U('garage_buyitem'), action = 'buy_vehicle'}
  630. }
  631.  
  632. ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle', {
  633. title = _U('garage_title'),
  634. align = 'top-left',
  635. elements = elements
  636. }, function(data, menu)
  637.  
  638. if data.current.action == 'buy_vehicle' then
  639. local shopCoords = Config.Hospitals[hospital].Vehicles[partNum].InsideShop
  640. local shopElements = {}
  641.  
  642. local authorizedVehicles = Config.AuthorizedVehicles[ESX.PlayerData.job.grade_name]
  643.  
  644. if #authorizedVehicles > 0 then
  645. for k,vehicle in ipairs(authorizedVehicles) do
  646. table.insert(shopElements, {
  647. label = ('%s - <span style="color:green;">%s</span>'):format(vehicle.label, _U('shop_item', ESX.Math.GroupDigits(vehicle.price))),
  648. name = vehicle.label,
  649. model = vehicle.model,
  650. price = vehicle.price,
  651. type = 'car'
  652. })
  653. end
  654. else
  655. return
  656. end
  657.  
  658. OpenShopMenu(shopElements, playerCoords, shopCoords)
  659. elseif data.current.action == 'garage' then
  660. local garage = {}
  661.  
  662. ESX.TriggerServerCallback('esx_vehicleshop:retrieveJobVehicles', function(jobVehicles)
  663. if #jobVehicles > 0 then
  664. for k,v in ipairs(jobVehicles) do
  665. local props = json.decode(v.vehicle)
  666. local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(props.model))
  667. local label = ('%s - <span style="color:darkgoldenrod;">%s</span>: '):format(vehicleName, props.plate)
  668.  
  669. if v.stored then
  670. label = label .. ('<span style="color:green;">%s</span>'):format(_U('garage_stored'))
  671. else
  672. label = label .. ('<span style="color:darkred;">%s</span>'):format(_U('garage_notstored'))
  673. end
  674.  
  675. table.insert(garage, {
  676. label = label,
  677. stored = v.stored,
  678. model = props.model,
  679. vehicleProps = props
  680. })
  681. end
  682.  
  683. ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_garage', {
  684. title = _U('garage_title'),
  685. align = 'top-left',
  686. elements = garage
  687. }, function(data2, menu2)
  688. if data2.current.stored then
  689. local foundSpawn, spawnPoint = GetAvailableVehicleSpawnPoint(hospital, 'Vehicles', partNum)
  690.  
  691. if foundSpawn then
  692. menu2.close()
  693.  
  694. ESX.Game.SpawnVehicle(data2.current.model, spawnPoint.coords, spawnPoint.heading, function(vehicle)
  695. ESX.Game.SetVehicleProperties(vehicle, data2.current.vehicleProps)
  696.  
  697. TriggerServerEvent('esx_vehicleshop:setJobVehicleState', data2.current.vehicleProps.plate, false)
  698. ESX.ShowNotification(_U('garage_released'))
  699. end)
  700. end
  701. else
  702. ESX.ShowNotification(_U('garage_notavailable'))
  703. end
  704. end, function(data2, menu2)
  705. menu2.close()
  706. end)
  707.  
  708. else
  709. ESX.ShowNotification(_U('garage_empty'))
  710. end
  711. end, 'car')
  712.  
  713. elseif data.current.action == 'store_garage' then
  714. StoreNearbyVehicle(playerCoords)
  715. end
  716.  
  717. end, function(data, menu)
  718. menu.close()
  719. end)
  720.  
  721. end
  722.  
  723. function StoreNearbyVehicle(playerCoords)
  724. local vehicles, vehiclePlates = ESX.Game.GetVehiclesInArea(playerCoords, 30.0), {}
  725.  
  726. if #vehicles > 0 then
  727. for k,v in ipairs(vehicles) do
  728.  
  729. -- Make sure the vehicle we're saving is empty, or else it wont be deleted
  730. if GetVehicleNumberOfPassengers(v) == 0 and IsVehicleSeatFree(v, -1) then
  731. table.insert(vehiclePlates, {
  732. vehicle = v,
  733. plate = ESX.Math.Trim(GetVehicleNumberPlateText(v))
  734. })
  735. end
  736. end
  737. else
  738. ESX.ShowNotification(_U('garage_store_nearby'))
  739. return
  740. end
  741.  
  742. ESX.TriggerServerCallback('esx_ambulancejob:storeNearbyVehicle', function(storeSuccess, foundNum)
  743. if storeSuccess then
  744. local vehicleId = vehiclePlates[foundNum]
  745. local attempts = 0
  746. ESX.Game.DeleteVehicle(vehicleId.vehicle)
  747. IsBusy = true
  748.  
  749. Citizen.CreateThread(function()
  750. while IsBusy do
  751. Citizen.Wait(0)
  752. drawLoadingText(_U('garage_storing'), 255, 255, 255, 255)
  753. end
  754. end)
  755.  
  756. -- Workaround for vehicle not deleting when other players are near it.
  757. while DoesEntityExist(vehicleId.vehicle) do
  758. Citizen.Wait(500)
  759. attempts = attempts + 1
  760.  
  761. -- Give up
  762. if attempts > 30 then
  763. break
  764. end
  765.  
  766. vehicles = ESX.Game.GetVehiclesInArea(playerCoords, 30.0)
  767. if #vehicles > 0 then
  768. for k,v in ipairs(vehicles) do
  769. if ESX.Math.Trim(GetVehicleNumberPlateText(v)) == vehicleId.plate then
  770. ESX.Game.DeleteVehicle(v)
  771. break
  772. end
  773. end
  774. end
  775. end
  776.  
  777. IsBusy = false
  778. ESX.ShowNotification(_U('garage_has_stored'))
  779. else
  780. ESX.ShowNotification(_U('garage_has_notstored'))
  781. end
  782. end, vehiclePlates)
  783. end
  784.  
  785. function GetAvailableVehicleSpawnPoint(hospital, part, partNum)
  786. local spawnPoints = Config.Hospitals[hospital][part][partNum].SpawnPoints
  787. local found, foundSpawnPoint = false, nil
  788.  
  789. for i=1, #spawnPoints, 1 do
  790. if ESX.Game.IsSpawnPointClear(spawnPoints[i].coords, spawnPoints[i].radius) then
  791. found, foundSpawnPoint = true, spawnPoints[i]
  792. break
  793. end
  794. end
  795.  
  796. if found then
  797. return true, foundSpawnPoint
  798. else
  799. ESX.ShowNotification(_U('garage_blocked'))
  800. return false
  801. end
  802. end
  803.  
  804. function OpenHelicopterSpawnerMenu(hospital, partNum)
  805. local playerCoords = GetEntityCoords(PlayerPedId())
  806. ESX.PlayerData = ESX.GetPlayerData()
  807. local elements = {
  808. {label = _U('helicopter_garage'), action = 'garage'},
  809. {label = _U('helicopter_store'), action = 'store_garage'},
  810. {label = _U('helicopter_buy'), action = 'buy_helicopter'}
  811. }
  812.  
  813. ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'helicopter_spawner', {
  814. title = _U('helicopter_title'),
  815. align = 'top-left',
  816. elements = elements
  817. }, function(data, menu)
  818.  
  819. if data.current.action == 'buy_helicopter' then
  820. local shopCoords = Config.Hospitals[hospital].Helicopters[partNum].InsideShop
  821. local shopElements = {}
  822.  
  823. local authorizedHelicopters = Config.AuthorizedHelicopters[ESX.PlayerData.job.grade_name]
  824.  
  825. if #authorizedHelicopters > 0 then
  826. for k,helicopter in ipairs(authorizedHelicopters) do
  827. table.insert(shopElements, {
  828. label = ('%s - <span style="color:green;">%s</span>'):format(helicopter.label, _U('shop_item', ESX.Math.GroupDigits(helicopter.price))),
  829. name = helicopter.label,
  830. model = helicopter.model,
  831. price = helicopter.price,
  832. type = 'helicopter'
  833. })
  834. end
  835. else
  836. ESX.ShowNotification(_U('helicopter_notauthorized'))
  837. return
  838. end
  839.  
  840. OpenShopMenu(shopElements, playerCoords, shopCoords)
  841. elseif data.current.action == 'garage' then
  842. local garage = {}
  843.  
  844. ESX.TriggerServerCallback('esx_vehicleshop:retrieveJobVehicles', function(jobVehicles)
  845. if #jobVehicles > 0 then
  846. for k,v in ipairs(jobVehicles) do
  847. local props = json.decode(v.vehicle)
  848. local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(props.model))
  849. local label = ('%s - <span style="color:darkgoldenrod;">%s</span>: '):format(vehicleName, props.plate)
  850.  
  851. if v.stored then
  852. label = label .. ('<span style="color:green;">%s</span>'):format(_U('garage_stored'))
  853. else
  854. label = label .. ('<span style="color:darkred;">%s</span>'):format(_U('garage_notstored'))
  855. end
  856.  
  857. table.insert(garage, {
  858. label = label,
  859. stored = v.stored,
  860. model = props.model,
  861. vehicleProps = props
  862. })
  863. end
  864.  
  865. ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'helicopter_garage', {
  866. title = _U('helicopter_garage_title'),
  867. align = 'top-left',
  868. elements = garage
  869. }, function(data2, menu2)
  870. if data2.current.stored then
  871. local foundSpawn, spawnPoint = GetAvailableVehicleSpawnPoint(hospital, 'Helicopters', partNum)
  872.  
  873. if foundSpawn then
  874. menu2.close()
  875.  
  876. ESX.Game.SpawnVehicle(data2.current.model, spawnPoint.coords, spawnPoint.heading, function(vehicle)
  877. ESX.Game.SetVehicleProperties(vehicle, data2.current.vehicleProps)
  878.  
  879. TriggerServerEvent('esx_vehicleshop:setJobVehicleState', data2.current.vehicleProps.plate, false)
  880. ESX.ShowNotification(_U('garage_released'))
  881. end)
  882. end
  883. else
  884. ESX.ShowNotification(_U('garage_notavailable'))
  885. end
  886. end, function(data2, menu2)
  887. menu2.close()
  888. end)
  889.  
  890. else
  891. ESX.ShowNotification(_U('garage_empty'))
  892. end
  893. end, 'helicopter')
  894.  
  895. elseif data.current.action == 'store_garage' then
  896. StoreNearbyVehicle(playerCoords)
  897. end
  898.  
  899. end, function(data, menu)
  900. menu.close()
  901. end)
  902.  
  903. end
  904.  
  905. function OpenShopMenu(elements, restoreCoords, shopCoords)
  906. local playerPed = PlayerPedId()
  907. isInShopMenu = true
  908.  
  909. ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop', {
  910. title = _U('vehicleshop_title'),
  911. align = 'top-left',
  912. elements = elements
  913. }, function(data, menu)
  914.  
  915. ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop_confirm',
  916. {
  917. title = _U('vehicleshop_confirm', data.current.name, data.current.price),
  918. align = 'top-left',
  919. elements = {
  920. { label = _U('confirm_no'), value = 'no' },
  921. { label = _U('confirm_yes'), value = 'yes' }
  922. }
  923. }, function(data2, menu2)
  924.  
  925. if data2.current.value == 'yes' then
  926. local newPlate = exports['esx_vehicleshop']:GeneratePlate()
  927. local vehicle = GetVehiclePedIsIn(playerPed, false)
  928. local props = ESX.Game.GetVehicleProperties(vehicle)
  929. props.plate = newPlate
  930.  
  931. ESX.TriggerServerCallback('esx_ambulancejob:buyJobVehicle', function (bought)
  932. if bought then
  933. ESX.ShowNotification(_U('vehicleshop_bought', data.current.name, ESX.Math.GroupDigits(data.current.price)))
  934.  
  935. isInShopMenu = false
  936. ESX.UI.Menu.CloseAll()
  937.  
  938. DeleteSpawnedVehicles()
  939. FreezeEntityPosition(playerPed, false)
  940. SetEntityVisible(playerPed, true)
  941.  
  942. ESX.Game.Teleport(playerPed, restoreCoords)
  943. else
  944. ESX.ShowNotification(_U('vehicleshop_money'))
  945. menu2.close()
  946. end
  947. end, props, data.current.type)
  948. else
  949. menu2.close()
  950. end
  951.  
  952. end, function(data2, menu2)
  953. menu2.close()
  954. end)
  955.  
  956. end, function(data, menu)
  957. isInShopMenu = false
  958. ESX.UI.Menu.CloseAll()
  959.  
  960. DeleteSpawnedVehicles()
  961. FreezeEntityPosition(playerPed, false)
  962. SetEntityVisible(playerPed, true)
  963.  
  964. ESX.Game.Teleport(playerPed, restoreCoords)
  965. end, function(data, menu)
  966. DeleteSpawnedVehicles()
  967.  
  968. WaitForVehicleToLoad(data.current.model)
  969. ESX.Game.SpawnLocalVehicle(data.current.model, shopCoords, 0.0, function(vehicle)
  970. table.insert(spawnedVehicles, vehicle)
  971. TaskWarpPedIntoVehicle(playerPed, vehicle, -1)
  972. FreezeEntityPosition(vehicle, true)
  973. end)
  974. end)
  975.  
  976. WaitForVehicleToLoad(elements[1].model)
  977. ESX.Game.SpawnLocalVehicle(elements[1].model, shopCoords, 0.0, function(vehicle)
  978. table.insert(spawnedVehicles, vehicle)
  979. TaskWarpPedIntoVehicle(playerPed, vehicle, -1)
  980. FreezeEntityPosition(vehicle, true)
  981. end)
  982. end
  983.  
  984. Citizen.CreateThread(function()
  985. while true do
  986. Citizen.Wait(0)
  987.  
  988. if isInShopMenu then
  989. DisableControlAction(0, 75, true) -- Disable exit vehicle
  990. DisableControlAction(27, 75, true) -- Disable exit vehicle
  991. else
  992. Citizen.Wait(500)
  993. end
  994. end
  995. end)
  996.  
  997. function DeleteSpawnedVehicles()
  998. while #spawnedVehicles > 0 do
  999. local vehicle = spawnedVehicles[1]
  1000. ESX.Game.DeleteVehicle(vehicle)
  1001. table.remove(spawnedVehicles, 1)
  1002. end
  1003. end
  1004.  
  1005. function WaitForVehicleToLoad(modelHash)
  1006. modelHash = (type(modelHash) == 'number' and modelHash or GetHashKey(modelHash))
  1007.  
  1008. if not HasModelLoaded(modelHash) then
  1009. RequestModel(modelHash)
  1010.  
  1011. while not HasModelLoaded(modelHash) do
  1012. Citizen.Wait(0)
  1013.  
  1014. DisableControlAction(0, Keys['TOP'], true)
  1015. DisableControlAction(0, Keys['DOWN'], true)
  1016. DisableControlAction(0, Keys['LEFT'], true)
  1017. DisableControlAction(0, Keys['RIGHT'], true)
  1018. DisableControlAction(0, 176, true) -- ENTER key
  1019. DisableControlAction(0, Keys['BACKSPACE'], true)
  1020.  
  1021. drawLoadingText(_U('vehicleshop_awaiting_model'), 255, 255, 255, 255)
  1022. end
  1023. end
  1024. end
  1025.  
  1026. function drawLoadingText(text, red, green, blue, alpha)
  1027. SetTextFont(4)
  1028. SetTextProportional(0)
  1029. SetTextScale(0.0, 0.5)
  1030. SetTextColour(red, green, blue, alpha)
  1031. SetTextDropShadow(0, 0, 0, 0, 255)
  1032. SetTextEdge(1, 0, 0, 0, 255)
  1033. SetTextDropShadow()
  1034. SetTextOutline()
  1035. SetTextCentre(true)
  1036.  
  1037. BeginTextCommandDisplayText("STRING")
  1038. AddTextComponentSubstringPlayerName(text)
  1039. EndTextCommandDisplayText(0.5, 0.5)
  1040. end
  1041.  
  1042. function OpenPharmacyMenu()
  1043. ESX.UI.Menu.CloseAll()
  1044.  
  1045. ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'pharmacy',
  1046. {
  1047. title = _U('pharmacy_menu_title'),
  1048. align = 'top-left',
  1049. elements = {
  1050. {label = _U('pharmacy_take', _U('medikit')), value = 'medikit'},
  1051. {label = _U('pharmacy_take', _U('bandage')), value = 'bandage'}
  1052. }
  1053. }, function(data, menu)
  1054. TriggerServerEvent('esx_ambulancejob:giveItem', data.current.value)
  1055. end, function(data, menu)
  1056. menu.close()
  1057. end)
  1058. end
  1059.  
  1060. function WarpPedInClosestVehicle(ped)
  1061. local coords = GetEntityCoords(ped)
  1062.  
  1063. local vehicle, distance = ESX.Game.GetClosestVehicle(coords)
  1064.  
  1065. if distance ~= -1 and distance <= 5.0 then
  1066. local maxSeats, freeSeat = GetVehicleMaxNumberOfPassengers(vehicle)
  1067.  
  1068. for i=maxSeats - 1, 0, -1 do
  1069. if IsVehicleSeatFree(vehicle, i) then
  1070. freeSeat = i
  1071. break
  1072. end
  1073. end
  1074.  
  1075. if freeSeat then
  1076. TaskWarpPedIntoVehicle(ped, vehicle, freeSeat)
  1077. end
  1078. else
  1079. ESX.ShowNotification(_U('no_vehicles'))
  1080. end
  1081. end
  1082.  
  1083. RegisterNetEvent('esx_ambulancejob:heal')
  1084. AddEventHandler('esx_ambulancejob:heal', function(healType)
  1085. local playerPed = PlayerPedId()
  1086. local maxHealth = GetEntityMaxHealth(playerPed)
  1087.  
  1088. if healType == 'small' then
  1089. local health = GetEntityHealth(playerPed)
  1090. local newHealth = math.min(maxHealth, math.floor(health + maxHealth / 8))
  1091. SetEntityHealth(playerPed, newHealth)
  1092. elseif healType == 'big' then
  1093. SetEntityHealth(playerPed, maxHealth)
  1094. end
  1095.  
  1096. ESX.ShowNotification(_U('healed'))
  1097. end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement