Files
esx_core/client/main.lua
T

395 lines
12 KiB
Lua

local firstSpawn, PlayerLoaded = true, false
isDead, isSearched, medic = false, false, 0
ESX = nil
Citizen.CreateThread(function()
while ESX == nil do
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
Citizen.Wait(0)
end
while ESX.GetPlayerData().job == nil do
Citizen.Wait(100)
end
PlayerLoaded = true
ESX.PlayerData = ESX.GetPlayerData()
end)
RegisterNetEvent('esx:playerLoaded')
AddEventHandler('esx:playerLoaded', function(xPlayer)
ESX.PlayerData = xPlayer
PlayerLoaded = true
end)
RegisterNetEvent('esx:setJob')
AddEventHandler('esx:setJob', function(job)
ESX.PlayerData.job = job
end)
AddEventHandler('playerSpawned', function()
isDead = false
TriggerServerEvent('esx_ambulancejob:onPlayerSpawn')
if firstSpawn then
exports.spawnmanager:setAutoSpawn(false) -- disable respawn
firstSpawn = false
ESX.TriggerServerCallback('esx_ambulancejob:getDeathStatus', function(shouldDie)
if shouldDie and Config.AntiCombatLog then
while not PlayerLoaded do
Citizen.Wait(1000)
end
ESX.ShowNotification(_U('combatlog_message'))
RemoveItemsAfterRPDeath()
end
end)
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('blip_hospital'))
EndTextCommandSetBlipName(blip)
end
end)
-- Disable most inputs when dead
Citizen.CreateThread(function()
while true do
Citizen.Wait(0)
if isDead then
DisableAllControlActions(0)
EnableControlAction(0, 47, true)
EnableControlAction(0, 245, true)
EnableControlAction(0, 38, true)
else
Citizen.Wait(500)
end
end
end)
Citizen.CreateThread(function()
while true do
Citizen.Wait(0)
if isDead and isSearched then
local playerPed = PlayerPedId()
local ped = GetPlayerPed(GetPlayerFromServerId(medic))
isSearched = false
AttachEntityToEntity(playerPed, ped, 11816, 0.54, 0.54, 0.0, 0.0, 0.0, 0.0, false, false, false, false, 2, true)
Citizen.Wait(1000)
DetachEntity(playerPed, true, false)
ClearPedTasksImmediately(playerPed)
end
end
end)
RegisterNetEvent('esx_ambulancejob:clsearch')
AddEventHandler('esx_ambulancejob:clsearch', function(medicId)
local playerPed = PlayerPedId()
if isDead then
local coords = GetEntityCoords(playerPed)
local playersInArea = ESX.Game.GetPlayersInArea(coords, 50.0)
for i=1, #playersInArea, 1 do
local player = playersInArea[i]
if player == GetPlayerFromServerId(medicId) then
medic = tonumber(medicId)
isSearched = true
break
end
end
end
end)
function OnPlayerDeath()
isDead = true
ESX.UI.Menu.CloseAll()
TriggerServerEvent('esx_ambulancejob:setDeathStatus', true)
StartDeathTimer()
StartDistressSignal()
StartScreenEffect('DeathFailOut', 0, false)
end
RegisterNetEvent('esx_ambulancejob:useItem')
AddEventHandler('esx_ambulancejob:useItem', function(itemName)
ESX.UI.Menu.CloseAll()
if itemName == 'medikit' then
local lib, anim = 'anim@heists@narcotics@funding@gang_idle', 'gang_chatting_idle01' -- TODO better animations
local playerPed = PlayerPedId()
ESX.Streaming.RequestAnimDict(lib, function()
TaskPlayAnim(playerPed, lib, anim, 8.0, -8.0, -1, 0, 0, false, false, false)
Citizen.Wait(500)
while IsEntityPlayingAnim(playerPed, lib, anim, 3) do
Citizen.Wait(0)
DisableAllControlActions(0)
end
TriggerEvent('esx_ambulancejob:heal', 'big', true)
ESX.ShowNotification(_U('used_medikit'))
end)
elseif itemName == 'bandage' then
local lib, anim = 'anim@heists@narcotics@funding@gang_idle', 'gang_chatting_idle01' -- TODO better animations
local playerPed = PlayerPedId()
ESX.Streaming.RequestAnimDict(lib, function()
TaskPlayAnim(playerPed, lib, anim, 8.0, -8.0, -1, 0, 0, false, false, false)
Citizen.Wait(500)
while IsEntityPlayingAnim(playerPed, lib, anim, 3) do
Citizen.Wait(0)
DisableAllControlActions(0)
end
TriggerEvent('esx_ambulancejob:heal', 'small', true)
ESX.ShowNotification(_U('used_bandage'))
end)
end
end)
function StartDistressSignal()
Citizen.CreateThread(function()
local timer = Config.BleedoutTimer
while timer > 0 and isDead do
Citizen.Wait(0)
timer = timer - 30
SetTextFont(4)
SetTextScale(0.45, 0.45)
SetTextColour(185, 185, 185, 255)
SetTextDropshadow(0, 0, 0, 0, 255)
SetTextDropShadow()
SetTextOutline()
BeginTextCommandDisplayText('STRING')
AddTextComponentSubstringPlayerName(_U('distress_send'))
EndTextCommandDisplayText(0.175, 0.805)
if IsControlJustReleased(0, 47) then
SendDistressSignal()
break
end
end
end)
end
function SendDistressSignal()
local playerPed = PlayerPedId()
local coords = GetEntityCoords(playerPed)
ESX.ShowNotification(_U('distress_sent'))
TriggerServerEvent('esx_ambulancejob:onPlayerDistress')
end
function DrawGenericTextThisFrame()
SetTextFont(4)
SetTextScale(0.0, 0.5)
SetTextColour(255, 255, 255, 255)
SetTextDropshadow(0, 0, 0, 0, 255)
SetTextDropShadow()
SetTextOutline()
SetTextCentre(true)
end
function secondsToClock(seconds)
local seconds, hours, mins, secs = tonumber(seconds), 0, 0, 0
if seconds <= 0 then
return 0, 0
else
local hours = string.format('%02.f', math.floor(seconds / 3600))
local mins = string.format('%02.f', math.floor(seconds / 60 - (hours * 60)))
local secs = string.format('%02.f', math.floor(seconds - hours * 3600 - mins * 60))
return mins, secs
end
end
function StartDeathTimer()
local canPayFine = false
if Config.EarlyRespawnFine then
ESX.TriggerServerCallback('esx_ambulancejob:checkBalance', function(canPay)
canPayFine = canPay
end)
end
local earlySpawnTimer = ESX.Math.Round(Config.EarlyRespawnTimer / 1000)
local bleedoutTimer = ESX.Math.Round(Config.BleedoutTimer / 1000)
Citizen.CreateThread(function()
-- early respawn timer
while earlySpawnTimer > 0 and isDead do
Citizen.Wait(1000)
if earlySpawnTimer > 0 then
earlySpawnTimer = earlySpawnTimer - 1
end
end
-- bleedout timer
while bleedoutTimer > 0 and isDead do
Citizen.Wait(1000)
if bleedoutTimer > 0 then
bleedoutTimer = bleedoutTimer - 1
end
end
end)
Citizen.CreateThread(function()
local text, timeHeld
-- early respawn timer
while earlySpawnTimer > 0 and isDead do
Citizen.Wait(0)
text = _U('respawn_available_in', secondsToClock(earlySpawnTimer))
DrawGenericTextThisFrame()
SetTextEntry('STRING')
AddTextComponentString(text)
DrawText(0.5, 0.8)
end
-- bleedout timer
while bleedoutTimer > 0 and isDead do
Citizen.Wait(0)
text = _U('respawn_bleedout_in', secondsToClock(bleedoutTimer))
if not Config.EarlyRespawnFine then
text = text .. _U('respawn_bleedout_prompt')
if IsControlPressed(0, 38) and timeHeld > 60 then
RemoveItemsAfterRPDeath()
break
end
elseif Config.EarlyRespawnFine and canPayFine then
text = text .. _U('respawn_bleedout_fine', ESX.Math.GroupDigits(Config.EarlyRespawnFineAmount))
if IsControlPressed(0, 38) and timeHeld > 60 then
TriggerServerEvent('esx_ambulancejob:payFine')
RemoveItemsAfterRPDeath()
break
end
end
if IsControlPressed(0, 38) then
timeHeld = timeHeld + 1
else
timeHeld = 0
end
DrawGenericTextThisFrame()
SetTextEntry('STRING')
AddTextComponentString(text)
DrawText(0.5, 0.8)
end
if bleedoutTimer < 1 and isDead then
RemoveItemsAfterRPDeath()
end
end)
end
function RemoveItemsAfterRPDeath()
TriggerServerEvent('esx_ambulancejob:setDeathStatus', false)
Citizen.CreateThread(function()
DoScreenFadeOut(800)
while not IsScreenFadedOut() do
Citizen.Wait(10)
end
ESX.TriggerServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function()
local formattedCoords = {
x = Config.RespawnPoint.coords.x,
y = Config.RespawnPoint.coords.y,
z = Config.RespawnPoint.coords.z
}
ESX.SetPlayerData('loadout', {})
RespawnPed(PlayerPedId(), formattedCoords, Config.RespawnPoint.heading)
StopScreenEffect('DeathFailOut')
DoScreenFadeIn(800)
end)
end)
end
function RespawnPed(ped, coords, heading)
SetEntityCoordsNoOffset(ped, coords.x, coords.y, coords.z, false, false, false, true)
NetworkResurrectLocalPlayer(coords.x, coords.y, coords.z, heading, true, false)
SetPlayerInvincible(ped, false)
TriggerEvent('playerSpawned', coords.x, coords.y, coords.z)
ClearPedBloodDamage(ped)
ESX.UI.Menu.CloseAll()
end
RegisterNetEvent('esx_phone:loaded')
AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts)
local specialContact = {
name = 'Ambulance',
number = 'ambulance',
base64Icon = 'data:image/png;base64,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'
}
TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon)
end)
AddEventHandler('esx:onPlayerDeath', function(data)
OnPlayerDeath()
end)
RegisterNetEvent('esx_ambulancejob:revive')
AddEventHandler('esx_ambulancejob:revive', function()
local playerPed = PlayerPedId()
local coords = GetEntityCoords(playerPed)
TriggerServerEvent('esx_ambulancejob:setDeathStatus', false)
DoScreenFadeOut(800)
while not IsScreenFadedOut() do
Citizen.Wait(50)
end
local formattedCoords = {
x = ESX.Math.Round(coords.x, 1),
y = ESX.Math.Round(coords.y, 1),
z = ESX.Math.Round(coords.z, 1)
}
RespawnPed(playerPed, formattedCoords, 0.0)
StopScreenEffect('DeathFailOut')
DoScreenFadeIn(800)
end)
-- Load unloaded IPLs
if Config.LoadIpl then
RequestIpl('Coroner_Int_on') -- Morgue
end