mirror of
https://github.com/esx-framework/esx_core.git
synced 2026-08-30 17:58:54 +00:00
27b9b8e9ac
By changing the main.lua i have made it so that if a player is to combat log and then join back, this will kill them and reset the timer so that they cannot force respawn
361 lines
11 KiB
Lua
361 lines
11 KiB
Lua
local firstSpawn, PlayerLoaded = true, false
|
|
|
|
isDead = false
|
|
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('esx:onPlayerSpawn', function()
|
|
isDead = false
|
|
|
|
if firstSpawn then
|
|
firstSpawn = false
|
|
|
|
if Config.AntiCombatLog then
|
|
while not PlayerLoaded do
|
|
Citizen.Wait(5000)
|
|
end
|
|
|
|
ESX.TriggerServerCallback('esx_ambulancejob:getDeathStatus', function(shouldDie)
|
|
if shouldDie then
|
|
Citizen.Wait(10000)
|
|
SetEntityHealth(PlayerPedId(), 0)
|
|
end
|
|
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)
|
|
|
|
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)
|
|
ClearPedBloodDamage(ped)
|
|
|
|
TriggerServerEvent('esx:onPlayerSpawn')
|
|
TriggerEvent('esx:onPlayerSpawn')
|
|
TriggerEvent('playerSpawned') -- compatibility with old scripts, will be removed soon
|
|
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
|