QBCore = exports['qb-core']:GetCoreObject() local getOutDict = 'switch@franklin@bed' local getOutAnim = 'sleep_getup_rubeyes' local canLeaveBed = true local bedOccupying = nil local bedObject = nil local bedOccupyingData = nil local doctorCount = 0 local CurrentDamageList = {} local cam = nil local playerArmor = nil local hospitalLocation = 1 inBedDict = 'anim@gangops@morgue@table@' inBedAnim = 'body_search' isInHospitalBed = false isBleeding = 0 bleedTickTimer, advanceBleedTimer = 0, 0 fadeOutTimer, blackoutTimer = 0, 0 legCount = 0 armcount = 0 headCount = 0 playerHealth = nil isDead = false isStatusChecking = false statusChecks = {} statusCheckTime = 0 healAnimDict = 'mini@cpr@char_a@cpr_str' healAnim = 'cpr_pumpchest' injured = {} BodyParts = { ['HEAD'] = { label = Lang:t('body.head'), causeLimp = false, isDamaged = false, severity = 0 }, ['NECK'] = { label = Lang:t('body.neck'), causeLimp = false, isDamaged = false, severity = 0 }, ['SPINE'] = { label = Lang:t('body.spine'), causeLimp = true, isDamaged = false, severity = 0 }, ['UPPER_BODY'] = { label = Lang:t('body.upper_body'), causeLimp = false, isDamaged = false, severity = 0 }, ['LOWER_BODY'] = { label = Lang:t('body.lower_body'), causeLimp = true, isDamaged = false, severity = 0 }, ['LARM'] = { label = Lang:t('body.left_arm'), causeLimp = false, isDamaged = false, severity = 0 }, ['LHAND'] = { label = Lang:t('body.left_hand'), causeLimp = false, isDamaged = false, severity = 0 }, ['LFINGER'] = { label = Lang:t('body.left_fingers'), causeLimp = false, isDamaged = false, severity = 0 }, ['LLEG'] = { label = Lang:t('body.left_leg'), causeLimp = true, isDamaged = false, severity = 0 }, ['LFOOT'] = { label = Lang:t('body.left_foot'), causeLimp = true, isDamaged = false, severity = 0 }, ['RARM'] = { label = Lang:t('body.right_arm'), causeLimp = false, isDamaged = false, severity = 0 }, ['RHAND'] = { label = Lang:t('body.right_hand'), causeLimp = false, isDamaged = false, severity = 0 }, ['RFINGER'] = { label = Lang:t('body.right_fingers'), causeLimp = false, isDamaged = false, severity = 0 }, ['RLEG'] = { label = Lang:t('body.right_leg'), causeLimp = true, isDamaged = false, severity = 0 }, ['RFOOT'] = { label = Lang:t('body.right_foot'), causeLimp = true, isDamaged = false, severity = 0 }, } -- Functions -- Gets a bed at the given hospital that is not taken. -- If all beds are taken it will just place them in the first bed local function getClosestAvailableBed(hospitalIndex) local hospital = Config.Locations['hospital'][hospitalIndex] -- Loop through beds at this hospital and find the first non taken bed for bedId, bed in pairs(hospital.beds) do local isBedTaken = bed.taken if not isBedTaken then return bedId end end return 1 -- default to the first bed end local function GetDamagingWeapon(ped) for k, v in pairs(Config.Weapons) do if HasPedBeenDamagedByWeapon(ped, k, 0) then return v end end return nil end local function IsDamagingEvent(damageDone, weapon) local luck = math.random(100) local multi = damageDone / Config.HealthDamage return luck < (Config.HealthDamage * multi) or (damageDone >= Config.ForceInjury or multi > Config.MaxInjuryChanceMulti or Config.ForceInjuryWeapons[weapon]) end local function DoLimbAlert() if not isDead and not InLaststand then if #injured > 0 then local limbDamageMsg = '' if #injured <= Config.AlertShowInfo then for k, v in pairs(injured) do limbDamageMsg = limbDamageMsg .. Lang:t('info.pain_message', { limb = v.label, severity = Config.WoundStates[v.severity] }) if k < #injured then limbDamageMsg = limbDamageMsg .. ' | ' end end else limbDamageMsg = Lang:t('info.many_places') end QBCore.Functions.Notify(limbDamageMsg, 'primary') end end end local function DoBleedAlert() if not isDead and tonumber(isBleeding) > 0 then QBCore.Functions.Notify(Lang:t('info.bleed_alert', { bleedstate = Config.BleedingStates[tonumber(isBleeding)].label }), 'error') end end local function ApplyBleed(level) if isBleeding ~= 4 then if isBleeding + level > 4 then isBleeding = 4 else isBleeding = isBleeding + level end DoBleedAlert() end end local function IsInjuryCausingLimp() for _, v in pairs(BodyParts) do if v.causeLimp and v.isDamaged then return true end end return false end local function ProcessRunStuff(ped) if IsInjuryCausingLimp() then RequestAnimSet('move_m@injured') while not HasAnimSetLoaded('move_m@injured') do Wait(0) end SetPedMovementClipset(ped, 'move_m@injured', 1) SetPlayerSprint(PlayerId(), false) end end function ResetPartial() for _, v in pairs(BodyParts) do if v.isDamaged and v.severity <= 2 then v.isDamaged = false v.severity = 0 end end for k, v in pairs(injured) do if v.severity <= 2 then v.severity = 0 table.remove(injured, k) end end if isBleeding <= 2 then isBleeding = 0 bleedTickTimer = 0 advanceBleedTimer = 0 fadeOutTimer = 0 blackoutTimer = 0 end TriggerServerEvent('hospital:server:SyncInjuries', { limbs = BodyParts, isBleeding = tonumber(isBleeding) }) ProcessRunStuff(PlayerPedId()) DoLimbAlert() DoBleedAlert() TriggerServerEvent('hospital:server:SyncInjuries', { limbs = BodyParts, isBleeding = tonumber(isBleeding) }) end local function ResetAll() isBleeding = 0 bleedTickTimer = 0 advanceBleedTimer = 0 fadeOutTimer = 0 blackoutTimer = 0 onDrugs = 0 wasOnDrugs = false onPainKiller = 0 wasOnPainKillers = false injured = {} for _, v in pairs(BodyParts) do v.isDamaged = false v.severity = 0 end TriggerServerEvent('hospital:server:SyncInjuries', { limbs = BodyParts, isBleeding = tonumber(isBleeding) }) CurrentDamageList = {} TriggerServerEvent('hospital:server:SetWeaponDamage', CurrentDamageList) ProcessRunStuff(PlayerPedId()) DoLimbAlert() DoBleedAlert() TriggerServerEvent('hospital:server:SyncInjuries', { limbs = BodyParts, isBleeding = tonumber(isBleeding) }) TriggerServerEvent('hospital:server:resetHungerThirst') end local function loadAnimDict(dict) while (not HasAnimDictLoaded(dict)) do RequestAnimDict(dict) Wait(1) end end local function SetBedCam() isInHospitalBed = true canLeaveBed = false local player = PlayerPedId() DoScreenFadeOut(1000) while not IsScreenFadedOut() do Wait(100) end if IsPedDeadOrDying(player) then local pos = GetEntityCoords(player, true) NetworkResurrectLocalPlayer(pos.x, pos.y, pos.z, GetEntityHeading(player), true, false) end bedObject = GetClosestObjectOfType(bedOccupyingData.coords.x, bedOccupyingData.coords.y, bedOccupyingData.coords.z, 1.0, bedOccupyingData.model, false, false, false) FreezeEntityPosition(bedObject, true) SetEntityCoords(player, bedOccupyingData.coords.x, bedOccupyingData.coords.y, bedOccupyingData.coords.z + 0.02) Wait(500) FreezeEntityPosition(player, true) loadAnimDict(inBedDict) TaskPlayAnim(player, inBedDict, inBedAnim, 8.0, 1.0, -1, 1, 0, 0, 0, 0) SetEntityHeading(player, bedOccupyingData.coords.w) cam = CreateCam('DEFAULT_SCRIPTED_CAMERA', 1) SetCamActive(cam, true) RenderScriptCams(true, false, 1, true, true) AttachCamToPedBone(cam, player, 31085, 0, 1.0, 1.0, true) SetCamFov(cam, 90.0) local heading = GetEntityHeading(player) heading = (heading > 180) and heading - 180 or heading + 180 SetCamRot(cam, -45.0, 0.0, heading, 2) DoScreenFadeIn(1000) Wait(1000) FreezeEntityPosition(player, true) end local function LeaveBed() local player = PlayerPedId() RequestAnimDict(getOutDict) while not HasAnimDictLoaded(getOutDict) do Wait(0) end FreezeEntityPosition(player, false) SetEntityInvincible(player, false) SetEntityHeading(player, bedOccupyingData.coords.w + 90) TaskPlayAnim(player, getOutDict, getOutAnim, 100.0, 1.0, -1, 8, -1, 0, 0, 0) Wait(4000) ClearPedTasks(player) TriggerServerEvent('hospital:server:LeaveBed', bedOccupying, hospitalLocation) FreezeEntityPosition(bedObject, true) RenderScriptCams(0, true, 200, true, true) DestroyCam(cam, false) bedOccupying = nil bedObject = nil bedOccupyingData = nil isInHospitalBed = false QBCore.Functions.GetPlayerData(function(PlayerData) if PlayerData.metadata['injail'] > 0 then TriggerEvent('prison:client:Enter', PlayerData.metadata['injail']) end end) end local function IsInDamageList(damage) local retval = false if CurrentDamageList then for k, _ in pairs(CurrentDamageList) do if CurrentDamageList[k] == damage then retval = true end end end return retval end local function CheckWeaponDamage(ped) local detected = false for k, v in pairs(QBCore.Shared.Weapons) do if HasPedBeenDamagedByWeapon(ped, k, 0) then detected = true if not IsInDamageList(k) then -- TriggerEvent('chat:addMessage', { -- color = { 255, 0, 0 }, -- multiline = false, -- args = { Lang:t('info.status'), v.damagereason } -- }) CurrentDamageList[#CurrentDamageList + 1] = k end end end if detected then TriggerServerEvent('hospital:server:SetWeaponDamage', CurrentDamageList) end ClearEntityLastDamageEntity(ped) end local function ApplyImmediateEffects(ped, bone, weapon, damageDone) local armor = GetPedArmour(ped) if Config.MinorInjurWeapons[weapon] and damageDone < Config.DamageMinorToMajor then if Config.CriticalAreas[Config.Bones[bone]] then if armor <= 0 then ApplyBleed(1) end end if Config.StaggerAreas[Config.Bones[bone]] and (Config.StaggerAreas[Config.Bones[bone]].armored or armor <= 0) then if math.random(100) <= math.ceil(Config.StaggerAreas[Config.Bones[bone]].minor) then SetPedToRagdoll(ped, 1500, 2000, 3, true, true, false) end end elseif Config.MajorInjurWeapons[weapon] or (Config.MinorInjurWeapons[weapon] and damageDone >= Config.DamageMinorToMajor) then if Config.CriticalAreas[Config.Bones[bone]] then if armor > 0 and Config.CriticalAreas[Config.Bones[bone]].armored then if math.random(100) <= math.ceil(Config.MajorArmoredBleedChance) then ApplyBleed(1) end else ApplyBleed(1) end else if armor > 0 then if math.random(100) < (Config.MajorArmoredBleedChance) then ApplyBleed(1) end else if math.random(100) < (Config.MajorArmoredBleedChance * 2) then ApplyBleed(1) end end end if Config.StaggerAreas[Config.Bones[bone]] and (Config.StaggerAreas[Config.Bones[bone]].armored or armor <= 0) then if math.random(100) <= math.ceil(Config.StaggerAreas[Config.Bones[bone]].major) then SetPedToRagdoll(ped, 1500, 2000, 3, true, true, false) end end end end local function CheckDamage(ped, bone, weapon, damageDone) if weapon == nil then return end if Config.Bones[bone] and not isDead and not InLaststand then ApplyImmediateEffects(ped, bone, weapon, damageDone) if not BodyParts[Config.Bones[bone]].isDamaged then BodyParts[Config.Bones[bone]].isDamaged = true BodyParts[Config.Bones[bone]].severity = math.random(1, 3) injured[#injured + 1] = { part = Config.Bones[bone], label = BodyParts[Config.Bones[bone]].label, severity = BodyParts[Config.Bones[bone]].severity } else if BodyParts[Config.Bones[bone]].severity < 4 then BodyParts[Config.Bones[bone]].severity = BodyParts[Config.Bones[bone]].severity + 1 for _, v in pairs(injured) do if v.part == Config.Bones[bone] then v.severity = BodyParts[Config.Bones[bone]].severity end end end end TriggerServerEvent('hospital:server:SyncInjuries', { limbs = BodyParts, isBleeding = tonumber(isBleeding) }) ProcessRunStuff(ped) end end local function ProcessDamage(ped) if not isDead and not InLaststand and not onPainKillers then for _, v in pairs(injured) do if (v.part == 'LLEG' and v.severity > 1) or (v.part == 'RLEG' and v.severity > 1) or (v.part == 'LFOOT' and v.severity > 2) or (v.part == 'RFOOT' and v.severity > 2) then if legCount >= Config.LegInjuryTimer then if not IsPedRagdoll(ped) and IsPedOnFoot(ped) then local chance = math.random(100) if (IsPedRunning(ped) or IsPedSprinting(ped)) then if chance <= Config.LegInjuryChance.Running then ShakeGameplayCam('SMALL_EXPLOSION_SHAKE', 0.08) -- change this float to increase/decrease camera shake SetPedToRagdollWithFall(ped, 1500, 2000, 1, GetEntityForwardVector(ped), 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) end else if chance <= Config.LegInjuryChance.Walking then ShakeGameplayCam('SMALL_EXPLOSION_SHAKE', 0.08) -- change this float to increase/decrease camera shake SetPedToRagdollWithFall(ped, 1500, 2000, 1, GetEntityForwardVector(ped), 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) end end end legCount = 0 else legCount = legCount + 1 end elseif (v.part == 'LARM' and v.severity > 1) or (v.part == 'LHAND' and v.severity > 1) or (v.part == 'LFINGER' and v.severity > 2) or (v.part == 'RARM' and v.severity > 1) or (v.part == 'RHAND' and v.severity > 1) or (v.part == 'RFINGER' and v.severity > 2) then if armcount >= Config.ArmInjuryTimer then if (v.part == 'LARM' and v.severity > 1) or (v.part == 'LHAND' and v.severity > 1) or (v.part == 'LFINGER' and v.severity > 2) then local isDisabled = 15 CreateThread(function() while isDisabled > 0 do if IsPedInAnyVehicle(ped, true) then DisableControlAction(0, 63, true) -- veh turn left end if IsPlayerFreeAiming(PlayerId()) then DisablePlayerFiring(PlayerId(), true) -- Disable weapon firing end isDisabled = isDisabled - 1 Wait(1) end end) else local isDisabled = 15 CreateThread(function() while isDisabled > 0 do if IsPedInAnyVehicle(ped, true) then DisableControlAction(0, 63, true) -- veh turn left end if IsPlayerFreeAiming(PlayerId()) then DisableControlAction(0, 25, true) -- Disable weapon firing end isDisabled = isDisabled - 1 Wait(1) end end) end armcount = 0 else armcount = armcount + 1 end elseif (v.part == 'HEAD' and v.severity > 2) then if headCount >= Config.HeadInjuryTimer then local chance = math.random(100) if chance <= Config.HeadInjuryChance then SetFlash(0, 0, 100, 10000, 100) DoScreenFadeOut(100) while not IsScreenFadedOut() do Wait(0) end if not IsPedRagdoll(ped) and IsPedOnFoot(ped) and not IsPedSwimming(ped) then ShakeGameplayCam('SMALL_EXPLOSION_SHAKE', 0.08) -- change this float to increase/decrease camera shake SetPedToRagdoll(ped, 5000, 1, 2) end Wait(5000) DoScreenFadeIn(250) end headCount = 0 else headCount = headCount + 1 end end end end end -- Events RegisterNetEvent('hospital:client:ambulanceAlert', function(coords, text) local street1, street2 = GetStreetNameAtCoord(coords.x, coords.y, coords.z) local street1name = GetStreetNameFromHashKey(street1) local street2name = GetStreetNameFromHashKey(street2) QBCore.Functions.Notify({ text = text, caption = street1name .. ' ' .. street2name }, 'ambulance') PlaySound(-1, 'Lose_1st', 'GTAO_FM_Events_Soundset', 0, 0, 1) local transG = 250 local blip = AddBlipForCoord(coords.x, coords.y, coords.z) local blip2 = AddBlipForCoord(coords.x, coords.y, coords.z) local blipText = Lang:t('info.ems_alert', { text = text }) SetBlipSprite(blip, 153) SetBlipSprite(blip2, 161) SetBlipColour(blip, 1) SetBlipColour(blip2, 1) SetBlipDisplay(blip, 4) SetBlipDisplay(blip2, 8) SetBlipAlpha(blip, transG) SetBlipAlpha(blip2, transG) SetBlipScale(blip, 0.8) SetBlipScale(blip2, 2.0) SetBlipAsShortRange(blip, false) SetBlipAsShortRange(blip2, false) PulseBlip(blip2) BeginTextCommandSetBlipName('STRING') AddTextComponentSubstringPlayerName(blipText) EndTextCommandSetBlipName(blip) while transG ~= 0 do Wait(180 * 4) transG = transG - 1 SetBlipAlpha(blip, transG) SetBlipAlpha(blip2, transG) if transG == 0 then RemoveBlip(blip) return end end end) RegisterNetEvent('hospital:client:Revive', function() local player = PlayerPedId() if isDead or InLaststand then local pos = GetEntityCoords(player, true) NetworkResurrectLocalPlayer(pos.x, pos.y, pos.z, GetEntityHeading(player), true, false) isDead = false SetEntityInvincible(player, false) SetLaststand(false) end if isInHospitalBed then loadAnimDict(inBedDict) TaskPlayAnim(player, inBedDict, inBedAnim, 8.0, 1.0, -1, 1, 0, 0, 0, 0) SetEntityInvincible(player, true) canLeaveBed = true end TriggerServerEvent('hospital:server:RestoreWeaponDamage') SetEntityMaxHealth(player, 200) SetEntityHealth(player, 200) ClearPedBloodDamage(player) SetPlayerSprint(PlayerId(), true) ResetAll() ResetPedMovementClipset(player, 0.0) TriggerServerEvent('hud:server:RelieveStress', 100) TriggerServerEvent('hospital:server:SetDeathStatus', false) TriggerServerEvent('hospital:server:SetLaststandStatus', false) emsNotified = false QBCore.Functions.Notify(Lang:t('info.healthy')) TriggerEvent('majestic-deathscreen:revive') end) RegisterNetEvent('hospital:client:SetPain', function() ApplyBleed(math.random(1, 4)) if not BodyParts[Config.Bones[24816]].isDamaged then BodyParts[Config.Bones[24816]].isDamaged = true BodyParts[Config.Bones[24816]].severity = math.random(1, 4) injured[#injured + 1] = { part = Config.Bones[24816], label = BodyParts[Config.Bones[24816]].label, severity = BodyParts[Config.Bones[24816]].severity } end if not BodyParts[Config.Bones[40269]].isDamaged then BodyParts[Config.Bones[40269]].isDamaged = true BodyParts[Config.Bones[40269]].severity = math.random(1, 4) injured[#injured + 1] = { part = Config.Bones[40269], label = BodyParts[Config.Bones[40269]].label, severity = BodyParts[Config.Bones[40269]].severity } end TriggerServerEvent('hospital:server:SyncInjuries', { limbs = BodyParts, isBleeding = tonumber(isBleeding) }) end) RegisterNetEvent('hospital:client:KillPlayer', function() SetEntityHealth(PlayerPedId(), 0) end) RegisterNetEvent('hospital:client:HealInjuries', function(type) if type == 'full' then ResetAll() else ResetPartial() end TriggerServerEvent('hospital:server:RestoreWeaponDamage') QBCore.Functions.Notify(Lang:t('success.wounds_healed'), 'success') end) RegisterNetEvent('hospital:client:SendToBed', function(id, data, isRevive) bedOccupying = id bedOccupyingData = data SetBedCam() CreateThread(function() Wait(5) if isRevive then QBCore.Functions.Notify(Lang:t('success.being_helped'), 'success') Wait(Config.AIHealTimer * 1000) TriggerEvent('hospital:client:Revive') else canLeaveBed = true end end) end) RegisterNetEvent('hospital:client:SetBed', function(id, isTaken, hospitalIndex) Config.Locations['hospital'][hospitalIndex]['beds'][id].taken = isTaken hospitalLocation = hospitalIndex end) RegisterNetEvent('hospital:client:SetBed2', function(id, isTaken) Config.Locations['jailbeds'][id].taken = isTaken end) RegisterNetEvent('hospital:client:RespawnAtHospital', function() local hospitalIndex = 1 -- Default hospital to respawn at TriggerEvent('majestic-deathscreen:revive') TriggerServerEvent('hospital:server:RespawnAtHospital', hospitalIndex) if exports['qb-policejob']:IsHandcuffed() then TriggerEvent('police:client:GetCuffed', -1) end TriggerEvent('police:client:DeEscort') end) RegisterNetEvent('hospital:client:SendBillEmail', function(amount, hospitalName) SetTimeout(math.random(2500, 4000), function() local gender = Lang:t('info.mr') if QBCore.Functions.GetPlayerData().charinfo.gender == 1 then gender = Lang:t('info.mrs') end local charinfo = QBCore.Functions.GetPlayerData().charinfo TriggerServerEvent('qb-phone:server:sendNewMail', { sender = hospitalName, subject = Lang:t('mail.subject'), message = Lang:t('mail.message', { gender = gender, lastname = charinfo.lastname, costs = amount }), button = {} }) end) end) RegisterNetEvent('hospital:client:SetDoctorCount', function(amount) doctorCount = amount end) RegisterNetEvent('hospital:client:adminHeal', function() local ped = PlayerPedId() SetEntityHealth(ped, 200) TriggerServerEvent('hospital:server:resetHungerThirst') end) RegisterNetEvent('QBCore:Client:OnPlayerUnload', function() local ped = PlayerPedId() TriggerServerEvent('hospital:server:SetDeathStatus', false) TriggerServerEvent('hospital:server:SetLaststandStatus', false) TriggerServerEvent('hospital:server:SetArmor', GetPedArmour(ped)) if bedOccupying then TriggerServerEvent('hospital:server:LeaveBed', bedOccupying, hospitalLocation) end isDead = false deathTime = 0 SetEntityInvincible(ped, false) SetPedArmour(ped, 0) ResetAll() end) -- Threads CreateThread(function() for i = 1, #Config.Locations['stations'] do local station = Config.Locations['stations'][i] local blip = AddBlipForCoord(station.coords.x, station.coords.y, station.coords.z) SetBlipSprite(blip, 61) SetBlipAsShortRange(blip, true) SetBlipScale(blip, 0.8) SetBlipColour(blip, 25) BeginTextCommandSetBlipName('STRING') AddTextComponentSubstringPlayerName(station.label) EndTextCommandSetBlipName(blip) end end) CreateThread(function() while true do local sleep = 1000 if isInHospitalBed and canLeaveBed then sleep = 0 LeaveBed() end Wait(sleep) end end) CreateThread(function() while true do Wait((1000 * Config.MessageTimer)) DoLimbAlert() end end) CreateThread(function() while true do Wait(1000) if isStatusChecking then statusCheckTime = statusCheckTime - 1 if statusCheckTime <= 0 then statusChecks = {} isStatusChecking = false end end end end) CreateThread(function() while true do local ped = PlayerPedId() local health = GetEntityHealth(ped) local armor = GetPedArmour(ped) if not playerHealth then playerHealth = health end if not playerArmor then playerArmor = armor end local armorDamaged = (playerArmor ~= armor and armor < (playerArmor - Config.ArmorDamage) and armor > 0) -- Players armor was damaged local healthDamaged = (playerHealth ~= health) -- Players health was damaged local damageDone = (playerHealth - health) if armorDamaged or healthDamaged then local hit, bone = GetPedLastDamageBone(ped) local bodypart = Config.Bones[bone] local weapon = GetDamagingWeapon(ped) if hit and bodypart ~= 'NONE' then local checkDamage = true if damageDone >= Config.HealthDamage then if weapon then if armorDamaged and (bodypart == 'SPINE' or bodypart == 'UPPER_BODY') or weapon == Config.WeaponClasses['NOTHING'] then checkDamage = false -- Don't check damage if the it was a body shot and the weapon class isn't that strong if armorDamaged then TriggerServerEvent('hospital:server:SetArmor', GetPedArmour(ped)) end end if checkDamage then if IsDamagingEvent(damageDone, weapon) then CheckDamage(ped, bone, weapon, damageDone) end end end elseif Config.AlwaysBleedChanceWeapons[weapon] then if armorDamaged and (bodypart == 'SPINE' or bodypart == 'UPPER_BODY') or weapon == Config.WeaponClasses['NOTHING'] then checkDamage = false -- Don't check damage if the it was a body shot and the weapon class isn't that strong end if math.random(100) < Config.AlwaysBleedChance and checkDamage then ApplyBleed(1) end end end CheckWeaponDamage(ped) end playerHealth = health playerArmor = armor if not isInHospitalBed then ProcessDamage(ped) end Wait(100) end end) local listen = false -- variable - 'checkin' or 'beds' -- hospitalIndex - index referring to the key of the hospital key/value pairs local function CheckInControls(variable, hospitalIndex, bedId) CreateThread(function() listen = true while listen do if IsControlJustPressed(0, 38) then exports['qb-core']:KeyPressed(38) if variable == 'checkin' then TriggerEvent('qb-ambulancejob:checkin') listen = false elseif variable == 'beds' then TriggerEvent('qb-ambulancejob:beds', hospitalIndex, bedId) listen = false end end Wait(1) end end) end RegisterNetEvent('qb-ambulancejob:checkin', function() local coords = GetEntityCoords(PlayerPedId()) for i = 1, #Config.Locations['hospital'] do local hospital = vector3(Config.Locations['hospital'][i]['location'].x, Config.Locations['hospital'][i]['location'].y, Config.Locations['hospital'][i]['location'].z) local distance = #(coords - hospital) if distance < 3 then if doctorCount >= Config.MinimalDoctors then --TriggerServerEvent('hospital:server:SendDoctorAlert', Config.Locations['hospital'][i]['name']) exports['ps-dispatch']:DeceasedPerson() QBCore.Functions.Notify('Called a Doctor', 'primary') else TriggerEvent('animations:client:EmoteCommandStart', { 'notepad' }) QBCore.Functions.Progressbar('hospital_checkin', Lang:t('progress.checking_in'), 2000, false, true, { disableMovement = true, disableCarMovement = true, disableMouse = false, disableCombat = true, }, { animDict = 'missheistdockssetup1clipboard@base', anim = 'base', flags = 33, }, { model = 'prop_notepad_01', bone = 18905, coords = { x = 0.1, y = 0.02, z = 0.05 }, rotation = { x = 10.0, y = 0.0, z = 0.0 }, }, { model = 'prop_pencil_01', bone = 58866, coords = { x = 0.11, y = -0.02, z = 0.001 }, rotation = { x = -120.0, y = 0.0, z = 0.0 }, }, function() -- Done TriggerEvent('animations:client:EmoteCommandStart', { 'c' }) local bedId = getClosestAvailableBed(i) if bedId then TriggerServerEvent('hospital:server:SendToBed', bedId, true, i) hospitalLocation = i else QBCore.Functions.Notify(Lang:t('error.beds_taken'), 'error') end end) end end end end) RegisterNetEvent('qb-ambulancejob:beds', function(hospitalIndex, bedId) if bedId then TriggerServerEvent('hospital:server:SendToBed', bedId, false, hospitalIndex) hospitalLocation = hospitalIndex else QBCore.Functions.Notify(Lang:t('error.beds_taken'), 'error') end end) -- Convar turns into a boolean if Config.UseTarget then CreateThread(function() for i = 1, #Config.Locations['checking'] do local v = Config.Locations['checking'][i] local v = Config.Locations['checking'][i] exports.interact:AddInteraction({ coords = vector3(v.x, v.y, v.z), distance = 8.0, -- optional interactDst = 2.0, -- optional id = 'checking' .. i, -- needed for removing interactions name = 'checking' .. i, -- optional options = { { label = 'Check In', action = function(entity, coords, args) TriggerEvent("qb-ambulancejob:checkin") end, }, } }) end --[[for hospitalKey = 1, #Config.Locations['hospital'] do for bedKey = 1, #Config.Locations['hospital'][hospitalKey]['beds'] do local v = Config.Locations['hospital'][hospitalKey]['beds'][bedKey] exports['qb-target']:AddBoxZone('beds' .. bedKey, v.coords, 2.5, 2.3, { name = 'beds' .. bedKey .. Config.Locations['hospital'][hospitalKey]['name'], heading = -20, debugPoly = false, minZ = v.coords.z - 0.3, maxZ = v.coords.z + 0.3, }, { options = { { type = 'client', event = 'qb-ambulancejob:beds', icon = 'fas fa-bed', label = 'Layin Bed', } }, distance = 1.5 }) end end--]] end) else CreateThread(function() local checkingPoly = {} for i = 1, #Config.Locations['checking'] do local v = Config.Locations['checking'][i] checkingPoly[#checkingPoly + 1] = BoxZone:Create(vector3(v.x, v.y, v.z), 3.5, 2, { heading = -72, name = 'checkin' .. i, debugPoly = false, minZ = v.z - 2, maxZ = v.z + 2, }) local checkingCombo = ComboZone:Create(checkingPoly, { name = 'checkingCombo', debugPoly = false }) checkingCombo:onPlayerInOut(function(isPointInside) if isPointInside then if doctorCount >= Config.MinimalDoctors then exports['qb-core']:DrawText(Lang:t('text.call_doc'), 'left') CheckInControls('checkin') else exports['qb-core']:DrawText(Lang:t('text.check_in'), 'left') CheckInControls('checkin') end else listen = false exports['qb-core']:HideText() end end) end local bedPoly = {} for hospitalKey = 1, #Config.Locations['hospital'] do for bedKey = 1, #Config.Locations['hospital'][hospitalKey]['beds'] do local v = Config.Locations['hospital'][hospitalKey]['beds'][bedKey] bedPoly[#bedPoly + 1] = BoxZone:Create(v.coords, 2.5, 2.3, { name = 'beds' .. bedKey .. Config.Locations['hospital'][hospitalKey]['name'], heading = -20, debugPoly = false, minZ = v.coords.z - 1, maxZ = v.coords.z + 1, data = { bedId = bedKey }, }) local bedCombo = ComboZone:Create(bedPoly, { name = 'bedCombo', debugPoly = false }) bedCombo:onPlayerInOut(function(isPointInside, _, zone) if isPointInside and not isInHospitalBed then exports['qb-core']:DrawText(Lang:t('text.lie_bed'), 'left') local bedId = zone.data.bedId CheckInControls('beds', hospitalKey, bedId) else listen = false exports['qb-core']:HideText() end end) end end end) end