Назад к блогу
Tutorial9 мин чтения

FiveM Hospital and EMS System: Скрипт реалистичных медицинских профессий

Разработайте полный цикл работы больницы и EMS для FiveM. Воскрешения, регистрация пациентов, аптека, связь с скорой помощью и лучшие медицинские скрипты для ролевой игры.

Agency Scripts

Основатель и ведущий разработчик Agency Scripts

Архитектура системы больницы

Система больницы и EMS меняет опыт здоровья и травм на FiveM ролевом сервере. Вместо простого респауна после падения игроки проходят медицинский ролевой процесс: стабилизация EMS на месте, транспортировка на скорой, приём в больницу, диагностика, лечение и выставление счета. Архитектура системы состоит из четырёх взаимосвязанных слоев: система травм, отслеживающая что и где произошло; инструменты диспетчеризации EMS и реагирования на месте; рабочий процесс приёма и лечения в больнице; и биллинговая система, связывающая медобслуживание с экономикой сервера. Каждый слой взаимодействует через серверные события, чтобы врач видел все травмы, задокументированные EMS при первичной оценке. Создание единой системы вместо отдельных скриптов обеспечивает бесшовный поток данных от вызова 911 до выхода пациента из больницы с счётом.

Система типов травм

Подробная система травм заменяет бинарное состояние жив или мёртв спектром состояний, требующих разных методов лечения. Отслеживайте травмы по частям тела, степени тяжести и причине, чтобы EMS и врачи могли разыгрывать реалистичные медицинские сценарии. При получении урона определяйте тип травмы по оружию или хешу причины смерти и применяйте её к соответствующей части тела. Огнестрельные ранения в торс серьёзнее удара по руке, и каждый тип травмы требует специфического лечения, которое врачи должны соблюдать:

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,
}

Диспетчер EMS и выезд на место

Система диспетчеризации EMS связывает упавших игроков с дежурными медицинскими работниками. Когда игрок переходит в состояние упавшего, он может вызвать 911, что создаёт оповещение диспетчера, видимое всем дежурным EMS. Оповещение включает GPS-координаты звонящего, краткое описание, сформированное на основе данных о травмах, и уровень приоритета в зависимости от тяжести травмы. Медики EMS могут принять вызов через интерфейс диспетчера, что помечает вызов как принятый и предоставляет GPS-навигацию к пациенту. Реализуйте таймер отклика, который отслеживает время от создания вызова до контакта с пациентом, полезный для оценки работы EMS и корректировки штата. Полевая помощь , это упрощённая версия лечения в больнице, где EMS может стабилизировать пациентов с помощью базовых средств, таких как бинты, жгуты и инъекции адреналина, чтобы предотвратить смерть во время транспортировки:

-- 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)

UI регистрации и лечения в больнице

Система регистрации в больнице управляет потоком пациентов от прибытия до выписки. Когда сотрудник EMS привозит пациента в больницу или игрок приходит самостоятельно, они взаимодействуют с NPC на стойке регистрации или целевой точкой для регистрации. Процесс регистрации создает запись пациента, включающую текущие травмы, жизненные показатели и уникальный идентификатор визита для целей выставления счетов. Врачи на дежурстве видят поступающих пациентов на панели управления больницей NUI, которая отображает очередь в приемной, приоритет триажа каждого пациента и задокументированные травмы. Когда врач выбирает пациента, открывается интерфейс лечения с диаграммой тела пациента и выделенными местами травм. Врач кликает по каждой травме, чтобы увидеть необходимые шаги лечения и может выполнять каждый шаг последовательно, вызывая анимации и используя медицинские расходные материалы из своего инвентаря. Каждый шаг лечения имеет индикатор прогресса и проверку успеха, зависящую от метаданных навыков врача, добавляя элемент прогрессии в медицинскую ролевую игру.

Рабочий процесс лечения

Разработайте процесс лечения как пошаговую процедуру, где каждая травма требует выполнения определённых действий в порядке. Огнестрельное ранение в туловище может потребовать очистки раны, извлечения пули пинцетом, зашивания раны с помощью набора для швов и наложения повязки. Каждый шаг расходует соответствующий предмет из инвентаря врача и воспроизводит анимацию лечения. Пропуск шагов или выполнение их в неправильном порядке должно либо приводить к неудаче, либо снижать эффективность, стимулируя правильную медицинскую ролевую игру. После лечения всех травм пациент входит в период восстановления, когда здоровье постепенно восстанавливается со временем, а не мгновенно:

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)

Система дежурств и вне дежурства

Система дежурств контролирует, когда сотрудники EMS и больницы активны и могут получать вызовы диспетчера. Когда игрок с работой скорой помощи заходит на дежурство в точке внутри больницы, он получает доступ к медицинским командам, получает уведомления диспетчера и отображается в активном списке EMS, видимом другим сотрудникам. Система дежурств должна отслеживать время входа и выхода для расчёта зарплаты, если на сервере используется автоматическая выплата. Реализуйте разные роли дежурств в работе EMS, такие как парамедик, врач и хирург, где каждая роль имеет доступ к разным возможностям лечения. Парамедик может выполнять стабилизацию на месте и базовое лечение, врач , стандартные процедуры в больнице, а хирург , сложные операции, такие как извлечение пуль и установка костей. Храните список дежурств в общем состоянии сервера, чтобы система диспетчеризации могла точно считать доступных реагирующих и корректировать таймер автоворожения для без сознания игроков в зависимости от доступности EMS.

Система медицинского выставления счетов

Медицинское выставление счетов связывает систему больницы с экономикой сервера и создает финансовые последствия за рискованное поведение. Когда пациент получает лечение, система генерирует детализированный счет, в котором перечислены все проведенные процедуры, использованные материалы и любые сборы за услуги. Счета можно оплатить на кассе через ресепшен, списать напрямую с банковского счета пациента или отправить как счет-фактуру, которую пациент должен оплатить в установленный срок. Реализуйте систему медицинского страхования, где игроки могут приобретать страховые полисы, покрывающие часть их медицинских расходов, снижая финансовую нагрузку от частых посещений больницы. Страховые взносы могут быть регулярным платежом, добавляющимся к экономической симуляции сервера. Для игроков, которые не могут оплатить, реализуйте систему медицинского долга, где неоплаченные счета накапливают проценты и в конечном итоге вызывают последствия, такие как удержание части зарплаты с работы или ограниченный доступ к определенным услугам до погашения долга. Храните все записи счетов для проверки администраторами и подключайте их к системе логирования транзакций для аудита движения денег от пациента к больнице.

Транспорт и оборудование скорой помощи

Автомобиль скорой помощи должен быть не просто быстрой машиной с сиреной. Реализуйте специфические функции, которые делают скорую мобильной лечебной станцией. Когда EMS-ответчик открывает задние двери машины через взаимодействие с транспортом, он получает доступ к мобильному меню лечения с подмножеством возможностей больницы, таких как перевязка, введение обезболивающих, наложение шин и использование дефибриллятора. Медицинские запасы хранятся в багажнике машины, поэтому ответчики должны пополнять их в больнице между вызовами. Дефибриллятор , это специальный предмет, который может оживить игроков, вошедших в состояние смерти, но для его использования требуется мини-игра с таймингом, имитирующая правильную технику CPR. Реализуйте систему носилок, где EMS может положить упавшего игрока на носилки, прикрепленные к машине, что блокирует пациента в анимации лежания внутри транспорта во время перевозки. Используйте AttachEntityToEntity обрабатывать размещение носилок и SetPedIntoVehicle для аккуратной загрузки.

Интеграция и удобство использования

Ваша система больницы должна интегрироваться с телефонным ресурсом сервера, чтобы игроки могли звонить 911 напрямую из приложения телефона, просматривать свою медицинскую историю и непогашенные счета, а также проверять время ожидания EMS перед тем, как решать, вызывать помощь или лечиться самостоятельно с помощью базовых предметов из аптеки. Подключите систему травм к штрафам за движение, чтобы травмы ног снижали скорость передвижения, а травмы рук влияли на точность прицеливания, создавая ощутимые игровые последствия, которые мотивируют игроков искать лечение, а не игнорировать травмы. Реализуйте систему медицинских записей, доступную через MDT больницы, где врачи могут просматривать полную историю лечения пациента, аллергии, отмеченные другими врачами, и текущие лекарства. Экспортируйте функции травм и лечения, чтобы другие ресурсы, такие как эффекты наркотиков, пищевое отравление или экологические опасности, могли использовать ту же медицинскую систему. Добавьте систему автоспауна с настраиваемым таймером, которая активируется, когда EMS не на дежурстве, гарантируя, что игроки не останутся в состоянии без сознания бесконечно, при этом приоритет отдаётся медицинской ролевой игре, управляемой игроками, когда персонал доступен.

Готовы начать?

Возьмите скрипты в нашем магазине или заходите в Discord за поддержкой, обновлениями и анонсами.