Por que os sistemas de aluguel melhoram a dramatização
Nem todo jogador em um servidor de roleplay possui um veículo, especialmente personagens novos que estão apenas começando. Um sistema de aluguel de carros e bicicletas preenche essa lacuna, fornecendo transporte temporário a preços acessíveis, criando oportunidades naturais de roleplay nos balcões de aluguel e dando aos novos jogadores liberdade para explorar o mapa sem depender de transporte público ou caminhar. Além do transporte básico, os sistemas de aluguel apoiam a dramatização turística, onde os visitantes alugam conversíveis para passeios panorâmicos, trabalhos de entrega que exigem tipos de veículos específicos e cenários de eventos onde os jogadores precisam de veículos correspondentes para cruzeiros ou corridas organizadas. O sistema também gera um fluxo de receita passivo para a economia do servidor por meio de taxas de aluguel, depósitos contra danos e multas por devolução atrasada.
Configuração de Frota e Categorias de Veículos
Organize sua frota de aluguel em categorias que atendam às diferentes necessidades e orçamentos dos jogadores. Os veículos econômicos oferecem transporte básico acessível, os carros de médio porte oferecem mais conforto e desempenho, os veículos premium oferecem experiências luxuosas e as motocicletas oferecem aos jogadores uma alternativa de duas rodas. Cada categoria deve ter múltiplas opções de veículos com preços claros. Inclua taxas de aluguel por hora e diárias para que os jogadores possam escolher a opção mais econômica para suas necessidades. Defina a frota em uma tabela de configuração que especifica cada veículo disponível com seu preço de aluguel, depósito obrigatório, categoria e modelo de spawn:
Config.RentalLocations = {
['airport'] = {
label = 'LS Airport Car Rental',
pedModel = 's_f_y_airhostess_01',
pedCoords = vector4(-1037.34, -2736.82, 20.17, 238.52),
spawnPoint = vector4(-1029.12, -2728.91, 20.17, 148.76),
returnZone = vector3(-1035.00, -2730.00, 20.17),
returnRadius = 10.0,
categories = {'economy', 'midrange', 'premium', 'motorcycle'},
},
['downtown'] = {
label = 'Downtown Bike Rental',
pedModel = 'a_m_y_business_02',
pedCoords = vector4(-259.68, -892.41, 31.08, 69.24),
spawnPoint = vector4(-264.30, -888.12, 31.08, 339.87),
returnZone = vector3(-260.00, -890.00, 31.08),
returnRadius = 8.0,
categories = {'motorcycle', 'bicycle'},
},
}
Config.RentalFleet = {
economy = {
{model = 'blista', label = 'Blista', priceHour = 150, priceDay = 800, deposit = 500},
{model = 'asea', label = 'Asea', priceHour = 120, priceDay = 650, deposit = 400},
{model = 'stanier', label = 'Stanier', priceHour = 130, priceDay = 700, deposit = 450},
},
midrange = {
{model = 'schafter2', label = 'Schafter', priceHour = 300, priceDay = 1600, deposit = 1000},
{model = 'oracle', label = 'Oracle', priceHour = 280, priceDay = 1500, deposit = 900},
},
premium = {
{model = 'felon', label = 'Felon GT', priceHour = 600, priceDay = 3200, deposit = 2500},
{model = 'exemplar', label = 'Exemplar', priceHour = 550, priceDay = 3000, deposit = 2000},
},
motorcycle = {
{model = 'pcj', label = 'PCJ-600', priceHour = 100, priceDay = 500, deposit = 300},
{model = 'sanchez', label = 'Sanchez', priceHour = 80, priceDay = 400, deposit = 250},
},
bicycle = {
{model = 'cruiser', label = 'Cruiser Bike', priceHour = 30, priceDay = 150, deposit = 50},
{model = 'tribike', label = 'Tri-Cycles Race', priceHour = 25, priceDay = 120, deposit = 50},
},
}Processo de locação e interface NUI
A interação de aluguel começa quando um jogador se aproxima do NPC do balcão de aluguel. Usando um sistema de destino ou verificação de proximidade, abra um menu NUI que exibe as categorias de veículos disponíveis com opções de filtragem. Cada listagem de veículo deve mostrar o nome do modelo, uma visualização da imagem, se possível, taxas horárias e diárias, o depósito exigido e o status de disponibilidade. Quando o jogador seleciona um veículo e confirma a duração do aluguel, o servidor processa a transação. A cobrança total é a taxa de aluguel pela duração selecionada mais o depósito caução. O depósito é retido pelo sistema e reembolsado quando o veículo é devolvido sem danos. Implemente a confirmação de aluguel como um evento de servidor que valida se o jogador tem fundos suficientes, verifica se o veículo selecionado está disponível, cobra o jogador e gera o veículo alugado no ponto de spawn designado:
RegisterNetEvent('rental:server:rentVehicle', function(locationId, vehicleModel, duration)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
local location = Config.RentalLocations[locationId]
if not location then return end
-- Check if player already has an active rental
if ActiveRentals[Player.PlayerData.citizenid] then
TriggerClientEvent('QBCore:Notify', src, 'You already have an active rental', 'error')
return
end
-- Find vehicle config
local vehicleConfig = nil
for _, category in pairs(Config.RentalFleet) do
for _, v in ipairs(category) do
if v.model == vehicleModel then
vehicleConfig = v
break
end
end
if vehicleConfig then break end
end
if not vehicleConfig then return end
-- Calculate cost
local rentalFee = duration == 'day' and vehicleConfig.priceDay or vehicleConfig.priceHour
local totalCost = rentalFee + vehicleConfig.deposit
if Player.Functions.GetMoney('bank') < totalCost then
TriggerClientEvent('QBCore:Notify', src, 'Insufficient funds. Need $' .. totalCost, 'error')
return
end
-- Charge player
Player.Functions.RemoveMoney('bank', totalCost, 'vehicle-rental')
-- Generate rental plate
local plate = 'RNT' .. math.random(10000, 99999)
-- Store active rental
ActiveRentals[Player.PlayerData.citizenid] = {
model = vehicleModel,
plate = plate,
deposit = vehicleConfig.deposit,
rentalFee = rentalFee,
startTime = os.time(),
duration = duration,
expiresAt = os.time() + (duration == 'day' and 86400 or 3600),
locationId = locationId,
initialHealth = 1000,
}
TriggerClientEvent('rental:client:spawnVehicle', src, vehicleModel, plate, location.spawnPoint)
TriggerClientEvent('QBCore:Notify', src, 'Vehicle rented! Return before your time expires.', 'success')
end)Depósito de Danos e Mecânica de Retorno
O sistema de depósito de danos cria responsabilidade sobre como os jogadores tratam os veículos alugados. Quando o veículo for devolvido, compare seus valores de saúde atuais com os valores iniciais registrados no momento da locação. Os veículos GTA têm valores de integridade separados para o motor, carroceria e componentes individuais, proporcionando controle granular sobre a avaliação de danos. Calcule o custo do reparo com base nos danos sofridos e deduza-o do depósito antes de reembolsar o restante. Se o dano exceder o valor do depósito, o jogador não receberá nenhum reembolso e poderá ser cobrada uma taxa adicional. Se o veículo for devolvido em perfeitas condições, o depósito integral será reembolsado. Este sistema incentiva uma condução cuidadosa sem ser punitivo por pequenos arranhões que são inevitáveis na física de condução do GTA:
RegisterNetEvent('rental:server:returnVehicle', function(vehicleNet)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
local citizenid = Player.PlayerData.citizenid
local rental = ActiveRentals[citizenid]
if not rental then return end
local vehicle = NetworkGetEntityFromNetworkId(vehicleNet)
if not DoesEntityExist(vehicle) then return end
-- Check plate matches
local plate = GetVehicleNumberPlateText(vehicle)
if plate:trim() ~= rental.plate then
TriggerClientEvent('QBCore:Notify', src, 'This is not your rental vehicle', 'error')
return
end
-- Calculate damage
local bodyHealth = GetVehicleBodyHealth(vehicle)
local engineHealth = GetVehicleEngineHealth(vehicle)
local damagePercent = 1.0 - ((bodyHealth + engineHealth) / 2000.0)
local repairCost = math.floor(rental.deposit * damagePercent)
-- Calculate late fee
local lateFee = 0
if os.time() > rental.expiresAt then
local overHours = math.ceil((os.time() - rental.expiresAt) / 3600)
lateFee = overHours * 200
end
-- Refund deposit minus costs
local refund = math.max(0, rental.deposit - repairCost - lateFee)
if refund > 0 then
Player.Functions.AddMoney('bank', refund, 'rental-deposit-refund')
end
DeleteEntity(vehicle)
ActiveRentals[citizenid] = nil
local message = string.format('Vehicle returned. Deposit: $%d | Repairs: $%d | Late fee: $%d | Refund: $%d',
rental.deposit, repairCost, lateFee, refund)
TriggerClientEvent('QBCore:Notify', src, message, refund > 0 and 'success' or 'warning')
end)Sistema de expiração e retorno automático
Os veículos alugados não devem persistir indefinidamente. Implemente um sistema de cronômetro que rastreie quando cada aluguel expira e tome as medidas adequadas. Envie ao jogador uma notificação trinta minutos antes do vencimento, depois outra dez minutos e um aviso final cinco minutos. Quando o aluguel expirar, comece a cobrar taxas de atraso por minuto até um limite máximo. Se o jogador não devolver o veículo dentro do período de carência após o vencimento, o veículo desaparecerá automaticamente e perderá todo o depósito. Isso evita que veículos alugados abandonados sobrecarreguem o servidor. A verificação de expiração deve ser executada no servidor em intervalos regulares, iterando todos os aluguéis ativos e tomando as medidas apropriadas com base no tempo restante. Armazene o ID de rede do veículo para que você possa excluí-lo remotamente, se necessário, e resolva o caso em que o veículo tenha sido destruído antes do vencimento do aluguel, fechando automaticamente o aluguel com a perda total do depósito.
Vários locais de aluguel
Coloque os locais de aluguel em pontos estratégicos do mapa onde o transporte temporário faz mais sentido. O aeroporto é uma escolha óbvia, atendendo jogadores que acabaram de chegar à cidade. Locais no centro, próximos a edifícios governamentais, atendem jogadores que participam de processos judiciais ou reuniões de negócios. Locais de praia oferecem motocicletas e bicicletas para atividades de lazer ao longo do litoral. Cada local pode oferecer um subconjunto diferente da frota, com o aeroporto tendo uma gama completa, desde econômica até premium, enquanto os locais de praia estocam apenas motocicletas e bicicletas. Personalize o modelo do NPC em cada local para corresponder à configuração. Os aluguéis em aeroportos usam um modelo de negócios profissional, os aluguéis em praias usam um modelo de surfista casual e os locais no centro da cidade usam um funcionário adequado. Essa atenção aos detalhes faz com que cada local de aluguel pareça um negócio distinto, em vez de cópias idênticas do mesmo sistema.
Rastreamento GPS e Anti-Roubo
Os veículos alugados devem ter rastreamento GPS integrado que permita à locadora e ao jogador localizar o veículo a qualquer momento. Exiba a localização do veículo alugado no mapa do jogador com um ícone distinto. Se o veículo sair de um limite configurável, envie uma notificação de aviso. Implemente medidas antirroubo que impeçam outros jogadores de armazenar ou estacionar um veículo alugado, garantindo que ele permaneça sob controle do sistema de aluguel. Quando um jogador tenta colocar um veículo alugado em sua garagem pessoal, o sistema deve bloquear a ação com uma notificação explicando que os veículos alugados não podem ser armazenados. Para motocicletas e bicicletas, adicione um cadeado virtual que somente o locatário pode desbloquear, evitando roubos casuais. Se um veículo alugado for roubado, o locatário deverá ser capaz de denunciá-lo por meio de um aplicativo de telefone, acionando um ping de GPS que o ajudará a localizar o veículo. Acompanhe a quilometragem total durante o aluguel para possíveis sobretaxas em locações de alta quilometragem, adicionando outra camada de gerenciamento realista de aluguel de veículos.
Integração de negócios e aluguel de propriedade do jogador
Para servidores com sistema de propriedade empresarial, permita que os jogadores comprem e operem seu próprio negócio de aluguel. O proprietário da empresa define a composição da frota comprando veículos para adicionar ao pool de aluguel, determina os preços, contrata funcionários para atender o balcão e coleta a receita dos aluguéis. Os proprietários de empresas devem ter um painel de gerenciamento que mostre aluguéis ativos, receitas diárias, taxas de utilização da frota e custos de manutenção para veículos que acumulam danos em vários aluguéis. Os funcionários podem lidar com operações de recepção, como processar aluguéis e devoluções, inspecionar veículos devolvidos em busca de danos e escalar disputas para o proprietário. Essa abordagem orientada ao jogador transforma o sistema de aluguel de uma mecânica de jogo estática em um negócio dinâmico que reflete o espírito empreendedor dos servidores de roleplay e cria oportunidades de emprego para jogadores que preferem funções de atendimento ao cliente em vez de jogos de alta ação.
