wasabi_ambulance/game/client/client.lua
8 removals
622 lines
12 additions
628 lines
-----------------For support, scripts, and more----------------
-----------------For support, scripts, and more----------------
--------------- https://discord.gg/wasabiscripts -------------
--------------- https://discord.gg/wasabiscripts -------------
---------------------------------------------------------------
---------------------------------------------------------------
if not wsb then return print((Strings.no_wsb):format(GetCurrentResourceName())) end
if not wsb then return print((Strings.no_wsb):format(GetCurrentResourceName())) end
isDead, disableKeys, isReviving, inMenu, medbagCoords, isBusy, Authorized, OnPainKillers, GameShake, InjuryRunning, IsCheckedIn =
isDead, disableKeys, isReviving, inMenu, medbagCoords, isBusy, Authorized, OnPainKillers, GameShake, InjuryRunning, IsCheckedIn =
nil, nil, nil, nil, nil, nil, nil, false, false, false, false
nil, nil, nil, nil, nil, nil, nil, false, false, false, false
local deathInjury, previousHealth, previousArmour
local deathInjury, previousHealth, previousArmour
plyRequests = {}
plyRequests = {}
currentDrugEffect, nodOutRunning = false, false
currentDrugEffect, nodOutRunning = false, false
local targetedVehicle = nil
local targetedVehicle = nil
CreateThread(function()
CreateThread(function()
while not wsb.playerLoaded do Wait(1000) end
while not wsb.playerLoaded do Wait(1000) end
if Config.policeCanTreat and Config.policeCanTreat.enabled and wsb.hasGroup(Config.policeCanTreat.jobs) then
if Config.policeCanTreat and Config.policeCanTreat.enabled and wsb.hasGroup(Config.policeCanTreat.jobs) then
Authorized = true
Authorized = true
end
end
if Config.UseRadialMenu then
if Config.UseRadialMenu then
AddRadialItems()
AddRadialItems()
end
end
if Config.targetSystem then
if Config.targetSystem then
wsb.target.model({ Config.BagProp }, {
wsb.target.model({ Config.BagProp }, {
options = {
options = {
{
{
event = 'wasabi_ambulance:pickupBag',
event = 'wasabi_ambulance:pickupBag',
icon = 'fas fa-hand-paper',
icon = 'fas fa-hand-paper',
label = Strings.pickup_bag_target,
label = Strings.pickup_bag_target,
canInteract = function(entity)
canInteract = function(entity)
local canInteract = false
local canInteract = false
if Entity(entity).state.useable then canInteract = true end
if Entity(entity).state.useable then canInteract = true end
if isPlayerDead() then canInteract = false end
if isPlayerDead() then canInteract = false end
return canInteract
return canInteract
end
end
},
},
{
{
event = 'wasabi_ambulance:interactBag',
event = 'wasabi_ambulance:interactBag',
icon = 'fas fa-briefcase',
icon = 'fas fa-briefcase',
label = Strings.interact_bag_target,
label = Strings.interact_bag_target,
canInteract = function(entity)
canInteract = function(entity)
local canInteract = false
local canInteract = false
if Entity(entity).state.useable then canInteract = true end
if Entity(entity).state.useable then canInteract = true end
if isPlayerDead() then canInteract = false end
if isPlayerDead() then canInteract = false end
return canInteract
return canInteract
end
end
},
},
},
},
job = 'all',
job = 'all',
distance = 1.5
distance = 1.5
})
})
wsb.target.player({
wsb.target.player({
options = {
options = {
{
{
event = 'wasabi_ambulance:diagnosePatient',
event = 'wasabi_ambulance:diagnosePatient',
icon = 'fas fa-stethoscope',
icon = 'fas fa-stethoscope',
label = Strings.diagnose_patient,
label = Strings.diagnose_patient,
job = Config.ambulanceJob or JobArrayToTarget(),
job = Config.ambulanceJob or JobArrayToTarget(),
groups = Config.ambulanceJob or JobArrayToTarget()
groups = Config.ambulanceJob or JobArrayToTarget()
},
},
{
{
event = 'wasabi_ambulance:reviveTarget',
event = 'wasabi_ambulance:reviveTarget',
icon = 'fas fa-medkit',
icon = 'fas fa-medkit',
label = Strings.revive_patient,
label = Strings.revive_patient,
job = Config.ambulanceJob or JobArrayToTarget(),
job = Config.ambulanceJob or JobArrayToTarget(),
groups = Config.ambulanceJob or JobArrayToTarget()
groups = Config.ambulanceJob or JobArrayToTarget()
},
},
{
{
event = 'wasabi_ambulance:healTarget',
event = 'wasabi_ambulance:healTarget',
icon = 'fas fa-bandage',
icon = 'fas fa-bandage',
label = Strings.heal_patient,
label = Strings.heal_patient,
job = Config.ambulanceJob or JobArrayToTarget(),
job = Config.ambulanceJob or JobArrayToTarget(),
groups = Config.ambulanceJob or JobArrayToTarget()
groups = Config.ambulanceJob or JobArrayToTarget()
},
},
{
{
event = 'wasabi_ambulance:useSedative',
event = 'wasabi_ambulance:useSedative',
icon = 'fas fa-syringe',
icon = 'fas fa-syringe',
label = Strings.sedate_patient,
label = Strings.sedate_patient,
job = Config.ambulanceJob or JobArrayToTarget(),
job = Config.ambulanceJob or JobArrayToTarget(),
groups = Config.ambulanceJob or JobArrayToTarget()
groups = Config.ambulanceJob or JobArrayToTarget()
}
}
},
},
distance = 1.5
distance = 1.5
})
})
wsb.target.vehicle({
wsb.target.vehicle({
options = {
options = {
--[[ {
--[[ {
event = 'wasabi_ambulance:enterBackVehicle',
event = 'wasabi_ambulance:enterBackVehicle',
icon = 'fas fa-car',
icon = 'fas fa-car',
label = Strings.enter_vehicle_back,
label = Strings.enter_vehicle_back,
canInteract = function(entity)
canInteract = function(entity)
if not IsVehicleAmbulance(entity) or not IsNearTrunk(entity) or MovingStretcher then return false end
if not IsVehicleAmbulance(entity) or not IsNearTrunk(entity) or MovingStretcher then return false end
return true
return true
end,
end,
job = Config.ambulanceJob,
job = Config.ambulanceJob,
groups = Config.ambulanceJob
groups = Config.ambulanceJob
},]] -- Lame
},]] -- Lame
{
{
event = 'wasabi_ambulance:toggleStretcher',
event = 'wasabi_ambulance:toggleStretcher',
icon = 'fas fa-car',
icon = 'fas fa-car',
label = Strings.toggle_stretcher,
label = Strings.toggle_stretcher,
canInteract = function(entity)
canInteract = function(entity)
if not IsVehicleAmbulance(entity) or not IsNearTrunk(entity) or MovingStretcher then return false end
if not IsVehicleAmbulance(entity) or not IsNearTrunk(entity) or MovingStretcher then return false end
local alreadyDeployed = HasAmbulanceSpawnedStretcher(VehToNet(entity))
local alreadyDeployed = HasAmbulanceSpawnedStretcher(VehToNet(entity))
local stretcherInside = GetStretcherInVehicle(entity)
local stretcherInside = GetStretcherInVehicle(entity)
return not alreadyDeployed or stretcherInside
return not alreadyDeployed or stretcherInside
end,
end,
job = Config.ambulanceJob or JobArrayToTarget(),
job = Config.ambulanceJob or JobArrayToTarget(),
groups = Config.ambulanceJob or JobArrayToTarget()
groups = Config.ambulanceJob or JobArrayToTarget()
},
},
{
{
event = 'wasabi_ambulance:stretcherInVehicle',
event = 'wasabi_ambulance:stretcherInVehicle',
icon = 'fas fa-car',
icon = 'fas fa-car',
label = Strings.stretcher_in_vehicle,
label = Strings.stretcher_in_vehicle,
canInteract = function(entity)
canInteract = function(entity)
if not IsVehicleAmbulance(entity) or not IsNearTrunk(entity) then return false end
if not IsVehicleAmbulance(entity) or not IsNearTrunk(entity) then return false end
local stretcherInside = GetStretcherInVehicle(entity)
local stretcherInside = GetStretcherInVehicle(entity)
if stretcherInside then return false end
if stretcherInside then return false end
if MovingStretcher then return true end
if MovingStretcher then return true end
if not GetClosestStretcher(3.0) then return false end
if not GetClosestStretcher(3.0) then return false end
return true
return true
end,
end,
job = Config.ambulanceJob or JobArrayToTarget(),
job = Config.ambulanceJob or JobArrayToTarget(),
groups = Config.ambulanceJob or JobArrayToTarget()
groups = Config.ambulanceJob or JobArrayToTarget()
},
},
{
{
event = 'wasabi_ambulance:removeDeadFromVehicle',
event = 'wasabi_ambulance:removeDeadFromVehicle',
icon = 'fas fa-car',
icon = 'fas fa-car',
label = Strings.remove_dead_target,
label = Strings.remove_dead_target,
canInteract = function(entity)
canInteract = function(entity)
local deadPlayerID = GetDeadPlayerInsideVehicle(entity)
local deadPlayerID = GetDeadPlayerInsideVehicle(entity)
return deadPlayerID
return deadPlayerID
end
end
},
},
{
{
event = 'wasabi_ambulance:placeInVehicle',
event = 'wasabi_ambulance:placeInVehicle',
icon = 'fas fa-car',
icon = 'fas fa-car',
label = Strings.place_patient,
label = Strings.place_patient,
canInteract = function(entity)
canInteract = function(entity)
if not IsVehicleAmbulance(entity) then return false end
if not IsVehicleAmbulance(entity) then return false end
local coords = GetEntityCoords(entity)
local coords = GetEntityCoords(entity)
local closestPlayer = wsb.getClosestPlayer(coords, 4.0)
local closestPlayer = wsb.getClosestPlayer(coords, 4.0)
if not closestPlayer then return false end
if not closestPlayer then return false end
targetedVehicle = entity
targetedVehicle = entity
if IsPedInAnyVehicle(GetPlayerPed(closestPlayer), false) then return true end
if IsPedInAnyVehicle(GetPlayerPed(closestPlayer), false) then return true end
if not Config.EnableStretcher then return true end
if not Config.EnableStretcher then return true end
if IsPlayerUsingStretcher(closestPlayer) then return false end
if IsPlayerUsingStretcher(closestPlayer) then return false end
return true
return true
end,
end,
job = Config.ambulanceJob or JobArrayToTarget(),
job = Config.ambulanceJob or JobArrayToTarget(),
groups = Config.ambulanceJob or JobArrayToTarget()
groups = Config.ambulanceJob or JobArrayToTarget()
},
},
},
},
distance = 1.5
distance = 1.5
})
})
end
end
end)
end)
AddEventHandler('onResourceStart', function(resourceName)
AddEventHandler('onResourceStart', function(resourceName)
if GetCurrentResourceName() ~= resourceName or not wsb or not wsb.playerLoaded or not Config.UseRadialMenu then return end
if GetCurrentResourceName() ~= resourceName or not wsb or not wsb.playerLoaded or not Config.UseRadialMenu then return end
AddRadialItems()
AddRadialItems()
end)
end)
AddEventHandler('onClientMapStart', function()
AddEventHandler('onClientMapStart', function()
exports.spawnmanager:spawnPlayer()
exports.spawnmanager:spawnPlayer()
Wait(5000)
Wait(5000)
exports.spawnmanager:setAutoSpawn(false)
exports.spawnmanager:setAutoSpawn(false)
end)
end)
lib.onCache('ped', function(ped)
lib.onCache('ped', function(ped)
if not DoesEntityExist(ped) then return end
if not DoesEntityExist(ped) then return end
if ped == cache.ped then return end
if ped == cache.ped then return end
SetHealthDefaults()
SetHealthDefaults()
end)
end)
RegisterNetEvent('wasabi_bridge:playerLoaded', function()
RegisterNetEvent('wasabi_bridge:playerLoaded', function()
while not wsb?.playerLoaded and not wsb?.playerData?.job do Wait(1000) end
while not wsb?.playerLoaded and not wsb?.playerData?.job do Wait(1000) end
if Config.AntiCombatLog.enabled then
if Config.AntiCombatLog.enabled then
CreateThread(function()
CreateThread(function()
while not DoesEntityExist(PlayerPedId()) do Wait(500) end
while not DoesEntityExist(PlayerPedId()) do Wait(500) end
local dead
local dead
if wsb.framework == 'qb' then
if wsb.framework == 'qb' then
dead = wsb.playerData.metadata["isdead"] or false
dead = wsb.playerData.metadata["isdead"] or false
if not dead and Config.LastStand then
if not dead and Config.LastStand then
dead = wsb.playerData.metadata["inlaststand"] or false
dead = wsb.playerData.metadata["inlaststand"] or false
end
end
elseif wsb.framework == 'esx' then
elseif wsb.framework == 'esx' then
dead = lib.callback.await('wasabi_ambulance:checkDeath', 300)
dead = lib.callback.await('wasabi_ambulance:checkDeath', 300)
end
end
if dead then
if dead then
Wait(3000)
Wait(3000)
SetEntityHealth(PlayerPedId(), 0)
SetEntityHealth(PlayerPedId(), 0)
if Config.AntiCombatLog.notification.enabled then
if Config.AntiCombatLog.notification.enabled then
TriggerEvent('wasabi_bridge:notify', Config.AntiCombatLog.notification.title,
TriggerEvent('wasabi_bridge:notify', Config.AntiCombatLog.notification.title,
Config.AntiCombatLog.notification.desc, 'error', 'skull-crossbones')
Config.AntiCombatLog.notification.desc, 'error', 'skull-crossbones')
end
end
else
else
local previousVitals = lib.callback.await('wasabi_ambulance:checkPreviousVitals', 1000)
local previousVitals = lib.callback.await('wasabi_ambulance:checkPreviousVitals', 1000)
if previousVitals then
if previousVitals then
Wait(3000)
Wait(3000)
if previousVitals.health then
if previousVitals.health then
SetEntityHealth(PlayerPedId(), previousVitals.health)
SetEntityHealth(PlayerPedId(), previousVitals.health)
end
end
if previousVitals.injuries and next(previousVitals.injuries) then
if previousVitals.injuries and next(previousVitals.injuries) then
PlayerInjury = previousVitals.injuries
PlayerInjury = previousVitals.injuries
TriggerServerEvent('wasabi_ambulance:injurySync', PlayerInjury)
TriggerServerEvent('wasabi_ambulance:injurySync', PlayerInjury)
end
end
end
end
end
end
end)
end)
elseif wsb.framework == 'qb' then
elseif wsb.framework == 'qb' then
if wsb.playerData.metadata["isdead"] or wsb.playerData.metadata["inlaststand"] then
if wsb.playerData.metadata["isdead"] or wsb.playerData.metadata["inlaststand"] then
TriggerServerEvent('wasabi_ambulance:setDeathStatus', false, false)
TriggerServerEvent('wasabi_ambulance:setDeathStatus', false, false)
wsb.playerData.metadata["isdead"] = false
wsb.playerData.metadata["isdead"] = false
wsb.playerData.metadata["inlaststand"] = false
wsb.playerData.metadata["inlaststand"] = false
end
end
end
end
if wsb.hasGroup(Config.ambulanceJobs or Config.ambulanceJob) then
if wsb.hasGroup(Config.ambulanceJobs or Config.ambulanceJob) then
TriggerServerEvent('wasabi_ambulance:requestSync')
TriggerServerEvent('wasabi_ambulance:requestSync')
end
end
end)
end)
RegisterNetEvent('wasabi_ambulance:setJob', function(job)
RegisterNetEvent('wasabi_ambulance:setJob', function(job)
Authorized = false
Authorized = false
if Config?.policeCanTreat?.enabled then
if Config?.policeCanTreat?.enabled then
if wsb.hasGroup(Config.policeCanTreat.jobs) then
if wsb.hasGroup(Config.policeCanTreat.jobs) then
Authorized = true
Authorized = true
end
end
end
end
if wsb.hasGroup(Config.ambulanceJobs or Config.ambulanceJob) then
if wsb.hasGroup(Config.ambulanceJobs or Config.ambulanceJob) then
TriggerServerEvent('wasabi_ambulance:requestSync')
TriggerServerEvent('wasabi_ambulance:requestSync')
end
end
if Config.UseRadialMenu then
if Config.UseRadialMenu then
AddRadialItems()
AddRadialItems()
end
end
end)
end)
if Config.lowHealthAlert.enabled then
if Config.lowHealthAlert.enabled then
CreateThread(function()
CreateThread(function()
local notified
local notified
while true do
while true do
Wait(1500)
Wait(1500)
local health = GetEntityHealth(cache.ped)
local health = GetEntityHealth(cache.ped)
if health ~= 0 and health < Config.lowHealthAlert.health and not notified then
if health ~= 0 and health < Config.lowHealthAlert.health and not notified then
TriggerEvent('wasabi_bridge:notify', Config.lowHealthAlert.notification.title,
TriggerEvent('wasabi_bridge:notify', Config.lowHealthAlert.notification.title,
Config.lowHealthAlert.notification.description, 'error')
Config.lowHealthAlert.notification.description, 'error')
notified = true
notified = true
elseif notified and health >= Config.lowHealthAlert.health then
elseif notified and health >= Config.lowHealthAlert.health then
notified = nil
notified = nil
end
end
end
end
end)
end)
end
end
CreateThread(function()
CreateThread(function()
local setDeadFace = false
local setDeadFace = false
while true do
while true do
local sleep = 1500
local sleep = 1500
if isDead and (IsPedArmed(cache.ped, 1) or IsPedArmed(cache.ped, 2) or IsPedArmed(cache.ped, 4)) then
if isDead and (IsPedArmed(cache.ped, 1) or IsPedArmed(cache.ped, 2) or IsPedArmed(cache.ped, 4)) then
SetCurrentPedWeapon(PlayerPedId(), `WEAPON_UNARMED`, true)
SetCurrentPedWeapon(PlayerPedId(), `WEAPON_UNARMED`, true)
end
end
if isDead == 'dead' or disableKeys or (isDead == 'laststand' and Config.DisableLastStandCrawl) then
if isDead == 'dead' or disableKeys or (isDead == 'laststand' and Config.DisableLastStandCrawl) then
sleep = 0
sleep = 0
DisableAllControlActions(0)
DisableAllControlActions(0)
for k, data in pairs(Config.EnabledKeys.dead) do
for k, data in pairs(Config.EnabledKeys.dead) do
EnableControlAction(0, data, true)
EnableControlAction(0, data, true)
end
end
if isReviving and Config.EnabledKeys.revive then
if isReviving and Config.EnabledKeys.revive then
for _, keys in pairs(Config.EnabledKeys.revive) do
for _, keys in pairs(Config.EnabledKeys.revive) do
EnableControlAction(0, keys, true)
EnableControlAction(0, keys, true)
end
end
end
end
end
end
if isDead == 'dead' and not setDeadFace then
if isDead == 'dead' and not setDeadFace then
setDeadFace = true
setDeadFace = true
SetFacialIdleAnimOverride(PlayerPedId(), 'dead_2', 0)
SetFacialIdleAnimOverride(PlayerPedId(), 'dead_2', 0)
end
end
if not isDead and setDeadFace then
if not isDead and setDeadFace then
setDeadFace = false
setDeadFace = false
ClearFacialIdleAnimOverride(PlayerPedId())
ClearFacialIdleAnimOverride(PlayerPedId())
end
end
Wait(sleep)
Wait(sleep)
end
end
end)
end)
local GetActivePlayers = GetActivePlayers
local GetActivePlayers = GetActivePlayers
local NAMES, serverBlips, activeBlips, showPlayers = {}, {}, {}, {}
local NAMES, serverBlips, activeBlips, showPlayers = {}, {}, {}, {}
CreateThread(function()
CreateThread(function()
if not Config.GPSBlips.enabled then return end
if not Config.GPSBlips.enabled then return end
while not wsb.playerLoaded do
while not wsb.playerLoaded do
Wait(1000)
Wait(1000)
end
end
while Config.GPSBlips.enabled do
while Config.GPSBlips.enabled do
NAMES = lib.callback.await('wasabi_ambulance:getPlayerNames', 500)
NAMES = lib.callback.await('wasabi_ambulance:getPlayerNames', 500)
Wait(60000)
Wait(60000)
end
end
end)
end)
RegisterNetEvent('wasabi_ambulance:useGPS', function(player, bool)
RegisterNetEvent('wasabi_ambulance:useGPS', function(player, bool)
showPlayers[player] = bool
showPlayers[player] = bool
end)
end)
CreateThread(function()
CreateThread(function()
if not Config.GPSBlips.enabled then return end
if not Config.GPSBlips.enabled then return end
local cooldown = 0
local cooldown = 0
local server = {}
local server = {}
local active, activeTable, activeCreated, activePed, activePlayer = {}, {}, {}, 0, 0
local active, activeTable, activeCreated, activePed, activePlayer = {}, {}, {}, 0, 0
while not wsb.playerLoaded do
while not wsb.playerLoaded do
Wait(1000)
Wait(1000)
end
end
Wait(1000)
Wait(1000)
while Config.GPSBlips.enabled do
while Config.GPSBlips.enabled do
active = GetActivePlayers()
active = GetActivePlayers()
for k, data in pairs(active) do
for k, data in pairs(active) do
activePlayer = GetPlayerServerId(data)
activePlayer = GetPlayerServerId(data)
if not showPlayers[activePlayer] then goto continue end
if not showPlayers[activePlayer] then goto continue end
if data == cache.playerId then goto continue end
if data == cache.playerId then goto continue end
activePed = GetPlayerPed(data)
activePed = GetPlayerPed(data)
if not DoesEntityExist(activePed) then goto continue end
if not DoesEntityExist(activePed) then goto continue end
activeTable[activePlayer] = {
activeTable[activePlayer] = {
coords = GetEntityCoords(activePed),
coords = GetEntityCoords(activePed),
player = activePlayer,
player = activePlayer,
ped = activePed,
ped = activePed,
name = NAMES[activePlayer]
name = NAMES[activePlayer]
}
}
::continue::
::continue::
end
end
for _, data in pairs(activeTable) do
for _, data in pairs(activeTable) do
if not DoesBlipExist(activeBlips[data.player]) and not activeCreated[data.player] then
if not DoesBlipExist(activeBlips[data.player]) and not activeCreated[data.player] then
activeCreated[data.player] = true
activeCreated[data.player] = true
activeBlips[data.player] = CreateBlip(activePed, Config.GPSBlips.blip.sprite, Config.GPSBlips.blip.color,
activeBlips[data.player] = CreateBlip(activePed, Config.GPSBlips.blip.sprite, Config.GPSBlips.blip.color,
data.name, Config.GPSBlips.blip.scale, false, 'entity', Config.GPSBlips.blip.short)
data.name, Config.GPSBlips.blip.scale, false, 'entity', Config.GPSBlips.blip.short)
SetBlipCategory(activeBlips[data.player], 7)
SetBlipCategory(activeBlips[data.player], 7)
elseif not DoesBlipExist(activeBlips[data.player]) and activeCreated[data.player] then
elseif not DoesBlipExist(activeBlips[data.player]) and activeCreated[data.player] then
activeCreated[data.player] = false
activeCreated[data.player] = false
activeBlips[data.player] = nil
activeBlips[data.player] = nil
end
end
end
end
for k, data in pairs(activeBlips) do
for k, data in pairs(activeBlips) do
if not DoesBlipExist(data) then
if not DoesBlipExist(data) then
activeBlips[k] = nil
activeBlips[k] = nil
elseif DoesBlipExist(data) and not showPlayers[k] then
elseif DoesBlipExist(data) and not showPlayers[k] then
RemoveBlip(data)
RemoveBlip(data)
activeBlips[k] = nil
activeBlips[k] = nil
end
end
end
end
if cooldown <= 0 then
if cooldown <= 0 then
cooldown = Config.GPSBlips.refreshrate
cooldown = Config.GPSBlips.refreshrate
server = lib.callback.await('wasabi_ambulance:getPlayerCoords', 500)
server = lib.callback.await('wasabi_ambulance:getPlayerCoords', 500)
if server == {} or not server then goto skip end
if server == {} or not server then goto skip end
for k, data in pairs(serverBlips) do
for k, data in pairs(serverBlips) do
if DoesBlipExist(data) then
if DoesBlipExist(data) then
RemoveBlip(data)
RemoveBlip(data)
serverBlips[k] = nil
serverBlips[k] = nil
end
end
end
end
for k, data in pairs(server) do
for k, data in pairs(server) do
if activeBlips[data.player] then goto continue end
if activeBlips[data.player] then goto continue end
serverBlips[data.player] = CreateBlip(vector(data.coords.x, data.coords.y, data.coords.z),
serverBlips[data.player] = CreateBlip(vector(data.coords.x, data.coords.y, data.coords.z),
Config.GPSBlips.blip.sprite, Config.GPSBlips.blip.color, data.name, Config.GPSBlips.blip.scale, false,
Config.GPSBlips.blip.sprite, Config.GPSBlips.blip.color, data.name, Config.GPSBlips.blip.scale, false,
'coords', Config.GPSBlips.blip.short)
'coords', Config.GPSBlips.blip.short)
SetBlipCategory(serverBlips[data.player], 7)
SetBlipCategory(serverBlips[data.player], 7)
::continue::
::continue::
end
end
else
else
cooldown -= 1
cooldown -= 1
end
end
::skip::
::skip::
Wait(1000)
Wait(1000)
end
end
end)
end)
-- Spawn event
-- Spawn event
local firstSpawn = true
local firstSpawn = true
AddEventHandler('wasabi_bridge:onPlayerSpawn', function(noAnim)
AddEventHandler('wasabi_bridge:onPlayerSpawn', function(noAnim)
if firstSpawn then
if firstSpawn then
firstSpawn = false
firstSpawn = false
return
return
end
end
isDead = false
isDead = false
if Config.DeathScreenEffects then AnimpostfxStopAll() end
if Config.DeathScreenEffects then AnimpostfxStopAll() end
if not noAnim then
if not noAnim then
lib.requestAnimDict('get_up@directional@movement@from_knees@action', 3000)
lib.requestAnimDict('get_up@directional@movement@from_knees@action', 3000)
TaskPlayAnim(cache.ped, 'get_up@directional@movement@from_knees@action', 'getup_r_0', 8.0, -8.0, -1, 0, 0, false,
TaskPlayAnim(cache.ped, 'get_up@directional@movement@from_knees@action', 'getup_r_0', 8.0, -8.0, -1, 0, 0, false,
false, false)
false, false)
RemoveAnimDict('get_up@directional@movement@from_knees@action')
RemoveAnimDict('get_up@directional@movement@from_knees@action')
end
end
HideDeathNui()
HideDeathNui()
TriggerServerEvent('wasabi_ambulance:setDeathStatus', false, true)
TriggerServerEvent('wasabi_ambulance:setDeathStatus', false, true)
end)
end)
-- Death Event
-- Death Event
local originalDeath
local originalDeath
local originalLocation
local originalLocation
AddEventHandler('wasabi_bridge:onPlayerDeath', function(data)
AddEventHandler('wasabi_bridge:onPlayerDeath', function(data)
-- Added Code (highqez_crawldead)
if exports['highqez_crawldead']:IsCrawling() then
exports['highqez_crawldead']:EndCrawl()
elseif exports['highqez_crawldead']:IsDead() then
elseif not exports['highqez_crawldead']:IsCrawling() and not isDead then
exports['highqez_crawldead']:StartCrawl()
return
else
return
end
if OccupyingStretcher then
if OccupyingStretcher then
local occupyingStretcher = OccupyingStretcher
local occupyingStretcher = OccupyingStretcher
OccupyingStretcher = nil
OccupyingStretcher = nil
CreateThread(function()
CreateThread(function()
local stretcherID = GetActiveStretcherIDFromEntity(occupyingStretcher)
local stretcherID = GetActiveStretcherIDFromEntity(occupyingStretcher)
local serverID = GetPlayerServerId(PlayerId())
local serverID = GetPlayerServerId(PlayerId())
if stretcherID and serverID then
if stretcherID and serverID then
Wait(100)
Wait(100)
TriggerServerEvent('wasabi_ambulance:placePlayerOnStretcher', stretcherID, serverID)
TriggerServerEvent('wasabi_ambulance:placePlayerOnStretcher', stretcherID, serverID)
end
end
end)
end)
end
end
if not isDead then
if not isDead then
originalDeath = data.deathCause
originalDeath = data.deathCause
local _, bone = GetPedLastDamageBone(cache.ped)
local _, bone = GetPedLastDamageBone(cache.ped)
if originalLocation ~= Bones[bone] then
if originalLocation ~= Bones[bone] then
originalLocation = Bones[bone]
originalLocation = Bones[bone]
end
end
end
end
if isDead == 'laststand' and originalDeath then
if isDead == 'laststand' and originalDeath then
if data.deathCause == -842959696 then
if data.deathCause == -842959696 then
data.deathCause = originalDeath
data.deathCause = originalDeath
else
else
local _, bone = GetPedLastDamageBone(cache.ped)
local _, bone = GetPedLastDamageBone(cache.ped)
if originalLocation ~= Bones[bone] then
if originalLocation ~= Bones[bone] then
originalLocation = Bones[bone]
originalLocation = Bones[bone]
end
end
end
end
originalDeath = nil
originalDeath = nil
end
end
if data.deathCause == 0 then
if data.deathCause == 0 then
local onFire = false
local onFire = false
if IsEntityOnFire(cache.ped) then
if IsEntityOnFire(cache.ped) then
deathInjury = 'burned'
deathInjury = 'burned'
onFire = true
onFire = true
end
end
local deathSource = wsb.getClosestPlayer(vec3(data.victimCoords.x, data.victimCoords.y, data.victimCoords.z), 3.0)
local deathSource = wsb.getClosestPlayer(vec3(data.victimCoords.x, data.victimCoords.y, data.victimCoords.z), 3.0)
local _, bone = GetPedLastDamageBone(cache.ped)
local _, bone = GetPedLastDamageBone(cache.ped)
if originalLocation ~= Bones[bone] then
if originalLocation ~= Bones[bone] then
originalLocation = Bones[bone]
originalLocation = Bones[bone]
end
end
if deathSource and not onFire then
if deathSource and not onFire then
local deathSourcePed = GetPlayerPed(deathSource)
local deathSourcePed = GetPlayerPed(deathSource)
local weapon = GetSelectedPedWeapon(deathSourcePed)
local weapon = GetSelectedPedWeapon(deathSourcePed)
local foundInjury
local foundInjury
for k, v in pairs(InjuryReasons) do
for k, v in pairs(InjuryReasons) do
for i = 1, #v do
for i = 1, #v do
if v[i] == weapon then
if v[i] == weapon then
deathInjury = tostring(k)
deathInjury = tostring(k)
foundInjury = true
foundInjury = true
break
break
end
end
end
end
end
end
if weapon and not foundInjury then deathInjury = CheckWeaponType(weapon) end
if weapon and not foundInjury then deathInjury = CheckWeaponType(weapon) end
if deathInjury == 'shot' then deathInjury = 'beat' end
if deathInjury == 'shot' then deathInjury = 'beat' end
end
end
elseif data.deathCause == -842959696 then
elseif data.deathCause == -842959696 then
deathInjury = 'bleedout'
deathInjury = 'bleedout'
else
else
local foundInjury
local foundInjury
for k, v in pairs(InjuryReasons) do
for k, v in pairs(InjuryReasons) do
for i = 1, #v do
for i = 1, #v do
if v[i] == data.deathCause then
if v[i] == data.deathCause then
deathInjury = tostring(k)
deathInjury = tostring(k)
foundInjury = true
foundInjury = true
break
break
end
end
end
end
end
end
if not foundInjury then deathInjury = CheckWeaponType(data.deathCause) end
if not foundInjury then deathInjury = CheckWeaponType(data.deathCause) end
end
end
PlayerInjury = {}
PlayerInjury = {}
if Config.DeathLogs then
if Config.DeathLogs then
local killer = GetPedSourceOfDeath(cache.ped)
local killer = GetPedSourceOfDeath(cache.ped)
local dCause = GetPedCauseOfDeath(cache.ped)
local dCause = GetPedCauseOfDeath(cache.ped)
local deathCause
local deathCause
if IsEntityAPed(killer) and IsPedAPlayer(killer) then
if IsEntityAPed(killer) and IsPedAPlayer(killer) then
killer = NetworkGetPlayerIndexFromPed(killer)
killer = NetworkGetPlayerIndexFromPed(killer)
elseif IsEntityAVehicle(killer) and IsEntityAPed(GetPedInVehicleSeat(killer, -1)) and IsPedAPlayer(GetPedInVehicleSeat(killer, -1)) then
elseif IsEntityAVehicle(killer) and IsEntityAPed(GetPedInVehicleSeat(killer, -1)) and IsPedAPlayer(GetPedInVehicleSeat(killer, -1)) then
killer = NetworkGetPlayerIndexFromPed(GetPedInVehicleSeat(dCause, -1))
killer = NetworkGetPlayerIndexFromPed(GetPedInVehicleSeat(dCause, -1))
end
end
if (killer == PlayerId()) then
if (killer == PlayerId()) then
deathCause = 'suicide'
deathCause = 'suicide'
elseif (killer == nil or killer == 0) then
elseif (killer == nil or killer == 0) then
deathCause = 'unknown'
deathCause = 'unknown'
end
end
if deathCause == 'suicide' or deathCause == 'unknown' then
if deathCause == 'suicide' or deathCause == 'unknown' then
TriggerServerEvent('wasabi_ambulance:logDeath', dCause, nil)
TriggerServerEvent('wasabi_ambulance:logDeath', dCause, nil)
elseif killer then
elseif killer then
TriggerServerEvent('wasabi_ambulance:logDeath', dCause, GetPlayerServerId(killer))
TriggerServerEvent('wasabi_ambulance:logDeath', dCause, GetPlayerServerId(killer))
end
end
end
end
if Config.MythicHospital then
if Config.MythicHospital then
TriggerEvent('mythic_hospital:client:RemoveBleed')
TriggerEvent('mythic_hospital:client:RemoveBleed')
TriggerEvent('mythic_hospital:client:ResetLimbs')
TriggerEvent('mythic_hospital:client:ResetLimbs')
end
end
local injuryData = {
local injuryData = {
injury = deathInjury or Strings.unknown,
injury = deathInjury or Strings.unknown,
location = originalLocation
location = originalLocation
}
}
TriggerServerEvent('wasabi_ambulance:injurySync', injuryData)
TriggerServerEvent('wasabi_ambulance:injurySync', injuryData)
if not Config.DisableHeadShotKill and Config.LastStand and not isDead and injuryData.injury == 'shot' and injuryData.location == 'head' then
if not Config.DisableHeadShotKill and Config.LastStand and not isDead and injuryData.injury == 'shot' and injuryData.location == 'head' then
OnPlayerDeath(false)
OnPlayerDeath(false)
return
return
end
end
if not Config.LastStand or IsPedInAnyVehicle(cache.ped, false) then
if not Config.LastStand or IsPedInAnyVehicle(cache.ped, false) then
OnPlayerDeath(false)
OnPlayerDeath(false)
return
return
end
end
OnLastStand()
OnLastStand()
end)
end)
-- Live injury
-- Live injury
RegisterNetEvent('wasabi_ambulance:syncInjury', function(data, notify)
RegisterNetEvent('wasabi_ambulance:syncInjury', function(data, notify)
PlayerInjury = data
PlayerInjury = data
if not notify then return end
if not notify then return end
if #PlayerInjury < 1 then
if #PlayerInjury < 1 then
TriggerEvent('wasabi_bridge:notify', Strings.player_treated, Strings.treated_fully_desc, 'success')
TriggerEvent('wasabi_bridge:notify', Strings.player_treated, Strings.treated_fully_desc, 'success')
else
else
TriggerEvent('wasabi_bridge:notify', Strings.player_treated, Strings.treated_not_fully_desc, 'inform')
TriggerEvent('wasabi_bridge:notify', Strings.player_treated, Strings.treated_not_fully_desc, 'inform')
end
end
end)
end)
if Config.EnableLiveInjury then
if Config.EnableLiveInjury then
local previousHealth = 200
local previousHealth = 200
AddEventHandler('gameEventTriggered', function(event, data)
AddEventHandler('gameEventTriggered', function(event, data)
if event == "CEventNetworkEntityDamage" then
if event == "CEventNetworkEntityDamage" then
local victim = data[1]
local victim = data[1]
local playerId = NetworkGetPlayerIndexFromPed(victim)
local playerId = NetworkGetPlayerIndexFromPed(victim)
if playerId ~= PlayerId() then return end
if playerId ~= PlayerId() then return end
if (IsPedDeadOrDying(victim, true) or IsPedFatallyInjured(victim)) then return end
if (IsPedDeadOrDying(victim, true) or IsPedFatallyInjured(victim)) then return end
local health = GetEntityHealth(cache.ped)
local health = GetEntityHealth(cache.ped)
local armour = GetPedArmour(cache.ped)
local armour = GetPedArmour(cache.ped)
if not previousHealth then previousHealth = health end
if not previousHealth then previousHealth = health end
if not previousArmour then previousArmour = armour end
if not previousArmour then previousArmour = armour end
local healthDamage = (previousHealth - health)
local healthDamage = (previousHealth - health)
local armourDamage = (previousArmour - armour)
local armourDamage = (previousArmour - armour)
if healthDamage > (Config?.DamageDetectThreshold?.health or 10) then
if healthDamage > (Config?.DamageDetectThreshold?.health or 10) then
ChanceInjury()
ChanceInjury()
elseif armourDamage > (Config?.DamageDetectThreshold?.armour or 5) then
elseif armourDamage > (Config?.DamageDetectThreshold?.armour or 5) then
ChanceInjury()
ChanceInjury()
end
end
end
end
end)
end)
-- Loop for debugging
-- Loop for debugging
--[[CreateThread(function()
--[[CreateThread(function()
while true do
while true do
Wait(2000)
Wait(2000)
if next(PlayerInjury) then
if next(PlayerInjury) then
for k, v in pairs(PlayerInjury) do
for k, v in pairs(PlayerInjury) do
print(k, v.data.level, v.data.bleed)
print(k, v.data.level, v.data.bleed)
end
end
end
end
end
end
end)]]
end)]]
function GetIdentifier()
function GetIdentifier()
local identifier = lib.callback.await('wasabi_ambulance:getIdentifier', 1000)
local identifier = lib.callback.await('wasabi_ambulance:getIdentifier', 1000)
return identifier or false
return identifier or false
end
end
-- Main loop
-- Main loop
CreateThread(function()
CreateThread(function()
local lastNotificationSent = 0
local lastNotificationSent = 0
local staggering = false
local staggering = false
local limping = false
local limping = false
local notificationCooldown = Config.InjuryNotificationFrequency
local notificationCooldown = Config.InjuryNotificationFrequency
local lastBleedCheck = 0
local lastBleedCheck = 0
local loggedInjury = {}
local loggedInjury = {}
local loggedHealth = {}
local loggedHealth = {}
local playerIsLoaded = true
local playerIsLoaded = true
local health = 200
local health = 200
local sentBlackoutNotification = false
local sentBlackoutNotification = false
local sentBlackoutTime = GetGameTimer()
local sentBlackoutTime = GetGameTimer()
while true do
while true do
local sleep = 100
local sleep = 100
local moveRate = 1.0
local moveRate = 1.0
local shouldLimp = false
local shouldLimp = false
local ped = PlayerPedId()
local ped = PlayerPedId()
local playerId = PlayerId()
local playerId = PlayerId()
if cache.ped and DoesEntityExist(cache.ped) then
if cache.ped and DoesEntityExist(cache.ped) then
health = GetEntityHealth(cache.ped)
health = GetEntityHealth(cache.ped)
end
end
if not wsb.playerLoaded and playerIsLoaded then
if not wsb.playerLoaded and playerIsLoaded then
local identifier = GetIdentifier()
local identifier = GetIdentifier()
if identifier then
if identifier then
loggedInjury[identifier] = PlayerInjury
loggedInjury[identifier] = PlayerInjury
loggedHealth[identifier] = health
loggedHealth[identifier] = health
end
end
playerIsLoaded = false
playerIsLoaded = false
DrugIntake = {}
DrugIntake = {}
nodOutRunning = false
nodOutRunning = false
currentDrugEffect = false
currentDrugEffect = false
isDead = false
isDead = false
PlayerInjury = {}
PlayerInjury = {}
TriggerServerEvent('wasabi_ambulance:injurySync', false)
TriggerServerEvent('wasabi_ambulance:injurySync', false)
TriggerServerEvent('wasabi_ambulance:setDeathStatus', false, false, true)
TriggerServerEvent('wasabi_ambulance:setDeathStatus', false, false, true)
elseif wsb.playerLoaded and not playerIsLoaded then
elseif wsb.playerLoaded and not playerIsLoaded then
playerIsLoaded = true
playerIsLoaded = true
local identifier = GetIdentifier()
local identifier = GetIdentifier()
if identifier then
if identifier then
if loggedHealth[identifier] then
SetEntityHealth(cache.ped, loggedHealth[identifier])
end
if loggedInjury[identifier] and next(loggedInjury[identifier]) then
PlayerInjury = loggedInjury[identifier]
TriggerServerEvent('wasabi_ambulance:injurySync', PlayerInjury)