FiveM मैकेनिक सिस्टम: ट्यूनिंग, रिपेयर और वाहन जॉब्स
एक पूर्ण FiveM मैकेनिक सिस्टम बनाएं। मरम्मत, ट्यूनिंग, इम्पाउंड टो, शॉप UI और QBCore और ESX सर्वरों के लिए सर्वश्रेष्ठ मैकेनिक स्क्रिप्ट।
Agency Scripts
Agency Scripts के संस्थापक और प्रमुख डेवलपर
मेकैनिक नौकरी वास्तुकला डिजाइन करना
एक मैकेनिक नौकरी प्रणाली FiveM रोलप्ले सर्वर के लिए विकसित करने के लिए सबसे लोकप्रिय और पुरस्कृत विशेषताओं में से एक है। सरल मरम्मत स्क्रिप्ट्स के विपरीत जो केवल कॉल करते हैं SetVehicleFixed() , एक उचित मैकेनिक सिस्टम एक पूरी नौकरी अर्थव्यवस्था प्रस्तुत करता है जिसमें विशेषीकृत भूमिकाएँ, पार्ट इन्वेंटरीज़, और प्लेयर-टू-प्लेयर इंटरैक्शन होते हैं जो रोलप्ले को चलाते हैं। आर्किटेक्चर को मानचित्र पर कई मैकेनिक दुकानों को ध्यान में रखना चाहिए, जिनमें से प्रत्येक संभवतः विभिन्न प्लेयर समूहों के स्वामित्व में हो, एक नौकरी ग्रेड पदानुक्रम के साथ जो निर्धारित करता है कि कौन कौन से मरम्मत कर सकता है। आधार पर, आपको एक साझा कॉन्फ़िगरेशन की आवश्यकता है जो दुकान स्थान, प्रत्येक स्तर पर उपलब्ध सेवाएँ, पार्ट्स की कीमतें, और उन्नत मरम्मत जैसे इंजन स्वैप या टर्बो इंस्टॉलेशन को अनलॉक करने के लिए आवश्यक नौकरी ग्रेड को परिभाषित करता है। सिस्टम को आपके सर्वर के मौजूदा नौकरी फ्रेमवर्क के साथ एकीकृत करना चाहिए, चाहे वह QBCore हो, ESX हो, या कस्टम समाधान, ताकि खिलाड़ी मैकेनिक भूमिका में सही वेतन और ड्यूटी स्थिति ट्रैकिंग के साथ लॉग इन और आउट कर सकें।
जॉब ग्रेड्स और अनुमति प्रणाली
एक स्तरित नौकरी ग्रेड प्रणाली आपके मैकेनिक नौकरी को गहराई देती है और खिलाड़ियों को रैंक के माध्यम से काम करने के लिए प्रोत्साहित करती है। स्पष्ट ग्रेड परिभाषित करके शुरू करें जिनमें विशिष्ट अनुमतियां हों: एक प्रशिक्षु केवल वाहनों को धो सकता है और मामूली बॉडी डैमेज की मरम्मत कर सकता है, एक मानक मैकेनिक इंजन मरम्मत और टायर प्रतिस्थापन संभाल सकता है, एक वरिष्ठ मैकेनिक प्रदर्शन ट्यूनिंग और स्प्रे पेंटिंग अनलॉक करता है, और दुकान का मालिक कर्मचारियों का प्रबंधन कर सकता है और सेवा मूल्य निर्धारण सेट कर सकता है। इन ग्रेड परिभाषाओं को एक साझा कॉन्फ़िग में संग्रहित करें ताकि क्लाइंट और सर्वर दोनों उन्हें सुसंगत रूप से संदर्भित कर सकें। यहां एक उदाहरण कॉन्फ़िगरेशन है जो ग्रेड को उनकी अनुमत सेवाओं से मैप करता है:
Config.MechanicGrades = {
[0] = {
label = 'Trainee',
services = {'wash', 'body_minor'},
payMultiplier = 0.7
},
[1] = {
label = 'Mechanic',
services = {'wash', 'body_minor', 'body_major', 'engine_repair', 'tire_replace', 'brake_repair'},
payMultiplier = 1.0
},
[2] = {
label = 'Senior Mechanic',
services = {'wash', 'body_minor', 'body_major', 'engine_repair', 'tire_replace',
'brake_repair', 'spray_paint', 'performance_tune', 'turbo_install'},
payMultiplier = 1.3
},
[3] = {
label = 'Shop Owner',
services = 'all',
payMultiplier = 1.5,
canManage = true
}
}
Config.ServicePrices = {
wash = 200,
body_minor = 800,
body_major = 2500,
engine_repair = 3500,
tire_replace = 1200,
brake_repair = 1500,
spray_paint = 5000,
performance_tune = 15000,
turbo_install = 25000
}
सर्वर पक्ष पर, किसी भी सेवा को निष्पादित करने की अनुमति देने से पहले हमेशा खिलाड़ी की ग्रेड को मान्य करें। कभी भी क्लाइंट पर भरोसा न करें कि कौन सी सेवाएं उपलब्ध हैं क्योंकि एक चीटर NUI को संशोधित करके कोई भी सेवा अनुरोध भेज सकता है। सर्वर कॉलबैक को खिलाड़ी की वर्तमान नौकरी, उनकी ग्रेड स्तर, और क्या अनुरोधित सेवा उनकी ग्रेड की सेवा सूची में मौजूद है, यह जांचना चाहिए फिर मरम्मत प्रक्रिया जारी रखनी चाहिए।
वाहन मरम्मत तंत्र और पुर्ज़े प्रणाली
वास्तविक मरम्मत मैकेनिक्स एकल नेटिव कॉल से आगे जाते हैं। तुरंत वाहन ठीक करने के बजाय, मरम्मत प्रक्रिया को चरणों में विभाजित करें जो समय लेते हैं और मैकेनिक की इन्वेंट्री से पार्ट्स का उपभोग करते हैं। जब कोई खिलाड़ी अपने इंजन की मरम्मत के लिए कार लाता है, तो मैकेनिक के पास सही पार्ट्स उनके व्यक्तिगत इन्वेंट्री या दुकान के साझा स्टैश में होने चाहिए। मरम्मत के लिए प्रगति बार सिस्टम का उपयोग करें जो समय लेता है, जिससे प्राकृतिक रोलप्ले क्षण बनते हैं जहाँ ग्राहक इंतजार करता है और मैकेनिक के साथ बातचीत करता है। मरम्मत तर्क विशिष्ट वाहन घटकों को लक्षित करना चाहिए नेटिव फंक्शंस का उपयोग करके ताकि आप इंजन की मरम्मत कर सकें बिना बॉडी डैमेज ठीक किए, या टायर बदल सकें बिना इंजन स्वास्थ्य को प्रभावित किए:
local RepairFunctions = {
engine_repair = function(vehicle)
local parts = {'engine_oil', 'spark_plugs', 'coolant'}
if not HasRequiredParts(parts) then
return false, 'Missing required parts'
end
RemovePartsFromInventory(parts)
-- Animate the repair
TaskTurnPedToFaceEntity(PlayerPedId(), vehicle, 1000)
Wait(1000)
if not StartProgressBar('Repairing engine...', 15000, 'mechanic_repair') then
return false, 'Repair cancelled'
end
SetVehicleEngineHealth(vehicle, 1000.0)
SetVehicleEngineOn(vehicle, true, true, false)
return true
end,
body_major = function(vehicle)
local parts = {'body_panel', 'filler_putty', 'paint_primer'}
if not HasRequiredParts(parts) then
return false, 'Missing required parts'
end
RemovePartsFromInventory(parts)
if not StartProgressBar('Repairing body damage...', 20000, 'mechanic_repair') then
return false, 'Repair cancelled'
end
SetVehicleBodyHealth(vehicle, 1000.0)
SetVehicleDeformationFixed(vehicle)
return true
end,
tire_replace = function(vehicle, tireIndex)
local parts = {'tire_set'}
if not HasRequiredParts(parts) then
return false, 'Missing required parts'
end
RemovePartsFromInventory(parts)
if not StartProgressBar('Replacing tire...', 8000, 'mechanic_repair') then
return false, 'Repair cancelled'
end
SetVehicleTyreFixed(vehicle, tireIndex)
return true
end
}
पार्ट्स सिस्टम आपके सर्वर पर एक अतिरिक्त अर्थव्यवस्था परत बनाता है। NPC होलसेलर्स पर पार्ट्स स्टॉक करें या खिलाड़ियों को औद्योगिक स्थानों पर उन्हें क्राफ्ट करने दें। मैकेनिक शॉप्स होलसेल कीमतों पर पार्ट्स थोक में खरीद सकते हैं और उन्हें साझा दुकान इन्वेंट्री में स्टोर कर सकते हैं, जिसका मतलब है कि दुकान मालिक को अपने सप्लाई चेन का प्रबंधन करना होगा ताकि व्यवसाय सुचारू रूप से चलता रहे। यह आपूर्ति और मांग की गतिशीलता रोलप्ले अनुभव में गहराई जोड़ती है।
स्प्रे पेंटिंग और कॉस्मेटिक सेवाएं
स्प्रे पेंटिंग एक ऐसी सेवा है जो मैकेनिक की दुकान में सबसे अधिक दृश्यात्मक संतोषजनक होती है, और इसे अच्छी तरह लागू करने के लिए कई वाहन रंग नेटिव फंक्शंस के साथ काम करना आवश्यक है। FiveM प्राथमिक रंग, द्वितीयक रंग, पर्लेसेंट, व्हील रंग, और कस्टम RGB मानों के लिए नेटिव प्रदान करता है। एक रंग चयनकर्ता UI बनाएं जो मैकेनिक को प्रीसेट रंगों में से चयन करने या प्रीमियम कीमत पर कस्टम RGB मान दर्ज करने की अनुमति देता है। NUI को वास्तविक समय पूर्वावलोकन दिखाना चाहिए, जो मैकेनिक विकल्पों को ब्राउज़ करते समय अस्थायी रूप से वाहन पर रंग लागू करता है। मैकेनिक द्वारा पेंट जॉब की पुष्टि करने और ग्राहक द्वारा भुगतान करने के बाद सर्वर-साइड रंग आवेदन को संभालने का तरीका इस प्रकार है:
RegisterNetEvent('mechanic:server:applyPaint', function(netId, paintData, customerId)
local src = source
local Mechanic = QBCore.Functions.GetPlayer(src)
local Customer = QBCore.Functions.GetPlayer(customerId)
if not Mechanic or not Customer then return end
if Mechanic.PlayerData.job.name ~= 'mechanic' then return end
local gradeServices = Config.MechanicGrades[Mechanic.PlayerData.job.grade.level].services
if gradeServices ~= 'all' and not TableContains(gradeServices, 'spray_paint') then
return TriggerClientEvent('QBCore:Notify', src, 'Not authorized', 'error')
end
local price = paintData.isCustomRGB and Config.ServicePrices.spray_paint * 1.5
or Config.ServicePrices.spray_paint
if Customer.Functions.RemoveMoney('cash', price, 'mechanic-paint') then
local shopCut = math.floor(price * 0.6)
local mechanicCut = price - shopCut
Mechanic.Functions.AddMoney('cash', mechanicCut, 'mechanic-paint-commission')
AddToShopFunds(Mechanic.PlayerData.job.grade.level >= 3 and src, shopCut)
TriggerClientEvent('mechanic:client:applyPaint', customerId, netId, paintData)
TriggerClientEvent('QBCore:Notify', src, 'Paint applied - earned $' .. mechanicCut, 'success')
TriggerClientEvent('QBCore:Notify', customerId, 'Vehicle painted for $' .. price, 'success')
else
TriggerClientEvent('QBCore:Notify', src, 'Customer cannot afford this', 'error')
end
end)
मूलभूत पेंट से परे, अलग-अलग कॉस्मेटिक सेवाओं के रूप में लिवरी आवेदन, नीयन लाइट इंस्टॉलेशन, और विंडो टिंटिंग जोड़ने पर विचार करें। प्रत्येक सेवा के अपने भाग आवश्यकताएँ और मूल्य बिंदु होने चाहिए। उदाहरण के लिए, नीयन लाइट्स के लिए पार्ट्स इन्वेंट्री से नीयन किट्स की आवश्यकता होती है और वे SetVehicleNeonLightEnabled और SetVehicleNeonLightsColour natives दृश्य प्रभाव लागू करने के लिए। विंडो टिंटिंग उपयोग करता है SetVehicleWindowTint विभिन्न टिंट स्तरों के साथ जो स्थानीय सर्वर कानूनों द्वारा प्रतिबंधित हो सकते हैं, जिससे पुलिस को खिलाड़ियों को अवैध टिंट के लिए रोकने का कारण मिलता है।
प्रदर्शन उन्नयन और ट्यूनिंग
प्रदर्शन ट्यूनिंग वह जगह है जहाँ मैकेनिक वास्तव में चमक सकते हैं और सर्वर पर उच्चतम कमाई कर सकते हैं। FiveM व्यापक वाहन संशोधन नेटिव प्रदान करता है SetVehicleMod function, जो एक मोड प्रकार और मोड इंडेक्स स्वीकार करता है। मोड प्रकारों में इंजन अपग्रेड (प्रकार 11), ब्रेक (प्रकार 12), ट्रांसमिशन (प्रकार 13), सस्पेंशन (प्रकार 15), आर्मर (प्रकार 16), और टर्बो (प्रकार 18) शामिल हैं। प्रत्येक मोड प्रकार के कई स्तर होते हैं जो वाहन के प्रदर्शन को क्रमिक रूप से बेहतर बनाते हैं। एक ट्यूनिंग इंटरफ़ेस बनाएं जो वर्तमान वाहन के लिए उपलब्ध अपग्रेड दिखाए, प्रत्येक स्तर की लागत, और आदर्श रूप से गति, त्वरण, ब्रेकिंग, और हैंडलिंग के लिए पहले और बाद के मानों की तुलना दिखाए:
function GetAvailableUpgrades(vehicle)
local upgrades = {}
local modTypes = {
{type = 11, label = 'Engine', icon = 'fa-engine'},
{type = 12, label = 'Brakes', icon = 'fa-brake'},
{type = 13, label = 'Transmission', icon = 'fa-gears'},
{type = 15, label = 'Suspension', icon = 'fa-car'},
{type = 16, label = 'Armor', icon = 'fa-shield'},
{type = 18, label = 'Turbo', icon = 'fa-bolt'}
}
SetVehicleModKit(vehicle, 0)
for _, mod in ipairs(modTypes) do
local currentLevel = GetVehicleMod(vehicle, mod.type)
local maxLevel = GetNumVehicleMods(vehicle, mod.type)
local isTurbo = mod.type == 18
table.insert(upgrades, {
type = mod.type,
label = mod.label,
icon = mod.icon,
currentLevel = currentLevel,
maxLevel = isTurbo and 1 or maxLevel,
installed = isTurbo and IsToggleModOn(vehicle, mod.type) or currentLevel >= 0,
price = CalculateUpgradePrice(mod.type, currentLevel + 1)
})
end
return upgrades
end
function ApplyPerformanceUpgrade(vehicle, modType, level)
SetVehicleModKit(vehicle, 0)
if modType == 18 then
ToggleVehicleMod(vehicle, 18, true)
else
SetVehicleMod(vehicle, modType, level, false)
end
end
प्रदर्शन उन्नयन के लिए उच्च-मूल्य वाले भागों जैसे टर्बो किट, रेसिंग ट्रांसमिशन, या स्पोर्ट ब्रेक असेंबली की आवश्यकता होनी चाहिए। ये भाग विशेष आपूर्तिकर्ताओं से प्राप्त किए जा सकते हैं या सही कौशल वाले खिलाड़ियों द्वारा बनाए जा सकते हैं, जो सर्वर अर्थव्यवस्था को समृद्ध करने वाले क्रॉस-जॉब निर्भरताएँ बनाते हैं। हमेशा सर्वर पर उन्नयन अनुरोधों को मान्य करें ताकि क्लाइंट उन संशोधनों को लागू न कर सकें जिनके लिए उन्होंने भुगतान नहीं किया है या जिनके पास भाग नहीं हैं।
बिलिंग सिस्टम और राजस्व साझाकरण
एक साफ बिलिंग सिस्टम पूरे मैकेनिक अनुभव को जोड़ता है और मैकेनिक, ग्राहक, और दुकान के बीच वित्तीय लेनदेन को संभालता है। जब एक मैकेनिक सेवा पूरी करता है, तो एक आइटमाइज्ड बिल उत्पन्न करें जो प्रत्येक की गई सेवा और उसकी लागत सूचीबद्ध करता है। बिल को ग्राहक को एक सूचना या NUI पॉपअप के माध्यम से प्रस्तुत करें जिसे उन्हें भुगतान प्रक्रिया से पहले स्वीकार करना होगा। राजस्व को उस मैकेनिक और दुकान के व्यवसाय खाते के बीच विभाजित करें, विभाजन अनुपात दुकान मालिक द्वारा कॉन्फ़िगर किया जा सकता है। यहाँ एक सर्वर-साइड बिलिंग सिस्टम है जो चालान निर्माण और भुगतान प्रक्रिया को संभालता है:
local activeInvoices = {}
RegisterNetEvent('mechanic:server:createInvoice', function(customerId, services)
local src = source
local Mechanic = QBCore.Functions.GetPlayer(src)
local Customer = QBCore.Functions.GetPlayer(customerId)
if not Mechanic or not Customer then return end
if Mechanic.PlayerData.job.name ~= 'mechanic' then return end
local totalPrice = 0
local lineItems = {}
for _, service in ipairs(services) do
local price = Config.ServicePrices[service.name]
if price then
totalPrice = totalPrice + price
table.insert(lineItems, {
name = service.label,
price = price
})
end
end
local invoiceId = 'INV-' .. os.time() .. '-' .. math.random(1000, 9999)
activeInvoices[invoiceId] = {
mechanic = src,
customer = customerId,
total = totalPrice,
items = lineItems,
shopId = Mechanic.PlayerData.metadata.currentShop,
timestamp = os.time()
}
TriggerClientEvent('mechanic:client:showInvoice', customerId, invoiceId, lineItems, totalPrice)
end)
RegisterNetEvent('mechanic:server:payInvoice', function(invoiceId)
local src = source
local invoice = activeInvoices[invoiceId]
if not invoice or invoice.customer ~= src then return end
local Customer = QBCore.Functions.GetPlayer(src)
local Mechanic = QBCore.Functions.GetPlayer(invoice.mechanic)
if Customer.Functions.RemoveMoney('cash', invoice.total, 'mechanic-invoice') then
local mechanicShare = math.floor(invoice.total * 0.4)
local shopShare = invoice.total - mechanicShare
if Mechanic then
Mechanic.Functions.AddMoney('cash', mechanicShare, 'mechanic-wage')
TriggerClientEvent('QBCore:Notify', invoice.mechanic,
'Received $' .. mechanicShare .. ' for services', 'success')
end
UpdateShopBalance(invoice.shopId, shopShare)
activeInvoices[invoiceId] = nil
TriggerClientEvent('QBCore:Notify', src, 'Paid $' .. invoice.total, 'success')
else
TriggerClientEvent('QBCore:Notify', src, 'Not enough cash', 'error')
end
end)
कई भुगतान विधियों का समर्थन करने पर विचार करें जिनमें नकद, बैंक ट्रांसफर, और यदि आपके सर्वर में क्रिप्टो सिस्टम है तो क्रिप्टोकरेंसी भी शामिल है। सभी लेनदेन को डेटाबेस लॉग में ट्रैक करें ताकि दुकान मालिक अपनी आय का इतिहास देख सकें, अपने सर्वश्रेष्ठ प्रदर्शन करने वाले मैकेनिक की पहचान कर सकें, और किसी भी संदिग्ध बिलिंग पैटर्न को पकड़ सकें। यह वित्तीय ट्रैकिंग टैक्स सिस्टम और सरकारी रोलप्ले इंटरैक्शन को भी सक्षम बनाती है जहाँ राज्य मैकेनिक दुकानों का ऑडिट कर सकता है।
स्टैश और शॉप इन्वेंटरी प्रबंधन
हर मैकेनिक शॉप को एक साझा स्टैश की जरूरत होती है जहाँ पार्ट्स संग्रहीत होते हैं और सभी ड्यूटी पर मौजूद कर्मचारियों के लिए सुलभ होते हैं। अपने सर्वर की इन्वेंटरी प्रणाली के साथ एकीकृत करें, चाहे वह ox_inventory हो, qb-inventory हो, या कोई कस्टम समाधान, ताकि एक दुकान-विशिष्ट स्टैश बनाया जा सके जिसे केवल अधिकृत मैकेनिक एक्सेस कर सकें। दुकान के मालिक को एक होलसेल सप्लायर NPC से पार्ट्स ऑर्डर करने की क्षमता होनी चाहिए, जो दुकान के व्यवसाय खाते से पैसा घटाता है और एक कॉन्फ़िगर करने योग्य डिलीवरी देरी के बाद पार्ट्स को स्टैश में जोड़ता है। यह देरी वास्तविक दुनिया की सप्लाई चेन लॉजिस्टिक्स का अनुकरण करती है और त्वरित पुनःपूर्ति को रोकती है। स्टैश एक्सेस को लॉग में ट्रैक करें ताकि दुकान का मालिक देख सके कि किस मैकेनिक ने कौन से पार्ट्स लिए, जिससे आंतरिक चोरी रोकी जा सके। क्लाइंट साइड पर, दुकान के अंदर एक विशिष्ट प्रॉप जैसे टूल कैबिनेट या पार्ट्स शेल्फ पर टारगेट इंटरैक्शन का उपयोग करके स्टैश खोलें। स्टैश को एक क्राफ्टिंग सिस्टम के साथ मिलाएं जहाँ मैकेनिक कच्चे माल से जटिल पार्ट्स असेंबल कर सकते हैं, जैसे कि टर्बो हाउसिंग, इम्पेलर, और वेस्टगेट को मिलाकर एक पूरा टर्बो किट बनाना, जो नौकरी में एक और कौशल-आधारित परत जोड़ता है।
टो ट्रक और रोडसाइड सहायता
मैकेनिक नौकरी को टो ट्रक और रोडसाइड सहायता सेवाओं को शामिल करने के लिए विस्तारित करना नौकरी की गतिविधि और राजस्व क्षमता को बहुत बढ़ाता है। मैकेनिक को अपनी दुकान से टो ट्रक चेक आउट करने में सक्षम होना चाहिए, फंसे हुए खिलाड़ी के स्थान पर ड्राइव करना चाहिए, टूटी हुई वाहन को संलग्न करना चाहिए AttachEntityToEntity native, और इसे मरम्मत के लिए दुकान पर वापस ले जाएं। एक डिस्पैच सिस्टम लागू करें जहां खिलाड़ी अपने फोन के माध्यम से रोडसाइड सहायता का अनुरोध कर सकते हैं, जो मानचित्र पर एक ब्लिप बनाता है जो सभी ऑन-ड्यूटी मैकेनिक को दिखाई देता है। पहला मैकेनिक जो कॉल स्वीकार करता है वह काम पाता है, और ग्राहक के स्थान तक GPS मार्ग बनाया जाता है। संलग्नक प्रणाली के लिए, टो ट्रक मॉडल के आधार पर उचित ऑफसेट पोजीशंस की गणना करें ताकि टो किया गया वाहन फ्लैटबेड पर सही ढंग से बैठे। टो सेवा के लिए दूरी-आधारित शुल्क जोड़ें ताकि लंबी दूरी के टो ग्राहक के लिए अधिक महंगे हों, जिससे मैकेनिक को उनके क्षेत्र में कॉल संभालने के लिए प्रोत्साहन मिले जबकि वे नकदी वाले लंबी दूरी के काम पूरे मानचित्र में ले जा सकें।