Architecture du système hospitalier
Un système hospitalier et EMS transforme la façon dont les joueurs vivent leur santé et leurs blessures sur un serveur de jeu de rôle FiveM. Au lieu de simplement réapparaître après avoir été abattus, les joueurs entrent dans un pipeline de jeu de rôle médical où ils peuvent être stabilisés par EMS sur le terrain, transportés en ambulance, enregistrés à l'hôpital, diagnostiqués, traités et facturés pour les services. L'architecture du système se divise en quatre couches interconnectées : le système de blessures qui suit ce qui est arrivé au joueur et où il se trouve sur son corps, les outils de répartition EMS et de réponse sur le terrain, le flux de travail d'enregistrement et de traitement à l'hôpital, et le système de facturation qui connecte les soins médicaux à l'économie des serveurs. Chaque couche communique via des événements de serveur afin que le médecin traitant un patient puisse voir exactement les blessures que l'intervenant EMS a déjà documentées lors du triage sur le terrain. Construire cela comme un système unifié plutôt que comme des scripts séparés garantit que les données des patients circulent de manière transparente depuis le moment où quelqu'un appelle le 911 jusqu'au moment où il sort de l'hôpital avec une facture en main.
Système de type de blessure
Un système détaillé de blessures remplace l’état binaire vivant ou mort par un éventail de conditions qui nécessitent différents traitements. Suivez les blessures par région du corps, gravité et cause afin que les services médicaux d'urgence et les médecins puissent jouer des scénarios médicaux réalistes. Lorsqu'un joueur subit des dégâts, déterminez le type de blessure en fonction de l'arme ou de la cause du décès et appliquez-le à la région du corps appropriée. Les blessures par balle au torse sont plus graves qu'un coup de poing au bras, et chaque type de blessure a des exigences de traitement spécifiques que les médecins doivent suivre :
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,
}
Répartition EMS et réponse sur le terrain
Le système de répartition EMS relie les joueurs abattus aux intervenants médicaux en service. Lorsqu'un joueur entre dans l'état abattu, il peut choisir d'appeler le 911, ce qui crée une alerte de répartition visible par tout le personnel EMS en service. L'alerte comprend les coordonnées GPS de l'appelant, une brève description générée à partir des données de sa blessure et un niveau de priorité basé sur la gravité de la blessure. Les intervenants EMS peuvent accepter l'appel via une interface utilisateur de répartition, qui marque l'appel comme réclamé et fournit une navigation GPS au patient. Implémentez un minuteur de réponse qui suit le temps nécessaire à chaque appel depuis sa création jusqu'au contact avec le patient, utile pour suivre les performances EMS et ajuster les besoins en personnel. Le traitement sur le terrain est une version simplifiée du traitement hospitalier où les services médicaux d'urgence peuvent stabiliser les patients à l'aide de fournitures de base telles que des bandages, des garrots et des injections d'adrénaline pour éviter la mort pendant le transport :
-- 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)
Interface utilisateur d'enregistrement et de traitement à l'hôpital
Le système d’enregistrement de l’hôpital gère le flux des patients de leur arrivée à leur sortie. Lorsqu'un intervenant EMS amène un patient à l'hôpital ou qu'un joueur entre seul, il interagit avec un PNJ du bureau d'accueil ou un point cible pour s'enregistrer. Le processus d'enregistrement crée un dossier patient qui comprend ses blessures actuelles, ses signes vitaux et un identifiant de visite unique à des fins de facturation. Les médecins de garde voient les patients entrants sur un panneau de gestion hospitalière NUI qui affiche la file d'attente dans la salle d'attente, la priorité de triage de chaque patient et ses blessures documentées. Lorsqu'un médecin sélectionne un patient, l'interface utilisateur de traitement s'ouvre et affiche le diagramme corporel du patient avec les emplacements des blessures en surbrillance. Le médecin clique sur chaque blessure pour voir les étapes de traitement requises et peut effectuer chaque étape dans l'ordre, déclenchant des animations et consommant des fournitures médicales de son inventaire. Chaque étape du traitement comporte une barre de progression et un contrôle de réussite qui dépendent des métadonnées de compétences du médecin, ajoutant ainsi un élément de progression au jeu de rôle médical.
Flux de travail de traitement
Concevez le flux de travail de traitement comme un processus étape par étape dans lequel chaque blessure nécessite des actions spécifiques effectuées dans l'ordre. Une blessure par balle au torse peut nécessiter de nettoyer la plaie, d'extraire la balle à l'aide d'une pince à épiler, de recoudre la plaie avec un kit de suture et d'appliquer un bandage. Chaque étape consomme l'élément approprié de l'inventaire du médecin et joue une animation de traitement. Sauter des étapes ou les exécuter dans le désordre devrait soit échouer, soit réduire l'efficacité, encourageant ainsi un jeu de rôle médical approprié. Une fois toutes les blessures traitées, le patient entre dans une période de récupération au cours de laquelle sa santé se régénère progressivement au fil du temps plutôt que de se rétablir instantanément :
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)
Système de service et de repos
Le système de service contrôle quand les services médicaux d'urgence et le personnel hospitalier sont actifs et éligibles pour recevoir des appels de répartition. Lorsqu'un joueur occupant le poste d'ambulancier se présente à un point de service à l'intérieur de l'hôpital, il a accès aux commandes médicales, reçoit des notifications de répartition et apparaît sur la liste EMS active visible par les autres membres du personnel. Le système de service doit suivre les heures d'arrivée et de départ pour les calculs de paie si ton serveur utilise le paiement automatique des salaires. Mettez en œuvre différents rôles de service au sein du travail EMS, tels que paramédical, médecin et chirurgien, où chaque rôle a accès à différentes capacités de traitement. Un ambulancier peut effectuer une stabilisation sur le terrain et des traitements de base, un médecin peut gérer des procédures hospitalières standard et un chirurgien peut effectuer des opérations complexes telles que l'extraction d'une balle et la mise en place d'os. Stockez la liste de tâches dans un état de serveur partagé afin que le système de répartition puisse compter avec précision les intervenants disponibles et ajuster le minuteur de réapparition automatique pour les joueurs abattus en fonction de la disponibilité EMS.
Système de facturation médicale
La facturation médicale connecte le système hospitalier à l’économie des serveurs et crée une conséquence financière en cas de comportement à risque. Lorsqu'un patient est traité, le système génère une facture détaillée répertoriant chaque traitement effectué, les fournitures consommées et les éventuels frais d'établissement. Les factures peuvent être payées au moment du paiement via la réception, facturées directement sur le compte bancaire du patient ou envoyées sous forme de facture que le patient doit payer dans un délai déterminé. Mettez en œuvre un système d’assurance médicale dans lequel les joueurs peuvent souscrire des polices d’assurance qui couvrent un pourcentage de leurs frais médicaux, réduisant ainsi le fardeau financier des fréquentes visites à l’hôpital. Les primes d'assurance peuvent constituer des frais récurrents qui s'ajoutent à la simulation économique du serveur. Pour les joueurs qui ne peuvent pas payer, mettez en place un système de dette médicale dans lequel les factures impayées accumulent des intérêts et finissent par déclencher des conséquences telles que la saisie-arrêt des salaires ou un accès restreint à certains services jusqu'à ce que la dette soit réglée. Stockez tous les enregistrements de facturation pour examen par l'administrateur et connectez-les au système de journalisation des transactions afin que le flux d'argent du patient à l'hôpital puisse être audité.
Véhicule et équipement d'ambulance
Le véhicule ambulance devrait être plus qu’une simple voiture rapide équipée d’une sirène. Implémentez des fonctionnalités spécifiques au véhicule qui font de l’ambulance une station de traitement mobile. Lorsqu'un intervenant EMS ouvre les portes arrière de l'ambulance via une interaction avec un véhicule, il accède à un menu de traitement mobile avec un sous-ensemble de capacités hospitalières telles que le bandage, l'administration d'analgésiques, l'application d'attelles et l'utilisation d'un défibrillateur. Conservez les fournitures médicales dans le coffre de l'ambulance afin que les intervenants doivent se réapprovisionner à l'hôpital entre les appels. Le défibrillateur est un objet spécial qui peut réanimer les joueurs qui sont entrés dans l'état de mort, mais il devrait nécessiter un mini-jeu avec des entrées basées sur le timing pour simuler une technique de RCP appropriée. Mettez en œuvre un système de civière dans lequel les services médicaux d'urgence peuvent placer un joueur abattu sur une civière attachée à l'ambulance, ce qui verrouille le patient dans une animation allongée à l'intérieur du véhicule pendant le transport. Utiliser AttachEntityToEntity pour gérer le placement de la civière et SetPedIntoVehicle pour le chargement du patient.
Intégration et qualité de vie
Ton système hospitalier doit s'intégrer à la ressource téléphonique du serveur afin que les joueurs puissent appeler le 911 directement depuis leur application téléphonique, consulter leurs antécédents médicaux et leurs factures impayées, et vérifier les temps d'attente EMS avant de décider s'ils doivent appeler à l'aide ou se soigner eux-mêmes avec des articles de base d'une pharmacie. Connectez le système de blessures aux pénalités de mouvement afin que les blessures aux jambes réduisent la vitesse de déplacement et que les blessures aux bras affectent la précision de la visée, créant ainsi des conséquences de jeu tangibles qui motivent les joueurs à se faire soigner plutôt que d'ignorer leurs blessures. Mettez en œuvre un système de dossiers médicaux accessible via l'hôpital MDT où les médecins peuvent consulter l'historique complet de traitement d'un patient, les allergies notées par d'autres médecins et les médicaments en cours. Exportez tes fonctions de traitement et de blessures afin que d’autres ressources telles que les effets des médicaments, les intoxications alimentaires ou les risques environnementaux puissent toutes alimenter le même pipeline médical. Ajoutez un système de réapparition automatique avec une minuterie configurable qui s'active lorsqu'aucun SMU n'est en service, garantissant que les joueurs ne sont jamais coincés indéfiniment dans un état à terre tout en donnant la priorité au jeu de rôle médical dirigé par les joueurs lorsque le personnel est disponible.
