FiveM Emlak Sistemi: Emlakçı Meslekleri ve Mülk Satışları
FiveM sunucunuzda bir emlak ekonomisi başlatın. QBCore ve ESX sunucuları için ilanlar, açık evler, komisyonlar ve en iyi emlak scriptleri.
Agency Scripts
Agency Scripts Kurucusu ve Baş Geliştiricisi
Mülk Sistemi Mimarisi
Bir emlak sistemi, FiveM sunucunuzu erişilemeyen binalar topluluğundan, oyuncuların ev, daire ve ticari alan satın aldığı, sattığı ve kiraladığı canlı bir mülk piyasasına dönüştürür. Mimari, sunucudaki her uygun mülkü konumu, türü, mevcut sahibi, piyasa değeri ve interior yapılandırmasıyla takip eden bir mülk kayıt veritabanı etrafında toplanır. Oyuncuların yalnızca önceden belirlenmiş bir mülk listesini satın almasına izin veren basit konut scriptlerinin aksine, iyi tasarlanmış bir emlak sistemi yer göstermeler, pazarlıklar ve komisyon yapılarıyla oyuncu odaklı işlemler oluşturan bir emlakçı mesleği içerir. Sistemin, mülk sahipliğinin fiziksel binaya erişimi otomatik olarak vermesi veya iptal etmesi için sunucunuzun door lock kaynağıyla ve özel MLO'lar veya instanced interior'lar gibi interior yükleme sistemleriyle entegre olması gerekir. En başından itibaren üç mülk kategorisi planlayın: oyuncu konutları için konut mülkleri, oyuncuların sahip olduğu işletmeler için ticari mülkler ve mülk sahipleri için pasif gelir sağlayan kiralık mülkler.
Mülk Veritabanı ve İlanları
Mülk veritabanı, diğer tüm bileşenlerin üzerine inşa edildiği temeldir. Her mülk kaydı, kullandığı shell veya MLO iç mekanı, giriş ve çıkış koordinatları, garaj durumu, depolama kapasitesi ve fiyat geçmişi dahil olmak üzere kapsamlı meta verilere ihtiyaç duyar. Şu anda piyasada olan mülkleri, talep edilen fiyatlarını, ilan emlakçısını ve ne kadar süredir listelendiklerini takip eden ayrı bir ilan tablosu tutun. Bu ayrım, piyasa geçmişini izlemenize ve zaman içindeki mülk değeri trendlerini hesaplamanıza olanak tanır. İşte tüm emlak yaşam döngüsünü destekleyen bir veritabanı şeması:
CREATE TABLE IF NOT EXISTS properties (
id INT AUTO_INCREMENT PRIMARY KEY,
property_id VARCHAR(50) NOT NULL UNIQUE,
label VARCHAR(100) NOT NULL,
property_type ENUM('house', 'apartment', 'commercial', 'penthouse') NOT NULL,
owner VARCHAR(50) DEFAULT NULL,
price INT NOT NULL,
original_price INT NOT NULL,
interior VARCHAR(50) DEFAULT 'standard_1bed',
enter_coords JSON NOT NULL,
exit_coords JSON DEFAULT NULL,
garage_slots INT DEFAULT 0,
stash_slots INT DEFAULT 50,
has_wardrobe TINYINT DEFAULT 1,
is_furnished TINYINT DEFAULT 1,
neighborhood VARCHAR(50) DEFAULT 'downtown',
purchased_at BIGINT DEFAULT NULL,
INDEX idx_owner (owner),
INDEX idx_type (property_type),
INDEX idx_neighborhood (neighborhood)
);
CREATE TABLE IF NOT EXISTS property_listings (
id INT AUTO_INCREMENT PRIMARY KEY,
property_id VARCHAR(50) NOT NULL,
asking_price INT NOT NULL,
listing_agent VARCHAR(50) DEFAULT NULL,
listed_at BIGINT NOT NULL,
status ENUM('active', 'pending', 'sold', 'cancelled') DEFAULT 'active',
buyer VARCHAR(50) DEFAULT NULL,
sold_at BIGINT DEFAULT NULL,
sold_price INT DEFAULT NULL,
INDEX idx_status (status),
INDEX idx_agent (listing_agent)
);
İlk kurulum sırasında properties tablosunu sunucunuzdaki tüm mevcut mülklerle doldurun. Her mülk, kapı konumları veya etkileşim bölgeleriyle hizalanmış giriş noktaları için dikkatle ayarlanmış koordinatlara sahip olmalıdır. Bu original_price alanı piyasa hesaplamaları için taban değeri korurken price alanı; mahalle talebine, mülk sahibi tarafından yapılan iyileştirmelere ve genel sunucu ekonomik koşullarına göre değişen mevcut piyasa değerini yansıtır.
Emlakçı Meslek Sistemi
Emlakçı mesleği, insan faktörünün bu sistemi öne çıkardığı yerdir. Emlakçılar alıcılar ve satıcılar arasında aracı olarak hareket eder, mülk gösterimleri yapar, fiyat pazarlığı yürütür ve tamamlanan satışlardan komisyon kazanır. Kademeli olarak daha iyi ilanların kilidini açan meslek kademeleri tanımlayın: stajyer emlakçılar daireler ve küçük evlerle ilgilenir, kıdemli emlakçılar lüks mülklere ve ticari alanlara erişir, ajans sahibi ise ekibi yönetip tüm komisyonlardan pay alır. Mülk satın almakla ilgilenen bir oyuncu bir emlakçıyla iletişime geçtiğinde, emlakçı her iki oyuncuyu da inceleme için mülkün içine ışınlayan bir gösterim başlatabilir. İşte gösterim ve satış işlemi mantığı:
RegisterNetEvent('realestate:server:startShowing', function(propertyId, buyerId)
local src = source
local Agent = QBCore.Functions.GetPlayer(src)
local Buyer = QBCore.Functions.GetPlayer(buyerId)
if not Agent or not Buyer then return end
if Agent.PlayerData.job.name ~= 'realtor' then return end
local property = MySQL.query.await(
'SELECT * FROM properties WHERE property_id = ? AND owner IS NULL',
{propertyId}
)
if not property or not property[1] then
return TriggerClientEvent('QBCore:Notify', src, 'Property not available', 'error')
end
local prop = property[1]
local enterCoords = json.decode(prop.enter_coords)
-- Teleport both to property
TriggerClientEvent('realestate:client:enterShowing', src, prop, enterCoords)
TriggerClientEvent('realestate:client:enterShowing', buyerId, prop, enterCoords)
TriggerClientEvent('QBCore:Notify', buyerId,
'Showing: ' .. prop.label .. ' - $' .. prop.price, 'info')
end)
RegisterNetEvent('realestate:server:purchaseProperty', function(propertyId, buyerId, agreedPrice)
local src = source
local Agent = QBCore.Functions.GetPlayer(src)
local Buyer = QBCore.Functions.GetPlayer(buyerId)
if not Agent or not Buyer then return end
if Agent.PlayerData.job.name ~= 'realtor' then return end
local property = MySQL.query.await(
'SELECT * FROM properties WHERE property_id = ? AND owner IS NULL',
{propertyId}
)
if not property or not property[1] then return end
if not Buyer.Functions.RemoveMoney('bank', agreedPrice, 'property-purchase') then
return TriggerClientEvent('QBCore:Notify', src, 'Buyer cannot afford this', 'error')
end
local commission = math.floor(agreedPrice * 0.05)
Agent.Functions.AddMoney('bank', commission, 'realtor-commission')
MySQL.update(
'UPDATE properties SET owner = ?, price = ?, purchased_at = ? WHERE property_id = ?',
{Buyer.PlayerData.citizenid, agreedPrice, os.time(), propertyId}
)
MySQL.update(
'UPDATE property_listings SET status = "sold", buyer = ?, sold_at = ?, sold_price = ? WHERE property_id = ? AND status = "active"',
{Buyer.PlayerData.citizenid, os.time(), agreedPrice, propertyId}
)
TriggerClientEvent('QBCore:Notify', src,
'Sale complete! Commission: $' .. commission, 'success')
TriggerClientEvent('QBCore:Notify', buyerId,
'Congratulations! You now own ' .. property[1].label, 'success')
TriggerEvent('doorlock:server:updateProperty', propertyId, Buyer.PlayerData.citizenid)
end)
Komisyon oranı yapılandırılabilir olmalı ve potansiyel olarak emlakçının kademe seviyesine göre değişkenlik gösterebilmelidir. Kıdemli emlakçılar %7 komisyon kazanırken stajyerler yalnızca %3 kazanabilir, bu da emlakçılık mesleği içinde kariyer ilerlemesini motive eder. Performans liderlik tabloları oluşturmak ve en iyi performans gösterenler için bonusların kilidini açmak adına her emlakçının toplam satış hacmini ve komisyon kazancını veritabanında takip edin.
İpotek ve Finansman Sistemi
Çoğu oyuncu yüksek değerli mülkleri peşin satın alamaz, bu nedenle bir ipotek sistemi potansiyel alıcı havuzunu ciddi oranda artırır ve mülk piyasasını yeni oyuncular için erişilebilir kılar. Bir alıcı bedelin tamamını ödeyemediğinde, mülk değerinin genellikle %10-20'si kadar yapılandırılabilir bir peşinat yüzdesi gerektiren bir ipotek seçeneği sunun. Kalan bakiye, her sunucu yeniden başlatmasında veya planlanan aralıklarla oyuncunun banka hesabından otomatik olarak düşülen düzenli taksitlerle ödenir. Anapara tutarı, faiz oranı, kalan bakiye, aylık ödeme tutarı ve ödeme geçmişi dahil ipotek ayrıntılarını takip edin. Bir oyuncu arka arkaya çok fazla ödemeyi kaçırırsa, mülke el koyan ve onu indirimli olarak piyasada yeniden listeleyen bir haciz süreci başlatın. Faiz oranı, borçlanmaya gerçek bir maliyet getirerek oyuncuları mümkün olduğunda ipoteklerini erken kapatmaya teşvik eder ve sistem, sunucu ekonomisindeki enflasyonla mücadeleye yardımcı olan düzenli bir para çıkışı sağlar.
Kira Geliri ve Ev Sahibi Sistemi
Birden fazla mülke sahip olan oyuncular, sürekli bir rol yapma ortamı oluşturan ev sahibi ve kiracı dinamiği yaratarak bunları pasif gelir elde etmek için kiralayabilmelidir. Bir mülk sahibi mülkünü kiralamak istediğinde aylık kira bedelini belirler ve emlak acentesi veya doğrudan ilan aracılığıyla kiralık olarak listeler. Kiracılar mülke anahtar erişimi elde eder ve kira süreleri boyunca mülkün deposunu, gardırobunu ve garajını kullanabilir. Kira, yapılandırılabilir bir takvime göre otomatik olarak tahsil edilir ve ev sahibinin banka hesabına yatırılır. İşte kiralama sistemi uygulaması:
Config.RentalSettings = {
minRentPrice = 100,
maxRentPrice = 50000,
collectionInterval = 86400, -- every 24 hours real time
maxMissedPayments = 3,
depositMultiplier = 2, -- security deposit = 2x monthly rent
}
RegisterNetEvent('realestate:server:listForRent', function(propertyId, rentPrice)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
local property = MySQL.query.await(
'SELECT * FROM properties WHERE property_id = ? AND owner = ?',
{propertyId, Player.PlayerData.citizenid}
)
if not property or not property[1] then return end
if rentPrice < Config.RentalSettings.minRentPrice or
rentPrice > Config.RentalSettings.maxRentPrice then
return TriggerClientEvent('QBCore:Notify', src, 'Invalid rent price', 'error')
end
MySQL.insert(
'INSERT INTO property_rentals (property_id, landlord, rent_price, deposit, listed_at) VALUES (?, ?, ?, ?, ?)',
{propertyId, Player.PlayerData.citizenid, rentPrice,
rentPrice * Config.RentalSettings.depositMultiplier, os.time()}
)
TriggerClientEvent('QBCore:Notify', src,
'Property listed for rent at $' .. rentPrice .. '/day', 'success')
end)
-- Automated rent collection thread
CreateThread(function()
while true do
Wait(1000 * 60 * 60) -- Check every hour
local rentals = MySQL.query.await(
'SELECT * FROM property_rentals WHERE tenant IS NOT NULL AND status = "active"'
)
for _, rental in ipairs(rentals or {}) do
if os.time() - rental.last_collected >= Config.RentalSettings.collectionInterval then
local success = ProcessRentPayment(rental)
if not success then
HandleMissedPayment(rental)
end
end
end
end
end)
Güvence bedeli, mülk sahiplerini mülke zarar veren veya haber vermeden ayrılan kiracılara karşı korur. Bir kiracı kira sözleşmesini sonlandırdığında, depozito hasar kesintileri düşülerek iade edilir. Aşınma ve yıpranmayı takip eden bir mülk durumu sistemi uygulayarak, kiracının mülke özen göstermemesi durumunda mülk sahiplerine depozitonun bir kısmını kesmek için meşru bir neden sağlayın. Bu, mülk sahipleri ve kiracılar arasında rol yapmayı teşvik eden doğal anlaşmazlık çözümü senaryoları yaratır.
Dinamik Piyasa Fiyatlandırması
Statik bir mülk piyasası, talep gören her mülk satın alındığında hızla sıkıcı hale gelir. Dinamik fiyatlandırma, mülk değerlerini sunucudaki gerçek hareketliliğe göre ayarlayarak piyasayı ilgi çekici tutar. Mahalle değerini etkileyen birkaç faktörü takip edin: bir bölgedeki son satışların sayısı, iş merkezleri ve dükkanlar gibi popüler konumlara yakınlık, polis sisteminden alınan suç istatistikleri ve dolu mülklerin boş mülklere genel oranı. Bir mahallede çok sayıda yeni satın alımla yüksek talep olduğunda mülk değerleri kademeli olarak artar; bu da gelişmekte olan bölgelerdeki ilk alıcıların mahalle geliştikçe kâr ettiği spekülatif bir unsur yaratır. Aksine, suç oranı yüksek alanlar veya çok sayıda boş mülk bulunan mahalleler değer kaybı yaşar. Piyasa ayarlamasını, ani piyasa şoklarını önlemek amacıyla değişiklikleri kademeli olarak uygulayarak tüm mülk değerlerini haftalık olarak yeniden hesaplayan planlanmış bir sunucu görevi olarak çalıştırın. Emlakçıların ve alıcıların nereye yatırım yapacakları konusunda bilinçli kararlar verebilmeleri için piyasa trendlerini emlak ajansının NUI panelinde görüntüleyin.
Mülk Gösterimleri ve NUI Arayüzü
NUI arayüzü, emlakçıların ve alıcıların mevcut mülklere göz attığı, detayları incelediği ve işlemleri başlattığı alandır. Mevcut her mülkü fotoğrafı veya iç mekan önizlemesi, haritadaki konumu, fiyatı, oda sayısı, garaj kapasitesi ve mahalle puanıyla gösteren temiz ve profesyonel görünümlü bir emlak listeleme sayfası oluşturun. Kullanıcıların sonuçları mülk türü, fiyat aralığı ve konuma göre daraltabilmesi için filtreleme ve sıralama seçenekleri ekleyin. Bir emlakçı gösterim için bir mülk seçtiğinde sistem mülkün girişine giden bir rota göstermeli ve alıcıya takip etmesi için bildirim göndermelidir. Mülkün içinde emlakçının 3D işaretçiler veya metin açıklamaları kullanarak özellikleri vurgulayabileceği etkileşimli bir tur modu sağlayın. Gösterimden sonra alıcıya fiyat, vergiler, emlakçı komisyonu ve varsa ipotek koşullarını içeren eksiksiz mali dökümü gösteren bir satın alma veya kiralama onay paneli sunun. Arayüz ayrıca tam mali şeffaflık sağlamak adına oyuncuların geçmiş satın alma, satış ve kira ödemelerini inceleyebilecekleri bir işlem geçmişi sekmesi içermelidir.
Mülk Özelleştirme ve Değer Artışı
Mülk sahiplerinin mülklerini özelleştirmelerine izin vermek kişisel bir dokunuş katar ve zamanla mülk değerlerini artıran bir geliştirme ekonomisi oluşturur. GTA Online'ın daire özelleştirmesini ele alışına benzer şekilde, oyuncuların mülklerinin içine mobilya satın alıp yerleştirmelerini sağlayan bir mobilya yerleştirme sistemi kurun. Satın alınan her mobilya mülkün geliştirilmiş değerini artırır, böylece mülk sahibi sattığında mobilya yatırımının bir kısmını geri kazanır. Mobilyaların ötesinde, mülkün taban değerini belirli bir yüzde oranında artıran mutfak tadilatları, banyo yenilemeleri ve güvenlik sistemi kurulumları gibi yapısal geliştirmeler sunun. Tüm geliştirmeleri bir mülk modifikasyonları tablosunda takip edin, böylece emlak ilanı potansiyel alıcılara tam olarak hangi geliştirmelerin yapıldığını gösterebilir. Ticari mülkler; bir dükkan için vitrinler, bir restoran için mutfak ekipmanları veya bir teknoloji şirketi için sunucu rafları gibi işletmeye özel geliştirmeleri desteklemeli ve mülk sistemini daha geniş ticari oyun döngüsüne bağlamalıdır. Konum tabanlı piyasa dinamikleri ile oyuncu odaklı geliştirmelerin birleşimi, gayrimenkulün sadece eşya saklanan ve kıyafet değiştirilen bir yer olmaktan çıkıp meşru bir servet edinme stratejisine dönüştüğü zengin bir mülk ekosistemi yaratır.