نظام السطو والسرقة في FiveM: البنوك، المتاجر والخزائن
سكريبت يكافئ عمليات السطو والسرقات في FiveM. Fleeca، Paleto، متاجر المجوهرات، الشرطة وأفضل سكريبتات السطو لخوادم لعب الأدوار القاسية.
Agency Scripts
المؤسس والمطور الرئيسي في Agency Scripts
نظرة عامة على بنية نظام السرقة
تعتبر عمليات السرقة والسطو من أكثر حلقات اللعب إثارة في أي خادم FiveM roleplay. تجمع بين المجرمين الذين يخططون لعملية معقدة، الشرطة التي تستجيب بدقة تكتيكية، مفاوضي الرهائن الذين يديرون المواجهات المتوترة، والمدنيين العالقين في تبادل إطلاق النار. نظام السرقة المصمم جيدًا يتجاوز مجرد مطالبة تفاعل بسيطة تمنح اللاعبين المال. يتطلب بنية متعددة الطبقات تتعامل مع إدارة المواقع، فحوصات المتطلبات المسبقة، مراحل الألعاب المصغرة التقدمية، توزيع الغنائم، دمج إرسال الشرطة، إدارة فترات التهدئة، وحمايات ضد الاستغلال. يجب بناء النظام بثلاث طبقات أساسية: طبقة التكوين التي تحدد كل موقع سرقة مع متطلباته ومكافآته، آلة حالة على جانب الخادم تتتبع السرقات النشطة وتطبق جميع القواعد، وطبقة عرض على جانب العميل تعرض الألعاب المصغرة، الرسوم المتحركة، وواجهات NUI. يجب أن تحدث كل القرارات الحرجة على جانب الخادم لأن منطق جانب العميل قابل للاستغلال بسهولة.
تكوين مواقع ودرجات السطو
نظام السطو الخاص بك يجب أن يدعم أنواع مواقع متعددة مع مستويات صعوبة متصاعدة. تمثل متاجر الراحة المستوى المبتدئ، وتتطلب وجود شرطة قليل وأدوات أساسية. فروع بنك Fleeca تقع في المستوى المتوسط مع طبقات أمنية معتدلة ومتطلبات شرطة أعلى. خزنة Pacific Standard تمثل السطو الأعلى، وتتطلب طاقمًا كاملاً، معدات متقدمة، وحضورًا كبيرًا لإنفاذ القانون عبر الإنترنت. كل موقع يحتاج إلى إدخال تكوين يحدد إحداثياته، العناصر المطلوبة، الحد الأدنى لعدد الشرطة، مدة التهدئة، نطاق المكافأة، وتسلسل طبقات الأمن التي يجب التغلب عليها:
Config.Robberies = {
['store_1'] = {
label = 'LTD Gasoline - Davis',
type = 'store',
coords = vector3(-47.02, -1757.23, 29.42),
register = vector3(-43.43, -1748.60, 29.42),
tier = 1,
cooldown = 1800, -- 30 minutes
minPolice = 2,
requiredItems = {'weapon_pistol'},
reward = {min = 2500, max = 6000, type = 'cash'},
securityLayers = {
{type = 'intimidate', time = 30},
{type = 'grab_cash', time = 15},
},
},
['fleeca_legion'] = {
label = 'Fleeca Bank - Legion Square',
type = 'bank',
coords = vector3(149.73, -1042.65, 29.37),
vault = vector3(144.87, -1044.16, 29.37),
tier = 2,
cooldown = 7200, -- 2 hours
minPolice = 4,
requiredItems = {'electronickit', 'thermite'},
reward = {min = 45000, max = 90000, type = 'markedbills'},
securityLayers = {
{type = 'hack', difficulty = 'medium', time = 25},
{type = 'thermite', time = 10},
{type = 'drill', time = 40},
},
},
['pacific_standard'] = {
label = 'Pacific Standard Bank',
type = 'vault',
coords = vector3(255.85, 225.60, 101.88),
vault = vector3(262.20, 222.10, 101.68),
tier = 3,
cooldown = 14400, -- 4 hours
minPolice = 6,
requiredItems = {'electronickit', 'thermite', 'advancedlaptop', 'duffelbag'},
reward = {min = 250000, max = 500000, type = 'markedbills'},
securityLayers = {
{type = 'hack', difficulty = 'hard', time = 20},
{type = 'hack', difficulty = 'hard', time = 20},
{type = 'thermite', time = 8},
{type = 'drill', time = 60},
{type = 'hack', difficulty = 'expert', time = 15},
},
},
}
يجب أن تتدرج كل طبقة ليس فقط في المكافأة ولكن أيضًا في التعقيد والمخاطرة. عمليات سرقة المتاجر هي عمليات سريعة تستغرق أقل من دقيقتين، بينما عملية سرقة Pacific Standard هي عملية متعددة المراحل يمكن أن تستغرق خمسة عشر دقيقة أو أكثر لإكمالها، مما يمنح الشرطة وقتًا كافيًا لإنشاء محيط أمني.
آلة الحالة على جانب الخادم
آلة حالة السرقة هي قلب النظام. تتتبع كل موقع سرقة خلال حالات دورة حياته: خامل، جارٍ، فترة تبريد، ومقفول. عندما يبدأ لاعب سرقة، يتحقق الخادم من جميع المتطلبات قبل تحويل الموقع من حالة خامل إلى جارٍ. خلال حالة الجارٍ، يتتبع الخادم طبقة الأمان التي يتواجد عليها المجرمون حاليًا، اللاعبين المشاركين، ومدة الوقت المنقضية. إذا غادر جميع اللاعبين المنطقة أو تم اعتقالهم، تفشل السرقة تلقائيًا وتدخل فترة تبريد قصيرة. عند الانتهاء، يدخل الموقع حالة التبريد للمدة المكونة قبل أن يصبح متاحًا مرة أخرى:
local RobberyState = {}
function InitializeRobbery(robberyId)
RobberyState[robberyId] = {
status = 'idle', -- idle | active | cooldown | locked
participants = {},
currentLayer = 0,
startedAt = 0,
cooldownUntil = 0,
}
end
RegisterNetEvent('robbery:server:startRobbery', function(robberyId)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
local config = Config.Robberies[robberyId]
local state = RobberyState[robberyId]
if not config or not state then return end
-- Validate state
if state.status ~= 'idle' then
TriggerClientEvent('QBCore:Notify', src, 'This location is not available', 'error')
return
end
-- Check cooldown
if os.time() < state.cooldownUntil then
TriggerClientEvent('QBCore:Notify', src, 'Location on cooldown', 'error')
return
end
-- Check minimum police online
local policeCount = GetOnlinePolicCount()
if policeCount < config.minPolice then
TriggerClientEvent('QBCore:Notify', src, 'Not enough police online', 'error')
return
end
-- Check required items
for _, item in ipairs(config.requiredItems) do
if not Player.Functions.GetItemByName(item) then
TriggerClientEvent('QBCore:Notify', src, 'Missing required equipment', 'error')
return
end
end
-- Start robbery
state.status = 'active'
state.participants = {src}
state.currentLayer = 1
state.startedAt = os.time()
-- Alert police dispatch
TriggerEvent('dispatch:server:notify', {
type = 'robbery',
coords = config.coords,
message = 'Silent alarm triggered at ' .. config.label,
tier = config.tier,
})
-- Send first security layer to client
TriggerClientEvent('robbery:client:startLayer', src, robberyId, config.securityLayers[1])
end)
يجب أن تتعامل آلة الحالة أيضًا مع الحالات الحدية مثل إعادة تشغيل الخادم أثناء عمليات السطو النشطة. عند بدء الخادم، أعد تعيين جميع حالات السطو إلى الخمول وامسح أي مشاركين نشطين. خزّن طوابع تبريد الوقت في جدول دائم بحيث تبقى بعد إعادة التشغيل.
تكامل الألعاب الصغيرة
تحول الألعاب الصغيرة عمليات السطو من تجربة انتظار سلبية إلى تحدي مهاري نشط. يجب أن يرتبط كل نوع من طبقات الأمان بأسلوب لعبة صغيرة مختلف يختبر قدرات اللاعب المختلفة. يمكن أن تستخدم ألعاب الاختراق ألغاز مطابقة الذاكرة، تحديات توصيل الدوائر، أو تسلسلات أرقام سريعة. يتطلب وضع الثيرمايت توقيتًا دقيقًا لوضع الشحنات قبل أن تنطفئ. تختبر آليات الحفر التحكم المستقر بالفأرة بينما يوجه اللاعب رأس الحفر عبر آلية القفل دون ارتفاع درجة الحرارة. المبدأ التصميمي الرئيسي هو أن المستويات الأصعب يجب أن تستخدم نسخًا أكثر تعقيدًا من هذه الألعاب الصغيرة مع نوافذ توقيت أضيق، المزيد من العناصر للتتبع، أو سرعات أعلى:
-- Client-side minigame dispatcher
function StartMinigame(layerType, difficulty, callback)
if layerType == 'hack' then
local config = HackDifficulty[difficulty]
exports['ps-ui']:Circle(function(success)
callback(success)
end, config.circles, config.speed)
elseif layerType == 'thermite' then
exports['ps-ui']:Thermite(function(success)
callback(success)
end, 10, 5, 3)
elseif layerType == 'drill' then
exports['drilling']:StartDrill(function(success)
callback(success)
end)
elseif layerType == 'intimidate' then
-- Store clerk intimidation: aim weapon at NPC
StartClerkIntimidation(function(success)
callback(success)
end)
end
end
RegisterNetEvent('robbery:client:startLayer', function(robberyId, layer)
local ped = PlayerPedId()
-- Play appropriate animation
if layer.type == 'hack' then
PlayHackingAnimation(ped)
elseif layer.type == 'drill' then
PlayDrillingAnimation(ped)
end
StartMinigame(layer.type, layer.difficulty, function(success)
ClearPedTasks(ped)
TriggerServerEvent('robbery:server:layerResult', robberyId, success)
end)
end)
يجب أن يكون لمحاولات الألعاب الصغيرة الفاشلة عواقب. قد يؤدي اختراق فاشل إلى تشغيل إنذارات إضافية، تقليل الوقت المتبقي، أو حظر اللاعب لفترة عقوبة قصيرة. بالنسبة للسرقات عالية المستوى، قد يؤدي فشل الاختراق النهائي إلى إغلاق الخزنة بالكامل، مما يجبر الطاقم على التخلي عن السرقة مع الحصول على غنيمة جزئية فقط. تضيف حالات الفشل هذه توتراً وتجعل الإنجازات الناجحة مجزية حقًا.
تكامل الإرسال والاستجابة للشرطة
نظام السطو غير مكتمل إلا بتكامل الشرطة. عند بدء السطو، يجب أن يرسل نظام الإرسال تنبيهات مصنفة بناءً على مستوى السطو. يطلق سطو متجر صغير إنذاراً صامتاً بسيطاً مع موقع المتجر. يفعّل فرع Fleeca إنذار البنك مع اسم الفرع ومستوى استجابة مقترح. يفعّل سطو Pacific Standard بث طوارئ كامل يوصي بالاستجابة من جميع الوحدات المتاحة. زود الشرطة بتحديثات في الوقت الحقيقي أثناء تقدم السطو: عند اختراق المجرمين طبقة أمان جديدة، عند إطلاق النار داخل المبنى، أو عند محاولة المجرمين الفرار. تساعد هذه التحديثات الشرطة على تنسيق استجابتهم وخلق سيناريوهات ديناميكية حيث يمكن للضباط اتخاذ قرار الاختراق الفوري أو إقامة محيط والتفاوض. نفذ آلية رهائن حيث يمكن للمجرمين أخذ موظفي البنك NPC رهائن، مما يمنح مفاوضي الشرطة دوراً ويوفر للمجرمين ورقة ضغط لتأخير استجابة الشرطة. يجب أن يتتبع نظام الرهائن عدد الرهائن المحتجزين، ما إذا تعرض أي منهم للأذى، ويوفر مطالبات تفاوض عبر مكالمات هاتفية بين المجرمين والضباط المستجيبين.
توزيع الغنائم وغسيل الأموال
ما يتلقاه اللاعبون من عملية سرقة يهم بقدر أهمية السرقة نفسها. بدلاً من إيداع النقود النظيفة مباشرة في الحسابات البنكية، كافئ المجرمين بأوراق نقدية معنونة أو بضائع مسروقة تتطلب خطوات إضافية لتحويلها إلى عملة قابلة للاستخدام. هذا التصميم يوسع حلقة اللعب الإجرامي بعد السرقة ويخلق أنظمة مترابطة. يمكن غسل الأوراق النقدية المعنونة في مواقع محددة حول الخريطة مقابل نسبة مئوية، مما يخلق قرارات مخاطرة-مكافأة حول متى وأين يتم الغسل. تحتاج المجوهرات أو الإلكترونيات المسروقة إلى بيعها عبر تجار NPC الذين يقدمون أسعارًا متغيرة حسب ندرة العنصر وظروف السوق الحالية. نفذ نظام حقيبة الغنائم حيث يجب على اللاعبين حمل الغنائم المادية، مما يحد من سرعة حركتهم ويمنع استخدام الأسلحة، مما يضيف اعتبارات تكتيكية لمرحلة الهروب:
RegisterNetEvent('robbery:server:distributeLoot', function(robberyId)
local src = source
local config = Config.Robberies[robberyId]
local state = RobberyState[robberyId]
if not config or not state then return end
if state.status ~= 'active' then return end
local rewardAmount = math.random(config.reward.min, config.reward.max)
local participants = state.participants
local perPlayer = math.floor(rewardAmount / #participants)
for _, playerId in ipairs(participants) do
local Player = QBCore.Functions.GetPlayer(playerId)
if Player then
if config.reward.type == 'markedbills' then
local billStacks = math.ceil(perPlayer / 5000)
for i = 1, billStacks do
local amount = math.min(5000, perPlayer - ((i - 1) * 5000))
Player.Functions.AddItem('markedbills', 1, nil, {
worth = amount,
source = config.label,
})
end
elseif config.reward.type == 'cash' then
Player.Functions.AddMoney('cash', perPlayer, 'robbery-' .. robberyId)
end
TriggerClientEvent('inventory:client:ItemBox', playerId, QBCore.Shared.Items['markedbills'], 'add')
end
end
-- Set cooldown
state.status = 'cooldown'
state.cooldownUntil = os.time() + config.cooldown
state.participants = {}
-- Log the robbery for admin review
LogRobbery(robberyId, participants, rewardAmount)
end)
إدارة مكافحة الاستغلال وفترات التهدئة
تجذب أنظمة السرقة المستغلين لأنها تولد ثروة. نفذ طبقات متعددة من الحماية ضد الاستغلالات الشائعة. تضمن فحوصات المسافة على جانب الخادم وجود اللاعبين فعليًا في موقع السرقة طوال كل مرحلة. يمنع تحديد المعدل اللاعبين من تكرار أحداث بدء السرقة. يتتبع المشاركون لضمان تقدم المشاركين المسجلين فقط عبر طبقات الأمان أو استلام الغنائم. تمنع فترات التهدئة العالمية تكرار السرقات على مستوى الخادم من خلال تحديد عدد السرقات النشطة في نفس الوقت. تمنع فترات التهدئة لكل لاعب سرقة متسلسلة متعددة المواقع من نفس اللاعب. سجّل كل محاولة سرقة مع الطوابع الزمنية، معرفات المشاركين، حالة النجاح أو الفشل، والمكافأة الموزعة ليتمكن المسؤولون من التحقيق في الأنماط المشبوهة. راقب أوقات الإنجاز المستحيلة حيث ينهي اللاعب كل طبقات الأمان أسرع مما هو ممكن فعليًا. نفذ نظام سمعة حيث تجذب الأنشطة السرقة المفرطة انتباه الشرطة المتزايد وعواقب أشد، مما يخلق تقييدًا طبيعيًا يشجع اللاعبين على توزيع أنشطتهم الإجرامية.
مسارات الهروب والأحداث الديناميكية
مرحلة الهروب هي حيث تصبح عمليات السرقة غير متوقعة حقًا. بمجرد تأمين الغنيمة، يجب على المجرمين الهروب من المنطقة وهم يحملون حقائب ثقيلة تقيد حركتهم. صمم النظام لدعم طرق هروب متعددة: مركبات أرضية متوقفة بالخارج، قوارب في أرصفة قريبة للبنوك على الواجهة البحرية، أو استخراج بطائرات هليكوبتر من الأسطح للسرقات عالية المستوى. أضف أحداثًا ديناميكية خلال مرحلة الهروب مثل شرائط مسامير الإطارات التي يمكن للشرطة نشرها، تحديثات دردشة الراديو التي تكشف وصف مركبة المشتبه به، وحواجز عشوائية عند التقاطعات الرئيسية. يجب أن يتتبع الخادم ما إذا كان المجرمون يغادرون منطقة السرقة بنجاح، المحددة كنطاق قابل للتكوين حول البنك، وعندها فقط يتم اعتبار السرقة مكتملة بالكامل. إذا قُتل أو اعتُقل جميع المشاركين قبل مغادرة المنطقة، يجب أن تكون الغنيمة قابلة للاسترداد من قبل الشرطة كدليل. هذا يخلق تجربة لعب مهمة بعد السرقة لكلا الجانبين ويضمن أن الهروب صعب ومجزٍ مثل السرقة نفسها.