>
Tutorial 2026-04-13

Desenvolvimento do Sistema de Hospital e EMS em FiveM

TDYSKY

TDYSKY

Fundador & Lead Developer na Agency Scripts

Arquitetura de Sistema Hospitalar

Um sistema hospitalar e EMS transforma a forma como os jogadores vivenciam a saúde e as lesões em um servidor de roleplay FiveM. Em vez de simplesmente reaparecer após serem abatidos, os jogadores entram em um pipeline de roleplay médico onde podem ser estabilizados pelo EMS no campo, transportados por ambulância, internados no hospital, diagnosticados, tratados e cobrados pelos serviços. A arquitetura do sistema se divide em quatro camadas interconectadas: o sistema de lesões que rastreia o que aconteceu ao jogador e onde está seu corpo, as ferramentas de envio do EMS e resposta de campo, o fluxo de trabalho de check-in e tratamento do hospital e o sistema de cobrança que conecta os cuidados médicos à economia do servidor. Cada camada se comunica por meio de eventos do servidor para que o médico que trata um paciente possa ver exatamente quais lesões o atendente do EMS já documentou durante a triagem de campo. Construir isso como um sistema unificado, em vez de scripts separados, garante que os dados do paciente fluam perfeitamente desde o momento em que alguém liga para o 911 até o momento em que sai do hospital com uma conta em mãos.

Sistema de tipo de lesão

Um sistema detalhado de lesões substitui o estado binário de vivo ou morto por um espectro de condições que requerem tratamentos diferentes. Rastreie lesões por região do corpo, gravidade e causa para que o EMS e os médicos possam interpretar cenários médicos realistas. Quando um jogador sofre dano, determine o tipo de lesão com base na arma ou no hash da causa da morte e aplique-o na região apropriada do corpo. Os ferimentos de bala no tronco são mais graves do que um soco no braço, e cada tipo de lesão tem requisitos de tratamento específicos que os médicos devem seguir:

Config.InjuryTypes = {
    gunshot = {
        label = 'Gunshot Wound',
        severity = { min = 60, max = 100 },
        bleedRate = 2.5,
        treatments = {'clean_wound', 'remove_bullet', 'stitch', 'bandage'},
        requiredItems = {'tweezers', 'suture_kit', 'bandage'},
        healTime = 120,
    },
    stabbing = {
        label = 'Stab Wound',
        severity = { min = 40, max = 80 },
        bleedRate = 1.8,
        treatments = {'clean_wound', 'stitch', 'bandage'},
        requiredItems = {'suture_kit', 'bandage'},
        healTime = 90,
    },
    blunt = {
        label = 'Blunt Force Trauma',
        severity = { min = 20, max = 60 },
        bleedRate = 0.5,
        treatments = {'examine', 'ice_pack', 'painkillers'},
        requiredItems = {'ice_pack', 'painkillers'},
        healTime = 60,
    },
    burn = {
        label = 'Burn Injury',
        severity = { min = 30, max = 90 },
        bleedRate = 0,
        treatments = {'cool_burn', 'apply_cream', 'bandage'},
        requiredItems = {'burn_cream', 'bandage'},
        healTime = 100,
    },
    fracture = {
        label = 'Bone Fracture',
        severity = { min = 50, max = 70 },
        bleedRate = 0,
        treatments = {'x_ray', 'set_bone', 'apply_cast'},
        requiredItems = {'splint', 'cast_material'},
        healTime = 180,
    },
    vehicle_crash = {
        label = 'Vehicle Collision Injury',
        severity = { min = 30, max = 95 },
        bleedRate = 1.0,
        treatments = {'examine', 'clean_wound', 'stitch', 'bandage', 'painkillers'},
        requiredItems = {'suture_kit', 'bandage', 'painkillers'},
        healTime = 110,
    },
}

Config.BodyRegions = {
    'head', 'torso', 'left_arm', 'right_arm', 'left_leg', 'right_leg'
}

-- Severity multipliers per body region
Config.RegionMultipliers = {
    head = 1.5,
    torso = 1.3,
    left_arm = 0.8,
    right_arm = 0.8,
    left_leg = 0.9,
    right_leg = 0.9,
}

Envio EMS e resposta em campo

O sistema de despacho EMS conecta jogadores abatidos com equipes médicas de plantão. Quando um jogador entra no estado abatido, ele pode optar por ligar para o 911, que cria um alerta de despacho visível para todo o pessoal do EMS em serviço. O alerta inclui as coordenadas GPS do chamador, uma breve descrição gerada a partir dos dados da lesão e um nível de prioridade baseado na gravidade da lesão. Os atendentes do EMS podem aceitar a chamada por meio de uma interface de despacho, que marca a chamada como reivindicada e fornece navegação GPS ao paciente. Implemente um cronômetro de resposta que rastreie quanto tempo cada chamada leva desde a criação até o contato com o paciente, útil para monitorar o desempenho do EMS e ajustar os requisitos de pessoal. O tratamento de campo é uma versão simplificada do tratamento hospitalar onde o EMS pode estabilizar os pacientes usando suprimentos básicos como bandagens, torniquetes e injeções de adrenalina para evitar a morte durante o transporte:

-- Server-side dispatch handler
local activeDispatches = {}

RegisterNetEvent('hospital:server:call911', function(description)
    local src = source
    local Player = QBCore.Functions.GetPlayer(src)
    if not Player then return end

    local ped = GetPlayerPed(src)
    local coords = GetEntityCoords(ped)
    local injuries = Player.Functions.GetMetaData('injuries') or {}

    -- Determine priority from injury severity
    local maxSeverity = 0
    for _, injury in ipairs(injuries) do
        if injury.severity > maxSeverity then
            maxSeverity = injury.severity
        end
    end

    local priority = maxSeverity >= 80 and 'CRITICAL' or maxSeverity >= 50 and 'URGENT' or 'STANDARD'

    local dispatch = {
        id = #activeDispatches + 1,
        callerId = src,
        citizenid = Player.PlayerData.citizenid,
        callerName = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname,
        coords = { x = coords.x, y = coords.y, z = coords.z },
        description = description or GenerateInjuryDescription(injuries),
        priority = priority,
        injuries = injuries,
        timestamp = os.time(),
        status = 'pending',
        responderId = nil,
    }

    table.insert(activeDispatches, dispatch)

    -- Notify all on-duty EMS
    local emsPlayers = QBCore.Functions.GetQBPlayers()
    for _, emsPlayer in pairs(emsPlayers) do
        if emsPlayer.PlayerData.job.name == 'ambulance' and emsPlayer.PlayerData.job.onduty then
            TriggerClientEvent('hospital:client:newDispatch', emsPlayer.PlayerData.source, dispatch)
        end
    end
end)

RegisterNetEvent('hospital:server:acceptDispatch', function(dispatchId)
    local src = source
    local Player = QBCore.Functions.GetPlayer(src)
    if not Player or Player.PlayerData.job.name ~= 'ambulance' then return end

    for i, dispatch in ipairs(activeDispatches) do
        if dispatch.id == dispatchId and dispatch.status == 'pending' then
            dispatch.status = 'responding'
            dispatch.responderId = src
            dispatch.responseTime = os.time()

            -- Notify caller
            TriggerClientEvent('QBCore:Notify', dispatch.callerId, 'EMS is on the way!', 'success')
            -- Set GPS blip for responder
            TriggerClientEvent('hospital:client:setDispatchGPS', src, dispatch.coords)
            break
        end
    end
end)

IU de check-in e tratamento hospitalar

O sistema de check-in do hospital gerencia o fluxo de pacientes desde a chegada até a alta. Quando um atendente do EMS traz um paciente ao hospital ou um jogador entra sozinho, ele interage com um NPC da recepção ou ponto de destino para fazer o check-in. O processo de check-in cria um registro do paciente que inclui seus ferimentos atuais, sinais vitais e um ID de visita exclusivo para fins de cobrança. Os médicos de plantão atendem os pacientes que chegam em um painel NUI de gerenciamento hospitalar que exibe a fila da sala de espera, a prioridade de triagem de cada paciente e seus ferimentos documentados. Quando um médico seleciona um paciente, a IU de tratamento é aberta mostrando o diagrama corporal do paciente com locais de lesões destacados. O médico clica em cada lesão para ver as etapas necessárias do tratamento e pode executar cada etapa em sequência, acionando animações e consumindo suprimentos médicos de seu inventário. Cada etapa do tratamento possui uma barra de progresso e uma verificação de sucesso que depende dos metadados de habilidade do médico, adicionando um elemento de progressão ao roleplay médico.

Fluxo de trabalho de tratamento

Projete o fluxo de trabalho do tratamento como um processo passo a passo em que cada lesão requer ações específicas executadas em ordem. Um ferimento de bala no tronco pode exigir limpeza do ferimento, extração da bala com uma pinça, sutura do ferimento com um kit de sutura e aplicação de um curativo. Cada etapa consome o item apropriado do inventário do médico e reproduz uma animação de tratamento. Pular etapas ou executá-las fora de ordem pode falhar ou reduzir a eficácia, incentivando a dramatização médica adequada. Depois de todas as lesões serem tratadas, o paciente entra num período de recuperação onde a sua saúde se regenera gradualmente ao longo do tempo, em vez de ser restaurada instantaneamente:

RegisterNetEvent('hospital:server:treatInjury', function(patientId, injuryIndex, treatmentStep)
    local src = source
    local Doctor = QBCore.Functions.GetPlayer(src)
    local Patient = QBCore.Functions.GetPlayer(patientId)

    if not Doctor or not Patient then return end
    if Doctor.PlayerData.job.name ~= 'ambulance' or not Doctor.PlayerData.job.onduty then
        TriggerClientEvent('QBCore:Notify', src, 'You must be on duty', 'error')
        return
    end

    local injuries = Patient.Functions.GetMetaData('injuries') or {}
    local injury = injuries[injuryIndex]
    if not injury then return end

    local injuryConfig = Config.InjuryTypes[injury.type]
    if not injuryConfig then return end

    -- Validate treatment step order
    local expectedStep = injury.currentStep or 1
    if treatmentStep ~= expectedStep then
        TriggerClientEvent('QBCore:Notify', src, 'Complete previous treatment steps first', 'error')
        return
    end

    local stepName = injuryConfig.treatments[treatmentStep]
    if not stepName then return end

    -- Check required item
    local requiredItem = Config.TreatmentItems[stepName]
    if requiredItem then
        local hasItem = Doctor.Functions.GetItemByName(requiredItem.name)
        if not hasItem or hasItem.amount < 1 then
            TriggerClientEvent('QBCore:Notify', src, 'Missing: ' .. requiredItem.label, 'error')
            return
        end
        Doctor.Functions.RemoveItem(requiredItem.name, 1)
    end

    -- Apply treatment
    injury.currentStep = treatmentStep + 1
    injury.treated = treatmentStep >= #injuryConfig.treatments

    if injury.treated then
        injury.bleedRate = 0
        injury.healStartTime = os.time()
    end

    injuries[injuryIndex] = injury
    Patient.Functions.SetMetaData('injuries', injuries)

    -- Notify both parties
    TriggerClientEvent('QBCore:Notify', src, 'Treatment step complete: ' .. stepName, 'success')
    TriggerClientEvent('QBCore:Notify', patientId, 'You received treatment: ' .. stepName, 'success')
    TriggerClientEvent('hospital:client:updateInjuries', patientId, injuries)
end)

Sistema de serviço e fora de serviço

O sistema de plantão controla quando o EMS e a equipe do hospital estão ativos e qualificados para receber chamadas de despacho. Quando um jogador com o trabalho de ambulância chega a um ponto de serviço dentro do hospital, ele obtém acesso a comandos médicos, recebe notificações de envio e aparece na lista ativa do EMS, visível para outros funcionários. O sistema de plantão deve rastrear os horários de entrada e saída para cálculos da folha de pagamento se o seu servidor usar pagamentos automáticos de salário. Implemente diferentes funções dentro do trabalho do EMS, como paramédico, médico e cirurgião, onde cada função tem acesso a diferentes capacidades de tratamento. Um paramédico pode realizar estabilização de campo e tratamentos básicos, um médico pode lidar com procedimentos hospitalares padrão e um cirurgião pode realizar operações complexas, como extração de bala e fixação de ossos. Armazene a lista de serviço em um estado de servidor compartilhado para que o sistema de despacho possa contar com precisão os respondentes disponíveis e ajustar o cronômetro de reaparecimento automático para jogadores abatidos com base na disponibilidade do EMS.

Sistema de faturamento médico

O faturamento médico conecta o sistema hospitalar à economia do servidor e cria uma consequência financeira para comportamentos de risco. Quando um paciente é tratado, o sistema gera uma fatura detalhada que lista cada tratamento realizado, os suprimentos consumidos e quaisquer taxas de instalação. As contas podem ser pagas na finalização da compra na recepção, debitadas diretamente na conta bancária do paciente ou enviadas em forma de fatura que o paciente deverá pagar em prazo determinado. Implementar um sistema de seguro médico onde os jogadores possam adquirir apólices de seguro que cubram uma porcentagem de seus custos médicos, reduzindo o impacto financeiro de visitas frequentes ao hospital. Os prêmios de seguro podem ser uma cobrança recorrente que aumenta a simulação econômica do servidor. Para jogadores que não podem pagar, implemente um sistema de dívida médica em que as contas não pagas acumulem juros e eventualmente desencadeiem consequências como penhora de salários de contracheques de trabalho ou acesso restrito a determinados serviços até que a dívida seja saldada. Armazene todos os registros de cobrança para revisão administrativa e conecte-os ao sistema de registro de transações para que o fluxo de dinheiro do paciente ao hospital possa ser auditado.

Veículo e equipamento ambulância

O veículo ambulância deve ser mais do que apenas um carro rápido com sirene. Implemente recursos específicos do veículo que tornem a ambulância uma estação de tratamento móvel. Quando um socorrista do EMS abre as portas traseiras da ambulância por meio de uma interação com o veículo, ele acessa um menu de tratamento móvel com um subconjunto de recursos hospitalares, como curativos, administração de analgésicos, aplicação de talas e uso de desfibrilador. Armazene suprimentos médicos no estoque do porta-malas da ambulância para que os socorristas precisem reabastecer no hospital entre as chamadas. O desfibrilador é um item especial que pode reviver jogadores que entraram no estado de morte, mas deve exigir um minijogo com entradas baseadas em tempo para simular a técnica adequada de RCP. Implemente um sistema de maca onde o EMS possa colocar um jogador caído em uma maca anexada à ambulância, que prende o paciente em uma animação deitada dentro do veículo durante o transporte. Use AttachEntityToEntity para lidar com a colocação da maca e SetPedIntoVehicle para carregar o paciente.

Integração e Qualidade de Vida

Seu sistema hospitalar deve ser integrado ao recurso telefônico do servidor para que os jogadores possam ligar para o 911 diretamente de seu aplicativo de telefone, visualizar seu histórico médico e contas pendentes e verificar os tempos de espera do EMS antes de decidir se devem ligar para pedir ajuda ou se autotratar com itens básicos de uma farmácia. Conecte o sistema de lesões às penalidades de movimento para que lesões nas pernas reduzam a velocidade de movimento e lesões nos braços afetem a precisão da mira, criando consequências tangíveis na jogabilidade que motivam os jogadores a procurar tratamento em vez de ignorar suas lesões. Implementar um sistema de registros médicos acessível através do MDT do hospital, onde os médicos possam visualizar o histórico completo de tratamento do paciente, alergias observadas por outros médicos e medicamentos atuais. Exporte suas funções de lesões e tratamento para que outros recursos, como efeitos de drogas, intoxicação alimentar ou riscos ambientais, possam alimentar o mesmo canal médico. Adicione um sistema de reaparecimento automático com um cronômetro configurável que é ativado quando nenhum EMS está de serviço, garantindo que os jogadores nunca fiquem presos em um estado abatido indefinidamente, ao mesmo tempo que prioriza a interpretação médica dirigida pelo jogador quando a equipe estiver disponível.

Partilhar este artigo

Pronto para melhorar o teu servidor?

Explora os nossos scripts FiveM premium na loja Agency Scripts ou junta-te à nossa comunidade no Discord para suporte e atualizações.