ब्लॉग पर वापस
Tutorial9 मिनट पढ़ें

FiveM एम्बुलेंस जॉब स्क्रिप्ट: एक यथार्थवादी EMS सिस्टम बनाएं

अपने FiveM सर्वर के लिए एक पूर्ण एम्बुलेंस नौकरी डिजाइन करें। रोगी पुनर्जीवन, अस्पताल कार्यप्रवाह, ESX और QBCore एकीकरण साथ ही उपलब्ध सर्वश्रेष्ठ EMS स्क्रिप्ट।

Agency Scripts

Agency Scripts के संस्थापक और प्रमुख डेवलपर

एम्बुलेंस जॉब सिस्टम अवलोकन

एक एम्बुलेंस जॉब स्क्रिप्ट किसी भी रोलप्ले सर्वर के लिए आवश्यक है जो इमर्सिव आपातकालीन सेवा गेमप्ले का लक्ष्य रखता है। EMS सिस्टम सब कुछ संभालता है, जब कोई खिलाड़ी गिरता है तो डिस्पैच कॉल प्राप्त करना, ऑन-सीन उपचार तंत्र, अस्पताल परिवहन, और चिकित्सा बिलिंग। एक अच्छी तरह से डिज़ाइन किया गया एम्बुलेंस स्क्रिप्ट EMS खिलाड़ियों के लिए सार्थक गेमप्ले बनाता है जबकि यह सुनिश्चित करता है कि गिरे हुए खिलाड़ी अनिश्चितकाल तक इंतजार न करें। वास्तुकला चार प्रमुख उपप्रणालियों में विभाजित है: डिस्पैच और सूचना प्रणाली जो EMS को घटनाओं की सूचना देती है, उपचार और स्थिरीकरण तंत्र जो मेडिकल कर्मियों को वास्तविक कार्य देते हैं, अस्पताल चेक-इन और पुनर्प्राप्ति प्रक्रिया, और बिलिंग सिस्टम जो चोटों के लिए आर्थिक लागत बनाता है। प्रत्येक उपप्रणाली स्वतंत्र रूप से कार्यात्मक होनी चाहिए ताकि यदि कोई EMS खिलाड़ी ड्यूटी पर न हो, तो स्वचालित फॉलबैक सिस्टम खिलाड़ी की पुनर्प्राप्ति संभाले।

जॉब कॉन्फ़िगरेशन और ड्यूटी सिस्टम

एम्बुलेंस जॉब को स्पष्ट रूप से परिभाषित ग्रेड की आवश्यकता होती है जिनमें प्रत्येक स्तर पर विभिन्न क्षमताएं होती हैं। प्रशिक्षु केवल बुनियादी प्राथमिक चिकित्सा कर सकते हैं, जबकि वरिष्ठ पैरामेडिक्स उन्नत उपचार दे सकते हैं और प्रतिबंधित चिकित्सा आपूर्ति तक पहुँच सकते हैं। एक कॉन्फ़िगरेशन तालिका का उपयोग करें जो जॉब ग्रेड को उपलब्ध क्रियाओं, आवश्यक वस्तुओं, और भुगतान दरों से मैप करती है। ड्यूटी सिस्टम को ट्रैक करना चाहिए कि कौन से EMS खिलाड़ी वर्तमान में सक्रिय हैं ताकि सर्वर यह जान सके कि स्वचालित पुनःस्पॉन फॉलबैक का उपयोग करना है या नहीं:

Config.AmbulanceJob = {
    name = 'ambulance',
    grades = {
        [0] = {
            label = 'Trainee',
            treatments = {'bandage', 'painkillers'},
            canRevive = false,
            salary = 250,
        },
        [1] = {
            label = 'EMT',
            treatments = {'bandage', 'painkillers', 'splint', 'iv_drip'},
            canRevive = true,
            salary = 400,
        },
        [2] = {
            label = 'Paramedic',
            treatments = {'bandage', 'painkillers', 'splint', 'iv_drip',
                         'defibrillator', 'blood_transfusion'},
            canRevive = true,
            salary = 550,
        },
        [3] = {
            label = 'Chief',
            treatments = {'all'},
            canRevive = true,
            salary = 750,
        },
    },
    minOnDutyForNoAutoRespawn = 2,
    respawnTimer = 300,  -- seconds before auto-respawn when no EMS
    hospitalCoords = vector3(311.2, -584.3, 43.3),
    bedSpawns = {
        vector4(309.7, -583.8, 43.3, 70.0),
        vector4(313.0, -585.2, 43.3, 70.0),
        vector4(316.3, -586.6, 43.3, 70.0),
    },
}

यह minOnDutyForNoAutoRespawn सेटिंग नियंत्रित करता है कि सर्वर EMS-निर्भर और स्वचालित पुनर्प्राप्ति के बीच कब स्विच करता है। जब ड्यूटी पर दो से कम EMS होते हैं, तो घायल खिलाड़ियों को कॉन्फ़िगर किए गए सेकंडों की प्रतीक्षा के बाद टाइमर-आधारित पुनरुत्थान विकल्प मिलता है। यह खिलाड़ियों को ऐसी चिकित्सा सहायता के इंतजार में फंसे रहने से रोकता है जो कभी नहीं आएगी।

डिस्पैच और सूचना प्रणाली

जब कोई खिलाड़ी असमर्थ हो जाता है, तो सिस्टम सभी ड्यूटी पर मौजूद EMS खिलाड़ियों को एक डिस्पैच अलर्ट प्रसारित करता है जिसमें स्थान, आपातकाल की प्रकृति, और कॉल दावा करने का तरीका दिखाया जाता है। कई EMS खिलाड़ी अलर्ट देख सकते हैं, लेकिन भ्रम से बचने के लिए केवल एक को इसे दावा करना चाहिए। एक दावा प्रणाली लागू करें जहां पहला रिस्पॉन्डर कॉल स्वीकार करता है और इसे असाइन कर दिया जाता है, और अन्य EMS इसे दावा किया हुआ देखते हैं जिसमें रिस्पॉन्डिंग यूनिट की पहचान होती है:

-- Server: handle player down event
local ActiveCalls = {}

RegisterNetEvent('ambulance:server:playerDown', function(deathCause)
    local src = source
    local Player = QBCore.Functions.GetPlayer(src)
    if not Player then return end

    local ped = GetPlayerPed(src)
    local coords = GetEntityCoords(ped)
    local streetHash, _ = GetStreetNameAtCoord(coords.x, coords.y, coords.z)
    local streetName = GetStreetNameFromHashKey(streetHash)

    local callId = 'EMS-' .. os.time() .. '-' .. src
    ActiveCalls[callId] = {
        source = src,
        patient = Player.PlayerData.charinfo.firstname .. ' ' ..
                  Player.PlayerData.charinfo.lastname,
        coords = coords,
        street = streetName,
        cause = deathCause,
        time = os.time(),
        claimed = false,
        responder = nil,
    }

    -- Notify all on-duty EMS
    local emsList = QBCore.Functions.GetPlayersOnDuty('ambulance')
    for _, emsId in ipairs(emsList) do
        TriggerClientEvent('ambulance:client:newCall', emsId, callId, ActiveCalls[callId])
    end
end)

RegisterNetEvent('ambulance:server:claimCall', function(callId)
    local src = source
    local call = ActiveCalls[callId]
    if not call or call.claimed then return end

    local Player = QBCore.Functions.GetPlayer(src)
    if not Player or Player.PlayerData.job.name ~= 'ambulance' then return end

    call.claimed = true
    call.responder = src

    -- Notify all EMS that call is claimed
    local emsList = QBCore.Functions.GetPlayersOnDuty('ambulance')
    for _, emsId in ipairs(emsList) do
        TriggerClientEvent('ambulance:client:callClaimed', emsId, callId, Player.PlayerData.charinfo.firstname)
    end

    -- Set GPS waypoint for responding EMT
    TriggerClientEvent('ambulance:client:setWaypoint', src, call.coords)
end)

डिस्पैच जानकारी में मृत्यु का कारण शामिल करें ताकि प्रतिक्रिया देने वाला EMT उचित उपचार आइटम तैयार कर सके। सामान्य कारण जैसे गोली लगना, वाहन टक्कर, गिरना, और डूबना प्रत्येक के लिए अलग उपचार आवश्यकताएं होती हैं, जो EMS भूमिका निभाने के अनुभव में गहराई जोड़ती हैं।

ट्रीटमेंट और रिवाइव मैकेनिक्स

ट्रीटमेंट मैकेनिक्स केवल किसी को पुनर्जीवित करने के लिए बटन दबाने से अधिक शामिल होने चाहिए। एक बहु-चरण प्रक्रिया बनाएं जहाँ EMT पहले रोगी को बुनियादी उपचारों से स्थिर करता है फिर वास्तविक पुनरुद्धार करता है। प्रत्येक उपचार चरण EMT की इन्वेंटरी से एक आइटम का उपयोग करता है और प्रगति बार एनिमेशन के साथ निर्धारित समय लेता है। रोगी की स्थिति एक सरल स्वास्थ्य स्थिति के साथ मॉडल की जा सकती है जो प्रत्येक लागू उपचार के साथ सुधरती है:

-- Client: treatment system
local TreatmentSteps = {
    ['bandage'] = {
        label = 'Apply Bandage',
        duration = 5000,
        anim = {dict = 'mini@cpr@char_a@cpr_str', name = 'cpr_pumpchest'},
        healthRestore = 10,
        item = 'bandage',
    },
    ['painkillers'] = {
        label = 'Administer Painkillers',
        duration = 3000,
        anim = {dict = 'mp_arresting', name = 'a_uncuff'},
        healthRestore = 15,
        item = 'painkillers',
    },
    ['defibrillator'] = {
        label = 'Use Defibrillator',
        duration = 8000,
        anim = {dict = 'mini@cpr@char_a@cpr_str', name = 'cpr_pumpchest'},
        healthRestore = 0,
        item = 'defibrillator',
        canRevive = true,
    },
}

function PerformTreatment(targetId, treatmentType)
    local treatment = TreatmentSteps[treatmentType]
    if not treatment then return end

    -- Check if EMT has required item
    if not HasItem(treatment.item) then
        QBCore.Functions.Notify('Missing: ' .. treatment.label, 'error')
        return
    end

    -- Play animation and progress bar
    TaskPlayAnim(PlayerPedId(), treatment.anim.dict, treatment.anim.name,
        8.0, -8.0, treatment.duration, 1, 0, false, false, false)

    QBCore.Functions.Progressbar('treatment_' .. treatmentType,
        treatment.label, treatment.duration, false, true, {}, {}, {}, {},
        function() -- success
            TriggerServerEvent('ambulance:server:applyTreatment',
                targetId, treatmentType)
            ClearPedTasks(PlayerPedId())
        end,
        function() -- cancel
            ClearPedTasks(PlayerPedId())
            QBCore.Functions.Notify('Treatment cancelled', 'error')
        end
    )
end

एनिमेशन के साथ प्रगति बार एक यथार्थवादी उपचार दृश्य बनाता है जिसे अन्य खिलाड़ी देख सकते हैं, जिससे रोलप्ले माहौल बढ़ता है। डिफिब्रिलेटर को अंतिम चरण बनाएं जो वास्तव में पुनर्जीवन करता है, जिससे EMT को पहले मरीज को पट्टियों और दर्द निवारकों से स्थिर करना पड़ता है। यह बहु-चरणीय दृष्टिकोण EMS भूमिका को एक सरल एक-क्लिक पुनर्जीवन से अधिक आकर्षक बनाता है।

अस्पताल चेक-इन और रिकवरी

फील्ड में मरीज को पुनर्जीवित करने या अस्पताल ले जाने के बाद, EMS खिलाड़ी उन्हें पूर्ण रिकवरी के लिए अस्पताल के बिस्तर में चेक-इन कर सकता है। चेक-इन प्रक्रिया मरीज को पूरी तरह से ठीक करती है, मेडिकल बिल चार्ज करती है, और विजिट को लॉग करती है। अस्पताल के बिस्तरों को ट्रैक किया जाना चाहिए ताकि एक ही बिस्तर पर कई मरीज न हों। एक बिस्तर प्रबंधन प्रणाली बनाएं जो बिस्तरों को व्यस्त के रूप में चिह्नित करे और कॉन्फ़िगर करने योग्य रिकवरी समय के बाद उन्हें रिलीज़ करे:

-- Server: hospital bed management
local OccupiedBeds = {}

RegisterNetEvent('ambulance:server:checkInPatient', function(patientId)
    local src = source
    local EMT = QBCore.Functions.GetPlayer(src)
    local Patient = QBCore.Functions.GetPlayer(patientId)

    if not EMT or not Patient then return end
    if EMT.PlayerData.job.name ~= 'ambulance' then return end

    -- Find available bed
    local bedIndex = nil
    for i, bed in ipairs(Config.AmbulanceJob.bedSpawns) do
        if not OccupiedBeds[i] then
            bedIndex = i
            break
        end
    end

    if not bedIndex then
        TriggerClientEvent('QBCore:Notify', src, 'No beds available', 'error')
        return
    end

    OccupiedBeds[bedIndex] = patientId

    -- Calculate and charge medical bill
    local bill = CalculateMedicalBill(Patient)
    Patient.Functions.RemoveMoney('bank', bill, 'medical-bill')

    -- Heal patient and teleport to bed
    local bed = Config.AmbulanceJob.bedSpawns[bedIndex]
    TriggerClientEvent('ambulance:client:bedRecovery', patientId, bed, bill)

    -- Pay EMT for service
    local salary = Config.AmbulanceJob.grades[EMT.PlayerData.job.grade.level].salary
    EMT.Functions.AddMoney('bank', salary, 'ems-treatment-pay')

    -- Release bed after recovery
    SetTimeout(60000, function()
        OccupiedBeds[bedIndex] = nil
    end)
end)

function CalculateMedicalBill(Patient)
    local baseCost = 500
    local injuryMultiplier = 1.0
    -- Could factor in injury severity, treatment count, etc.
    return math.floor(baseCost * injuryMultiplier)
end

मेडिकल बिल मरने के लिए एक आर्थिक परिणाम बनाता है जो सर्वर अर्थव्यवस्था को संतुलित करता है। बिल को इस आधार पर स्केल करने पर विचार करें कि खिलाड़ी कैसे घायल हुआ, जैसे तेज़ गति से दुर्घटना जैसी लापरवाही के लिए उच्च लागत बनाम अपराध पीड़ित होने के लिए कम लागत। यह सावधान ड्राइविंग को प्रोत्साहित करता है और खतरनाक परिस्थितियों को महत्व देता है।

ऑटो-रिस्पॉन फालबैक सिस्टम

जब कोई EMS खिलाड़ी ड्यूटी पर नहीं होता है, तो सर्वर को एक वैकल्पिक पुनर्प्राप्ति मार्ग प्रदान करना चाहिए ताकि घायल खिलाड़ी स्थायी रूप से फंसे न रहें। एक काउंटडाउन टाइमर लागू करें जो एक कॉन्फ़िगर करने योग्य विलंब के बाद दिखाई देता है, जिससे खिलाड़ी अस्पताल में पुनःस्पॉन कर सके और एक फ्लैट मेडिकल शुल्क स्वचालित रूप से कटे। पुनःस्पॉन स्थान अस्पताल के प्रवेश द्वार या निर्दिष्ट पुनर्प्राप्ति क्षेत्र में होना चाहिए। ऑटो-रिस्पॉन विकल्प दिखाने से पहले वर्तमान EMS संख्या की जांच करें, और यदि काउंटडाउन के दौरान कोई EMT कॉल स्वीकार करता है तो इसे तुरंत बंद कर दें। यह द्वि-मार्ग प्रणाली सुनिश्चित करती है कि खिलाड़ी हमेशा पुनर्प्राप्ति का एक तरीका रखते हैं जबकि EMS इंटरैक्शन की भूमिका निभाने के अनुभव को प्राथमिकता देते हैं जब मेडिक्स उपलब्ध हों।

मेडिकल सप्लाई और इन्वेंटरी इंटीग्रेशन

EMS खिलाड़ियों को अस्पताल में नौकरी-सीमित स्टैश के माध्यम से और क्राफ्टिंग या खरीद प्रणाली के माध्यम से चिकित्सा आपूर्ति तक पहुंच की आवश्यकता होती है। अस्पताल स्टैश को बैंडेज, पेनकिलर, स्प्लिंट, IV ड्रिप, ब्लड बैग और डिफिब्रिलेटर चार्ज से स्टॉक करें। प्रत्येक उपचार क्रिया संबंधित आइटम का उपभोग करती है, जिससे पुनःपूर्ति की निरंतर मांग बनती है। खपत पैटर्न की निगरानी के लिए आपूर्ति उपयोग को डेटाबेस में ट्रैक करें और कॉन्फ़िगर करने योग्य अंतराल पर अस्पताल स्टैश को स्वचालित रूप से पुनःपूर्ति करें। कुछ आपूर्ति को फार्मासिस्ट या डॉक्टर भूमिका वाले खिलाड़ियों द्वारा क्राफ्टेबल बनाने पर विचार करें, जिससे अतिरिक्त रोलप्ले अवसर और सर्वर पर विभिन्न नौकरियों के बीच आर्थिक संबंध बनते हैं।

लॉगिंग और प्रदर्शन निगरानी

प्रशासनिक समीक्षा के लिए हर EMS इंटरैक्शन को लॉग करें, जिसमें कौन इलाज किया गया, कौन से उपचार लागू किए गए, प्रतिक्रिया देने वाला EMT, और अंतिम मेडिकल बिल शामिल हैं। इन लॉग्स को एक समर्पित डेटाबेस टेबल में संग्रहित करें और वैकल्पिक रूप से वास्तविक समय स्टाफ मॉनिटरिंग के लिए सारांश Discord वेबहुक पर भेजें। ये लॉग विवादों को सुलझाने, EMS खिलाड़ियों की पहचान करने में मदद करते हैं जो अपनी जिम्मेदारियां नहीं निभा रहे हैं, और समग्र सिस्टम स्वास्थ्य को ट्रैक करते हैं। प्रदर्शन पक्ष पर, मृत्यु जांच तर्क को हल्का रखें केवल उन खिलाड़ियों पर चलाकर जिनका स्वास्थ्य शून्य हो गया है, हर फ्रेम में हर खिलाड़ी पर नहीं। घटना-चालित वास्तुकला का उपयोग करें जहां मृत्यु स्थिति एकल सर्वर घटना को ट्रिगर करती है बजाय पोलिंग के। डिस्पैच नोटिफिकेशन सिस्टम को अलर्ट्स को बैच में भेजना चाहिए बजाय प्रत्येक EMS खिलाड़ी को व्यक्तिगत घटनाएं भेजने के, जिससे नेटवर्क ओवरहेड कम होता है जब कई खिलाड़ी एक साथ गिरते हैं।

शुरू करने के लिए तैयार?

हमारी शॉप से स्क्रिप्ट लें, या सपोर्ट, अपडेट और आगे आने वाली चीज़ों की झलक के लिए Discord से जुड़ें।