Bloga Geri Dön
Guide9 dk. okuma

FiveM Hapishane Sistemi: Anlamlı Hapis Süreleri Scriptleyin

Oyuncuların gerçekten etkileşimde bulunduğu bir hapishane sistemi oluşturun. Cezaevi işleri, kaçış rotaları, gardiyanlar, şartlı tahliye ve derin rol deneyimi için en iyi FiveM hapishane scriptleri.

Agency Scripts

Agency Scripts Kurucusu ve Baş Geliştiricisi

Hapishane Sistemi Mimarisi

Cezaevi sistemi, suç faaliyetleri için anlamlı sonuçlar yaratırken hapsedilen oyunculara otuz dakika boyunca bir duvara bakmak yerine yapacak ilgi çekici bir şeyler sunduğundan, bir FiveM roleplay sunucusuna ekleyebileceğiniz en etkili özelliklerden biridir. Mimari, gerçek zamanlı olarak geri sayan bir hapis zamanlayıcısı, mahkumların emek vererek cezalarını azaltmalarına olanak tanıyan bir dizi cezaevi faaliyeti ve cezaları bitene kadar oyuncuları cezaevi yerleşkesiyle sınırlandıran bir sınır sistemi etrafında döner. GTA V'teki Bolingbroke Penitentiary konumu standart tercihtir çünkü hücre blokları, bir avlu ve çevre tesisleri ile tamamen modellenmiş bir iç mekana sahiptir. Sisteminizin üç temel bileşene ihtiyacı vardır: Sunucuda hapis süresini atayan, silahları ve yasadışı maddeleri alan ceza verme mantığı, oyuncular cezaevi sınırından ayrılırsa onları geri ışınlayan istemci tarafı sınır uygulaması ve mahkumlara zaman geçirmeleri için üretken görevler veren aktivite altyapısı.

Veri Tabanı Şeması ve Ceza Verme

Veritabanı aktif cezaları, sabıka kayıtları için ceza geçmişini ve mahkumların aktivitelerdeki ilerlemesini takip eder. Oyuncuların cezalarını duraklatmak için oyundan çıkma açığını önlemek adına, ceza bitiş süresini kalan bir süre yerine mutlak bir zaman damgası olarak saklayın; böylece oyuncu çevrimdışı olduğunda bile süre geri saymaya devam eder. Kayıt tutma amacıyla tutuklayan polis memuru, suçlamalar ve orijinal ceza süresi için alanlar ekleyin:

CREATE TABLE IF NOT EXISTS prison_sentences (
    id INT AUTO_INCREMENT PRIMARY KEY,
    citizenid VARCHAR(50) NOT NULL,
    sentence_minutes INT NOT NULL,
    time_served INT DEFAULT 0,
    reduction_earned INT DEFAULT 0,
    jailed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    release_at TIMESTAMP NOT NULL,
    charges TEXT DEFAULT NULL,
    arresting_officer VARCHAR(50) DEFAULT NULL,
    status ENUM('active', 'released', 'escaped', 'pardoned') DEFAULT 'active',
    parole_eligible BOOLEAN DEFAULT FALSE,
    INDEX idx_citizen (citizenid),
    INDEX idx_status (status)
);

CREATE TABLE IF NOT EXISTS prison_activity_log (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    citizenid VARCHAR(50) NOT NULL,
    sentence_id INT NOT NULL,
    activity_type ENUM('mining', 'gym', 'cleaning', 'library', 'yard') NOT NULL,
    reduction_minutes INT DEFAULT 0,
    completed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (sentence_id) REFERENCES prison_sentences(id)
);

Bir Oyuncuyu Cezalandırma

Polis hapis komutunu kullandığında sunucu memurun yetkilerini doğrular, suçlamalara göre cezayı hesaplar, mahkumun silahlarını ve yasa dışı eşyalarını alır ve onu hapishane içindeki bir doğma noktasına ışınlar. Ceza, sunucu yeniden başlatmalarında kaybolmaması için derhal veritabanına kaydedilmelidir. Ceza vermeyi yalnızca yetkili polis memurlarının çalıştırabileceği bir sunucu tarafı komutu olarak uygulayın:

RegisterCommand('jail', function(source, args)
    local src = source
    local Officer = QBCore.Functions.GetPlayer(src)
    if not Officer then return end

    -- Check police job
    if Officer.PlayerData.job.name ~= 'police' then
        TriggerClientEvent('QBCore:Notify', src, 'Unauthorized', 'error')
        return
    end

    local targetId = tonumber(args[1])
    local minutes = tonumber(args[2])
    local charges = table.concat(args, ' ', 3)

    if not targetId or not minutes or minutes <= 0 then
        TriggerClientEvent('QBCore:Notify', src, 'Usage: /jail [id] [minutes] [charges]', 'error')
        return
    end

    local Target = QBCore.Functions.GetPlayer(targetId)
    if not Target then
        TriggerClientEvent('QBCore:Notify', src, 'Player not found', 'error')
        return
    end

    local citizenid = Target.PlayerData.citizenid
    local releaseAt = os.date('!%Y-%m-%d %H:%M:%S', os.time() + (minutes * 60))

    -- Insert sentence
    local sentenceId = MySQL.insert.await(
        'INSERT INTO prison_sentences (citizenid, sentence_minutes, release_at, charges, arresting_officer) VALUES (?, ?, ?, ?, ?)',
        { citizenid, minutes, releaseAt, charges, Officer.PlayerData.citizenid }
    )

    -- Strip weapons and contraband
    local contraband = {'weapon_pistol', 'weapon_smg', 'lockpick', 'thermite'}
    for _, item in ipairs(contraband) do
        local playerItem = Target.Functions.GetItemByName(item)
        if playerItem then
            Target.Functions.RemoveItem(item, playerItem.amount)
        end
    end

    -- Set jail metadata and teleport
    Target.Functions.SetMetaData('injail', sentenceId)
    TriggerClientEvent('prison:client:enter', targetId, sentenceId, minutes)
    TriggerClientEvent('QBCore:Notify', src, 'Jailed ' .. GetPlayerName(targetId) .. ' for ' .. minutes .. ' minutes', 'success')
end, false)

Hapishane Aktiviteleri

Hapishane aktiviteleri, mahkum oyuncuların oyunda kalmasını sağlayan temel oynanış döngüsüdür. Bunlar olmadan hapis süresi, oyuncuları oyundan çıkmaya iten bir cezaya dönüşür ve bu da sunucu nüfusu için kötüdür. Bir denge sunan aktiviteler tasarlayın: emek sarf etmek cezayı azaltır ve mahkumlara kendi deneyimleri üzerinde kontrol hakkı verir. Spam yapılmasını önlemek için her aktivitenin bir bekleme süresi ve aktivite döngüsü başına maksimum azaltma sınırı olmalıdır; böylece 60 dakikalık bir ceza 5 dakikada silinemez. En yaygın aktiviteler taş ocağında madencilik, spor salonunda egzersiz, tesisi temizleme ve hapishane kütüphanesinde vakit geçirmektir. Her aktivite çeşitlilik sağlamak adına farklı bir minigame veya etkileşim modeli kullanır:

Config.PrisonActivities = {
    mining = {
        label = 'Quarry Mining',
        coords = vector3(1690.64, 2592.63, 45.56),
        radius = 15.0,
        reductionPerCycle = 2,   -- minutes reduced per completion
        cycleDuration = 45,       -- seconds per mining cycle
        cooldown = 30,            -- seconds between cycles
        maxReductionPerSession = 10,
        animation = { dict = 'amb@world_human_hammering@male@base', anim = 'base' },
        requiredProp = 'prop_tool_pickaxe',
    },
    gym = {
        label = 'Prison Gym',
        coords = vector3(1662.67, 2527.84, 45.56),
        radius = 10.0,
        reductionPerCycle = 1,
        cycleDuration = 30,
        cooldown = 60,
        maxReductionPerSession = 6,
        animation = { dict = 'amb@world_human_muscle_free_weights@male@barbell@base', anim = 'base' },
    },
    cleaning = {
        label = 'Facility Cleaning',
        coords = vector3(1653.18, 2499.26, 45.56),
        radius = 20.0,
        reductionPerCycle = 1,
        cycleDuration = 25,
        cooldown = 20,
        maxReductionPerSession = 8,
        animation = { dict = 'amb@world_human_janitor@male@base', anim = 'base' },
        requiredProp = 'prop_cs_broom',
    },
    library = {
        label = 'Prison Library',
        coords = vector3(1680.21, 2513.45, 45.56),
        radius = 8.0,
        reductionPerCycle = 1,
        cycleDuration = 60,
        cooldown = 45,
        maxReductionPerSession = 4,
        animation = { dict = 'amb@world_human_clipboard@male@base', anim = 'base' },
    },
}

-- Server-side activity completion handler
RegisterNetEvent('prison:server:completeActivity', function(activityType, sentenceId)
    local src = source
    local Player = QBCore.Functions.GetPlayer(src)
    if not Player then return end

    local citizenid = Player.PlayerData.citizenid
    local activity = Config.PrisonActivities[activityType]
    if not activity then return end

    -- Validate sentence is active
    local sentence = MySQL.single.await(
        'SELECT * FROM prison_sentences WHERE id = ? AND citizenid = ? AND status = "active"',
        { sentenceId, citizenid }
    )
    if not sentence then return end

    -- Check session reduction cap
    local sessionReduction = MySQL.scalar.await(
        'SELECT COALESCE(SUM(reduction_minutes), 0) FROM prison_activity_log WHERE sentence_id = ? AND activity_type = ? AND completed_at > DATE_SUB(NOW(), INTERVAL 1 HOUR)',
        { sentenceId, activityType }
    )
    if sessionReduction >= activity.maxReductionPerSession then
        TriggerClientEvent('QBCore:Notify', src, 'Maximum reduction reached for this activity', 'error')
        return
    end

    -- Apply reduction
    local reduction = activity.reductionPerCycle
    MySQL.update('UPDATE prison_sentences SET reduction_earned = reduction_earned + ?, release_at = DATE_SUB(release_at, INTERVAL ? MINUTE) WHERE id = ?',
        { reduction, reduction, sentenceId })

    MySQL.insert('INSERT INTO prison_activity_log (citizenid, sentence_id, activity_type, reduction_minutes) VALUES (?, ?, ?, ?)',
        { citizenid, sentenceId, activityType, reduction })

    TriggerClientEvent('QBCore:Notify', src, 'Sentence reduced by ' .. reduction .. ' minute(s)', 'success')
    TriggerClientEvent('prison:client:updateTimer', src, reduction)
end)

Şartlı Tahliye Sistemi

Şartlı tahliye sistemi, hapishane ile tam özgürlük arasına bir roleplay katmanı ekler. Bir mahkum cezasının yapılandırılabilir bir yüzdesini (genellikle %60 ila %75) tamamladığında şartlı tahliyeye hak kazanır. Şartlı tahliye, bir hakim veya kıdemli polis memuru tarafından bir komutla verilebilir; bu da oyuncuyu erken serbest bırakır ancak kısıtlamalar altına sokar. Şartlı tahliye edilen oyuncuların belirli saatler arasında mülklerinde bulunmalarını gerektiren bir sokağa çıkma yasağı, düzenli aralıklarla bir şartlı tahliye memuruna imza verme zorunluluğu ve silah bulundurma veya belirli alanlara girme yasakları olabilir. Şartlı tahliye edilen bir oyuncu herhangi bir koşulu ihlal ederse, kalan cezası ve ihlal için ek süre ile birlikte otomatik olarak hapishaneye geri gönderilir. Şartlı tahliye durumunu oyuncu meta verilerinde takip edin ve koşullara uyumu doğrulamak için sunucuda periyodik kontroller çalıştırın.

Hapishaneden Kaçış Etkinlikleri

Hapishaneden kaçışlar, hem suçlular hem de kolluk kuvvetleri için yüksek tansiyonlu rol yapma fırsatı yaratan sunucu genelindeki etkinliklerdir. Bir hapishane firarı ciddi bir hazırlık, birden fazla katılımcı gerektirmeli ve polise karşılık verebilmesi için yeterli uyarıyı vermelidir. Bunu çok aşamalı bir etkinlik olarak kurgulayın: dışarıdaki bir ekip öncelikle helikopter, patlayıcılar ve kılık değiştirme ekipmanları gibi belirli eşyaları temin etmelidir. Ardından dış kontrol panelindeki zorlu bir minigame ile hapishane güvenlik sistemini hacklemelidirler. Güvenlik devre dışı kaldığında, hücre kapıları sınırlı bir süre için açılır ve gardiyan NPC'ler ile müdahale eden polisler onları durdurmaya çalışırken mahkumlar önceden belirlenmiş rotalardan kaçmaya çalışabilir. Adil bir müdahale sağlamak adına sistem yalnızca çevrim içi minimum sayıda polis memuru olduğunda hapishaneden kaçışlara izin vermelidir:

Config.PrisonBreak = {
    minPoliceOnline = 5,
    cooldown = 28800, -- 8 hours between break attempts
    requiredItems = {
        { name = 'electronickit', amount = 2, label = 'Electronic Kit' },
        { name = 'thermite', amount = 3, label = 'Thermite Charge' },
    },
    phases = {
        {
            name = 'hack_security',
            label = 'Hack Security Grid',
            coords = vector3(1746.23, 2488.90, 45.80),
            duration = 60,
            minigame = { type = 'hack', difficulty = 'hard', attempts = 3 },
        },
        {
            name = 'breach_wall',
            label = 'Breach Perimeter Wall',
            coords = vector3(1651.78, 2569.33, 45.56),
            duration = 30,
            minigame = { type = 'thermite', time = 10 },
        },
        {
            name = 'disable_lockdown',
            label = 'Disable Lockdown Protocol',
            coords = vector3(1691.45, 2565.12, 45.56),
            duration = 45,
            minigame = { type = 'hack', difficulty = 'expert', attempts = 2 },
        },
    },
    escapeWindow = 300, -- 5 minutes to escape after all phases complete
    escapeRoutes = {
        { label = 'Main Gate', coords = vector3(1845.12, 2585.87, 45.67) },
        { label = 'Drainage Tunnel', coords = vector3(1617.34, 2523.90, 44.12) },
        { label = 'Helipad', coords = vector3(1700.89, 2565.34, 52.34) },
    },
}

Gardiyan NPC Sistemi

Gardiyan NPC'leri hapishane çevresinde genel güvenlik sağlar ve mahkumların öylece dışarı çıkmasını önler. Gardiyanları ana kapı, hücre bloğu girişleri ve çevre duvarı gibi kritik noktalara yerleştirin. Her gardiyanın sırayla geçtiği rota noktalarına sahip bir devriye rotası olmalı ve bu sayede belirli alanların korunmasız kaldığı zaman pencereleri oluşturulmalıdır. Gardiyanlar yetkili bölgeleri terk eden mahkumları tespit eder ve sözlü uyarıda bulunur, mahkum uymazsa takip edip saldırır. Mahkumların siper arkasında kalarak gardiyanları gizlice geçebilmesi için görüş hattını hesaba katan yakınlık kontrolleri kullanarak gardiyan tespitini uygulayın. Bir hapishaneden kaçış etkinliği sırasında kritik konumlarda ek gardiyanlar spawn edin ve saldırganlık seviyelerini artırın. Şu FiveM native fonksiyonlarını kullanın: TaskPatrol ve SetPedCombatAttributes gardiyanlara gerçekçi devriye davranışı kazandırmak için. İlişki gruplarını mahkumlara karşı düşmanca, polislere ve ziyaretçilere karşı tarafsız olacak şekilde ayarladığınızdan emin olun, böylece hapishaneden kaçış müdahaleleri sırasında dost ateşi olaylarının önüne geçersiniz.

Sınır Denetimi ve Serbest Bırakma

Sınır sistemi, tüm tesisi kapsayan bir poligon bölgesi kullanarak mahkumları hapishane sınırları içinde tutar. Aktif cezası bulunan bir oyuncu bu bölgenin dışına çıktığında bir uyarı bildirimi alır ve firar teşebbüsü cezası olarak cezasına ek süre eklenip hapishane doğma noktasına geri ışınlanmadan önce geri dönmek için 10 saniyesi olur. İstemci tarafında, oyuncunun konumunu hapishane sınır poligonu ile karşılaştıran her 2 saniyede bir periyodik kontrol çalıştırın. Tahliye işlemi için sunucu, her 30 saniyede bir tüm aktif cezaları kontrol eden bir zamanlayıcı döngüsü yürütür. Ceza süresi dolduğunda sistem veritabanı durumunu tahliye edildi olarak günceller, oyuncunun hapis meta verilerini temizler, uyguladıysanız envanterini hapis öncesi yedekten geri yükler ve serbest kaldıklarına dair bir bildirimle onları hapishane çıkışına ışınlar. Ceza süresi dolduğunda oyuncu çevrimdışıysa tahliye, oyuncu yükleme etkinliğinde süresi dolmuş aktif cezalar kontrol edilerek bir sonraki girişinde işlenir. Haksız yere hapis cezası veya rol yoluyla müzakere edilen anlaşmalar gibi durumlar için polisin oyuncuları erkenden manuel olarak serbest bırakabileceği bir komut ekleyin.

Polis ve Hukuk Sistemleriyle Entegrasyon

Hapishane sisteminiz, polis MDT'si ve sunucudaki herhangi bir mahkeme sistemiyle sıkı bir şekilde entegre olmalıdır. Bir oyuncu hapse atıldığında, MDT'deki sabıka kaydı suçlamalar, ceza süresi ve tutuklayan memur bilgileriyle otomatik olarak güncellenmelidir. Sunucunuzda bir mahkeme sistemi varsa, tutarlılığı sağlamak için bir yargıç tarafından verilen cezalar aynı jailing fonksiyonu üzerinden akmalıdır. Mahkumların hapishane kütüphanesinden yargıçların incelemesi için bir talep oluşturan ve potansiyel olarak ceza indirimine veya erken tahliyeye yol açabilecek bir ceza itirazı gönderebileceği bir itiraz sistemi kurun. Her vatandaşın kaç kez hapse girdiğini sayarak mükerrer suçları takip edin ve bir çarpan sistemi aracılığıyla mükerrer suçlulara daha ağır cezalar uygulamak için bu verileri kullanın. Mahkeme sistemi, otomatik suç tespiti veya yönetici komutları gibi diğer kaynakların tümünün oyuncuları aynı doğrulanmış yol üzerinden cezaevine gönderebilmesi için jailing fonksiyonunuzu export edin.

Başlamaya Hazır mısınız?

Scriptleri mağazamızdan edinin veya destek, güncellemeler ve gelecek yeniliklere göz atmak için Discord'a katılın.