DRS Motel
Motéis com quartos arrendados ao dia ou comprados. Cada jogador novo pode receber um quarto inicial grátis e depois arrendar quartos noutros motéis. Cada quarto tem interior privado (numa dimensão própria), cofre, roupeiro com roupas guardadas, chaves para amigos, campainha, rusga da polícia e parque privado. Os motéis criam-se e editam-se em jogo. Funciona com Qbox, QBCore e ESX.
#Requisitos
| Recurso | Obrigatório |
|---|---|
oxmysql | Sim |
| Qbox, QBCore ou ESX | Sim (deteção automática) |
ox_target ou qb-target | Não — sem target usa a tecla E com marcador no chão |
ox_inventory ou qb-inventory | Não — sem eles o cofre usa a janela própria da DRS (funciona com qualquer inventário) |
illenium-appearance, fivem-appearance ou skinchanger | Não — o roupeiro também funciona com as roupas nativas do GTA |
#Instalação
- Coloca
drs_motelemresources. - Adiciona ao
server.cfg, depois dooxmysqle da framework:
ensure oxmysql
ensure qb-core
ensure drs_motel- As tabelas são criadas sozinhas no primeiro arranque. Se preferires criá-las à mão, importa o
sql/drs_motel.sql. - Para a rusga da polícia, cria o item
police_stormram(ou mudaConfig.Raid.item). - Dá acesso ao criador de motéis à tua staff (os grupos de admin da framework já têm):
add_ace group.admin drs.motel allow#Como funciona
#Arrendar, comprar e prolongar
Na porta de um quarto livre escolhes arrendar (preço por dia, price) ou comprar (buyPrice), conforme o Config.Mode ('rent', 'buy' ou 'both'). Cada motel pode ter o seu próprio mode. Pagas em dinheiro ou banco, e podes prolongar o arrendamento na porta ou dentro do quarto. Ao entrar na cidade recebes um aviso quando faltam menos de Config.ExpireWarningHours horas.
| Limite | Opção |
|---|---|
| Quartos por pessoa no total (conta o inicial) | Config.MaxRooms |
| Quartos por pessoa em cada motel | Config.RoomsPerMotel |
| Máximo de dias pagos de uma vez | Config.MaxDays |
#Quarto inicial
Com Config.StarterRoom.enabled = true, cada jogador novo recebe (uma vez) um quarto grátis no motel Config.StarterRoom.motel. Com days = 0 nunca acaba; com outro valor acaba ao fim desses dias e pode ser prolongado a pagar.
#Vender o quarto
- Ao banco: recebes
Config.Sell.bankPercent% do valor (comprado = % do preço; arrendado = % dos dias que faltam; o quarto inicial não vale nada). - A um jogador perto: escolhes o preço e o comprador aceita com Y ou recusa com X. Fica retida a comissão
Config.Sell.playerFee%.
#Dentro do quarto
- Interior privado: cada quarto numa dimensão própria. Quem sai do jogo dentro do quarto volta à porta.
- Cofre e roupeiro: só se abrem nos seus pontos dentro do quarto. O cofre fica vazio quando o arrendamento acaba.
- Roupeiro: guardar a roupa vestida, vestir, mudar o nome e apagar (até
Config.MaxOutfits).
#Chaves e campainha
O dono dá e tira chaves a quem está perto (até Config.MaxKeys). Quem tem chave entra e usa o cofre, o roupeiro e o parque. Na campainha, quem está dentro recebe um aviso com contagem e abre com Y ou ignora com X.
#Rusga da polícia
Os empregos de Config.Raid.jobs, com o item police_stormram, arrombam a porta em duration segundos. A porta fica aberta minutes minutos para qualquer pessoa entrar e o dono é avisado.
#Parque privado
Um carro por quarto num lugar livre do motel. O carro aparece trancado para todos e só quem tem acesso o tira. Quando o arrendamento acaba, volta à garagem. A staff tira um carro com /motelremovercarro [matrícula].
#Criador de motéis
/motelcriador abre o criador (staff): criar, editar e apagar motéis, pôr as portas e os lugares de parque onde estás e fazer TP para cada ponto.
| Tecla | Ação |
|---|---|
| E | Colocar o ponto onde estás |
| BACKSPACE | Desfazer o último |
| ENTER | Terminar |
Os motéis criados em jogo ficam guardados na base de dados.
#Comandos
| Comando | Quem | O que faz |
|---|---|---|
/motel | Todos | Os teus quartos, com o tempo que falta e GPS |
/motelcriador | Staff | Criador de motéis |
/motelremovercarro [matrícula] | Staff | Tira um carro do parque |
#Opções principais
| Opção | Por defeito | Descrição |
|---|---|---|
Config.Locale | 'pt' | Idioma: pt ou en |
Config.Mode | 'rent' | rent, buy ou both |
Config.MaxRooms | 3 | Quartos por pessoa (0 = sem limite) |
Config.StarterRoom.enabled | true | Quarto inicial grátis |
Config.Society.enabled | false | Parte de cada pagamento para uma empresa |
Config.Stash | 'auto' | ox_inventory, qb-inventory, builtin ou custom |
Config.Wardrobe | 'builtin' | builtin, illenium ou custom |
Config.Raid.enabled | true | Rusga da polícia |
Config.Parking.enabled | true | Parque privado |
Config.Interaction | 'auto' | ox_target, qb-target ou key |
#Configuração completa
Config = {}
-- Idioma / Language: 'pt' ou 'en'
Config.Locale = 'pt'
-- Framework: 'auto' deteta Qbox/QBCore/ESX (ou 'qbx' | 'qb' | 'esx')
Config.Framework = 'auto'
-- Moeda mostrada na interface / Currency shown in the UI
Config.Currency = '€'
-- Como se interage com as portas, o cofre e o roupeiro: 'auto' (ox_target > qb-target > tecla) | 'ox_target' | 'qb-target' | 'key'
-- How doors, stash and wardrobe are used
Config.Interaction = 'auto'
Config.InteractKey = 38 -- E
Config.InteractKeyLabel = 'E'
-- Marcador no chão em modo tecla (false = sem marcador) / Ground marker in key mode
Config.Marker = { type = 20, size = 0.25, color = { 245, 158, 11, 160 } }
Config.UseOxNotify = false -- notificações do ox_lib / ox_lib notifications
-- ------------------------------------------------------------------ arrendar ou comprar / rent or buy
-- 'rent' = arrendar ao dia (price) | 'buy' = comprar (buyPrice, é teu para sempre) | 'both' = o jogador escolhe
-- Cada motel pode ter o seu: mode = 'buy' dentro do motel, em baixo.
-- Each motel can override it with its own `mode`.
Config.Mode = 'rent'
-- Vender o quarto / Selling the room
-- bankPercent: o banco paga esta % do valor (comprado = % do buyPrice; arrendado = % dos dias que faltam; o inicial não vale nada)
-- playerFee: % que fica retida quando vendes a outro jogador (vai para Config.Society se estiver ligada)
-- The bank pays bankPercent % of the value; playerFee % is kept when selling to another player
Config.Sell = { bankPercent = 80, toPlayer = true, playerFee = 10, offerTimeout = 30 }
-- ------------------------------------------------------------------ arrendamento / renting
Config.MaxDays = 50 -- máximo de dias pagos de uma vez / most days paid ahead
Config.QuickDays = { 1, 3, 7, 14, 30 }
Config.MaxRooms = 3 -- quartos por pessoa no total, com o inicial (0 = sem limite) / rooms per person overall, starter included (0 = no limit)
Config.RoomsPerMotel = 1 -- quartos por pessoa em cada motel / rooms per person in each motel
-- Quarto inicial: cada pessoa recebe (uma vez) um quarto grátis neste motel quando entra na cidade sem quarto.
-- Depois pode arrendar quartos nos outros motéis, até Config.MaxRooms.
-- days = 0: o quarto inicial nunca acaba; days > 0: acaba ao fim desses dias (e pode ser prolongado a pagar).
-- Starter room: everyone gets (once) a free room at this motel when they join without one. days = 0 never ends.
-- enabled = false: os jogadores novos NÃO recebem quarto (têm de arrendar ou comprar) / new players get NO room
Config.StarterRoom = {
enabled = true, -- true = jogador novo recebe um quarto grátis / new players get a free room
motel = 'pinkcage', -- id do motel (Config.Motels ou criado in-game) / motel id
days = 0, -- 0 = sem fim / never ends
}
Config.ExpireWarningHours = 24 -- avisa ao entrar na cidade quando faltam menos horas / warns on join when fewer hours are left
-- Parte do pagamento que vai para uma empresa (ex.: imobiliária). enabled = false desliga.
-- Share of every payment sent to a business account (e.g. real estate). enabled = false turns it off.
Config.Society = { enabled = false, account = 'realestate', percent = 50 }
-- ------------------------------------------------------------------ quarto / room
Config.MaxKeys = 5 -- pessoas com chave por quarto / key holders per room
Config.KeyDistance = 5.0 -- distância para dar a chave / distance to give a key
Config.BucketBase = 5000 -- cada quarto usa a dimensão BucketBase + id / each room uses routing bucket BucketBase + id
-- Campainha: só quem está dentro do quarto a ouve (false = dono e chaves em qualquer sítio da cidade)
-- Doorbell: only people inside the room hear it (false = owner and key holders anywhere in the city)
Config.Doorbell = { onlyInside = true, timeout = 15, cooldown = 10, acceptKey = 246, acceptLabel = 'Y', denyKey = 73, denyLabel = 'X' }
-- Cofre: 'auto' (ox_inventory > qb-inventory > builtin) | 'ox_inventory' | 'qb-inventory' | 'builtin' | 'custom' (server/editable.lua)
-- Stash: 'builtin' is the DRS stash window (works with any inventory)
-- O cofre fica vazio quando o arrendamento acaba / The stash is emptied when the rent ends
Config.Stash = 'auto'
-- Roupeiro: 'builtin' (roupas guardadas no quarto) | 'illenium' | 'custom' (client/editable.lua)
-- Wardrobe: 'builtin' saves outfits in the room
Config.Wardrobe = 'builtin'
Config.MaxOutfits = 20
-- ------------------------------------------------------------------ polícia / police
-- A polícia com o item pode arrombar a porta: fica aberta durante `minutes` para qualquer pessoa entrar.
-- Police with the item can break the door: it stays open for `minutes` for anyone to enter.
Config.Raid = {
enabled = true,
jobs = { 'police', 'sheriff' },
item = 'police_stormram', -- nil = não precisa de item / no item needed
removeItem = false,
duration = 5, -- segundos a arrombar / seconds breaking the door
minutes = 1, -- minutos com a porta aberta / minutes the door stays open
}
-- ------------------------------------------------------------------ parque / parking
Config.Parking = {
enabled = true,
distance = 2.5, -- distância ao lugar / distance to the spot
ownedOnly = true, -- só veículos teus (owned_vehicles / player_vehicles) / only owned vehicles
staffCommand = 'motelremovercarro', -- /motelremovercarro [matrícula] tira um carro do parque (staff)
}
-- Comando para ver os teus quartos com GPS ('' = desligado) / Command listing your rooms with GPS ('' = off)
Config.RoomsCommand = 'motel'
Config.Blip = { sprite = 475, color = 47, scale = 0.7 }
-- ------------------------------------------------------------------ criador in-game / in-game creator
-- /motelcriador abre o criador (staff: ACE `ace` ou grupos de admin). Os motéis criados ficam na base de dados.
-- /motelcriador opens the creator (staff). Motels made there are saved in the database.
Config.Creator = {
command = 'motelcriador',
ace = 'drs.motel',
addKey = 38, addLabel = 'E', -- colocar aqui / place here
undoKey = 177, undoLabel = 'BACKSPACE', -- desfazer o último / undo last
doneKey = 191, doneLabel = 'ENTER', -- terminar / finish
}
-- ------------------------------------------------------------------ interiores / interiors
-- entry: onde entras (e sais) / where you spawn inside; stash e wardrobe: pontos dentro do quarto
Config.Interiors = {
standard = {
entry = vector4(151.4, -1007.88, -99.0, 0.0),
stash = vector3(151.31, -1003.13, -99.0),
wardrobe = vector3(151.77, -1001.33, -99.0),
slots = 50,
weight = 100000,
},
}
-- ------------------------------------------------------------------ motéis / motels
-- id: único e sem espaços (fica guardado na base de dados) / unique, no spaces (saved in the database)
-- rooms: id do quarto e posição da porta / room id and door position
-- parking: lugares (x, y, z, direção) / spots (x, y, z, heading)
-- center + radius: zona onde os carros estacionados aparecem / area where parked cars are shown
-- blip = false esconde o blip deste motel / hides this motel's blip
-- mode = 'rent' | 'buy' | 'both' muda o modo só deste motel / changes the mode of this motel only
Config.Motels = {
{
id = 'perrera',
label = 'Perrera Beach',
price = 500, -- arrendar: preço por dia / rent: price per day
buyPrice = 25000, -- comprar: preço do quarto / buy: price of the room
interior = 'standard',
center = vector3(-1472.8, -658.85, 29.11),
radius = 30.0,
rooms = {
{ id = '1', door = vector3(-1493.75, -668.37, 29.03) },
{ id = '2', door = vector3(-1498.18, -664.7, 29.03) },
{ id = '3', door = vector3(-1495.36, -661.59, 29.03) },
{ id = '4', door = vector3(-1490.77, -658.24, 29.03) },
{ id = '5', door = vector3(-1486.78, -655.37, 29.58) },
{ id = '6', door = vector3(-1482.18, -652.01, 29.58) },
{ id = '7', door = vector3(-1478.22, -649.14, 29.58) },
{ id = '8', door = vector3(-1473.65, -645.8, 29.58) },
{ id = '9', door = vector3(-1469.65, -642.92, 29.58) },
{ id = '10', door = vector3(-1465.08, -639.58, 29.58) },
{ id = '11', door = vector3(-1461.26, -640.85, 29.58) },
{ id = '12', door = vector3(-1452.36, -653.24, 29.58) },
{ id = '13', door = vector3(-1454.36, -655.97, 29.58) },
{ id = '14', door = vector3(-1458.98, -659.32, 29.58) },
{ id = '15', door = vector3(-1462.96, -662.18, 29.58) },
{ id = '16', door = vector3(-1467.54, -665.56, 29.58) },
{ id = '17', door = vector3(-1471.54, -668.43, 29.58) },
{ id = '18', door = vector3(-1461.45, -641.04, 33.38) },
{ id = '19', door = vector3(-1457.92, -645.51, 33.38) },
{ id = '20', door = vector3(-1455.71, -648.62, 33.38) },
{ id = '21', door = vector3(-1452.48, -653.29, 33.38) },
{ id = '22', door = vector3(-1454.4, -655.94, 33.38) },
{ id = '23', door = vector3(-1458.93, -659.31, 33.38) },
{ id = '24', door = vector3(-1462.92, -662.2, 33.38) },
{ id = '25', door = vector3(-1467.5, -665.53, 33.38) },
{ id = '26', door = vector3(-1471.55, -668.36, 33.38) },
{ id = '27', door = vector3(-1476.11, -671.79, 33.38) },
{ id = '28', door = vector3(-1465.02, -639.63, 33.38) },
{ id = '29', door = vector3(-1469.68, -642.98, 33.38) },
{ id = '30', door = vector3(-1473.61, -645.89, 33.38) },
{ id = '31', door = vector3(-1478.17, -649.13, 33.38) },
{ id = '32', door = vector3(-1482.19, -652.03, 33.38) },
{ id = '33', door = vector3(-1486.78, -655.34, 33.38) },
{ id = '34', door = vector3(-1490.77, -658.25, 33.38) },
{ id = '35', door = vector3(-1495.3, -661.55, 33.38) },
{ id = '36', door = vector3(-1498.1, -664.7, 33.38) },
{ id = '37', door = vector3(-1493.75, -668.29, 33.38) },
{ id = '38', door = vector3(-1489.9, -671.46, 33.38) },
},
parking = {
vector4(-1465.87, -648.57, 28.5, 35.47),
vector4(-1468.57, -650.68, 28.5, 35.37),
vector4(-1471.41, -652.78, 28.5, 33.28),
vector4(-1480.69, -659.38, 27.94, 34.88),
vector4(-1483.36, -661.61, 27.94, 33.91),
vector4(-1486.08, -663.68, 27.94, 35.97),
vector4(-1478.01, -657.2, 27.94, 35.64),
},
},
{
id = 'pinkcage',
label = 'The Pink Cage',
price = 500, -- arrendar: preço por dia / rent: price per day
buyPrice = 25000, -- comprar: preço do quarto / buy: price of the room
interior = 'standard',
center = vector3(326.0, -211.15, 54.09),
radius = 30.0,
rooms = {
{ id = '1', door = vector3(312.85, -218.86, 54.22) },
{ id = '2', door = vector3(311.01, -218.04, 54.22) },
{ id = '3', door = vector3(307.45, -216.68, 54.22) },
{ id = '4', door = vector3(307.47, -213.27, 54.22) },
{ id = '5.1', door = vector3(309.5, -207.98, 54.22) },
{ id = '5.2', door = vector3(311.31, -203.45, 54.22) },
{ id = '6', door = vector3(313.34, -198.14, 54.22) },
{ id = '7', door = vector3(315.75, -194.9, 54.23) },
{ id = '8', door = vector3(319.4, -196.31, 54.23) },
{ id = '9', door = vector3(321.36, -197.09, 54.23) },
{ id = '11', door = vector3(312.9, -218.81, 58.02) },
{ id = '12', door = vector3(310.86, -218.09, 58.02) },
{ id = '13', door = vector3(307.29, -216.75, 58.02) },
{ id = '14', door = vector3(307.58, -213.3, 58.02) },
{ id = '15', door = vector3(309.51, -207.96, 58.02) },
{ id = '16', door = vector3(311.26, -203.37, 58.02) },
{ id = '17', door = vector3(313.33, -198.07, 58.02) },
{ id = '18', door = vector3(315.84, -194.88, 58.02) },
{ id = '19', door = vector3(319.39, -196.13, 58.02) },
{ id = '20', door = vector3(321.45, -196.93, 58.02) },
{ id = '21', door = vector3(329.39, -225.16, 54.22) },
{ id = '22', door = vector3(331.32, -225.97, 54.22) },
{ id = '23', door = vector3(334.9, -227.37, 54.22) },
{ id = '24', door = vector3(337.18, -224.79, 54.22) },
{ id = '25', door = vector3(339.18, -219.46, 54.22) },
{ id = '26', door = vector3(340.99, -214.91, 54.22) },
{ id = '27', door = vector3(343.01, -209.57, 54.22) },
{ id = '28', door = vector3(344.74, -205.03, 54.22) },
{ id = '29', door = vector3(346.8, -199.73, 54.22) },
{ id = '30', door = vector3(329.37, -225.19, 58.02) },
{ id = '31', door = vector3(331.34, -225.94, 58.02) },
{ id = '32', door = vector3(334.97, -227.34, 58.02) },
{ id = '33', door = vector3(337.15, -224.85, 58.02) },
{ id = '34', door = vector3(339.21, -219.51, 58.02) },
{ id = '35', door = vector3(340.98, -214.92, 58.02) },
{ id = '36', door = vector3(342.99, -209.67, 58.02) },
{ id = '37', door = vector3(344.75, -205.04, 58.02) },
{ id = '39', door = vector3(346.81, -199.73, 58.02) },
},
parking = {
vector4(337.48, -207.39, 53.09, 250.31),
vector4(336.36, -210.66, 53.09, 250.31),
vector4(335.22, -213.88, 53.09, 250.31),
vector4(334.05, -217.05, 53.09, 250.31),
vector4(314.93, -209.41, 53.09, 67.59),
vector4(316.08, -206.15, 53.09, 67.59),
vector4(317.51, -203.02, 53.09, 67.59),
vector4(318.56, -199.69, 53.09, 67.59),
},
},
{
id = 'bilingsgate',
label = 'Bilingsgate',
price = 500, -- arrendar: preço por dia / rent: price per day
buyPrice = 25000, -- comprar: preço do quarto / buy: price of the room
interior = 'standard',
center = vector3(565.73, -1762.93, 29.17),
radius = 50.0,
rooms = {
{ id = '1', door = vector3(566.18, -1778.16, 29.35) },
{ id = '2', door = vector3(550.31, -1775.52, 29.31) },
{ id = '3', door = vector3(552.2, -1771.52, 29.31) },
{ id = '4', door = vector3(554.65, -1766.26, 29.31) },
{ id = '5', door = vector3(557.7, -1759.64, 29.31) },
{ id = '6', door = vector3(561.38, -1751.79, 29.28) },
{ id = '7', door = vector3(560.15, -1777.17, 33.44) },
{ id = '8', door = vector3(559.09, -1777.35, 33.44) },
{ id = '10', door = vector3(550.09, -1770.55, 33.44) },
{ id = '11', door = vector3(552.6, -1765.24, 33.44) },
{ id = '12', door = vector3(555.6, -1758.64, 33.44) },
{ id = '14', door = vector3(559.3, -1750.81, 33.44) },
{ id = '15', door = vector3(561.75, -1747.38, 33.44) },
},
parking = {
vector4(567.46, -1799.15, 28.19, 170.95),
vector4(564.35, -1798.98, 28.2, 170.56),
vector4(561.38, -1798.52, 28.2, 170.14),
vector4(558.33, -1798.24, 28.2, 173.09),
vector4(555.26, -1797.74, 28.2, 171.69),
vector4(552.26, -1797.26, 28.2, 169.95),
vector4(549.18, -1796.66, 28.2, 171.47),
vector4(545.07, -1794.89, 28.2, 171.47),
vector4(561.23, -1789.0, 28.2, 334.09),
vector4(558.45, -1787.92, 28.2, 335.03),
vector4(555.56, -1786.83, 28.2, 335.19),
vector4(545.02, -1781.77, 28.12, 334.57),
vector4(542.09, -1780.59, 27.97, 334.21),
},
},
{
id = 'motor',
label = 'The Motor',
price = 500, -- arrendar: preço por dia / rent: price per day
buyPrice = 25000, -- comprar: preço do quarto / buy: price of the room
interior = 'standard',
center = vector3(1125.89, 2653.3, 38.0),
radius = 30.0,
rooms = {
{ id = '1', door = vector3(1142.4, 2654.69, 38.15) },
{ id = '2', door = vector3(1142.42, 2651.12, 38.14) },
{ id = '3', door = vector3(1142.32, 2643.58, 38.14) },
{ id = '4', door = vector3(1141.15, 2641.68, 38.14) },
{ id = '5', door = vector3(1136.34, 2641.64, 38.14) },
{ id = '6', door = vector3(1132.75, 2641.64, 38.14) },
{ id = '7', door = vector3(1125.22, 2641.64, 38.14) },
{ id = '8', door = vector3(1121.35, 2641.74, 38.14) },
{ id = '9', door = vector3(1114.67, 2641.74, 38.14) },
{ id = '10', door = vector3(1107.16, 2641.64, 38.14) },
{ id = '11', door = vector3(1106.01, 2649.04, 38.14) },
{ id = '12', door = vector3(1106.14, 2652.9, 38.14) },
},
parking = {
vector4(1097.97, 2663.28, 36.96, 179.76),
vector4(1101.54, 2663.26, 36.97, 180.6),
vector4(1105.27, 2663.24, 36.97, 178.45),
vector4(1111.8, 2657.94, 36.99, 89.36),
vector4(1111.67, 2654.31, 37.0, 88.74),
vector4(1116.53, 2648.04, 37.0, 179.22),
vector4(1120.26, 2647.54, 37.0, 178.72),
vector4(1123.88, 2647.65, 37.0, 179.35),
vector4(1127.53, 2647.94, 37.0, 179.94),
vector4(1131.26, 2647.72, 37.0, 177.5),
vector4(1135.23, 2647.61, 37.0, 178.44),
},
},
{
id = 'eastern',
label = 'Eastern',
price = 500, -- arrendar: preço por dia / rent: price per day
buyPrice = 25000, -- comprar: preço do quarto / buy: price of the room
interior = 'standard',
center = vector3(366.34, 2635.42, 44.5),
radius = 30.0,
rooms = {
{ id = '1', door = vector3(341.69, 2614.92, 44.67) },
{ id = '2', door = vector3(346.93, 2618.21, 44.68) },
{ id = '3', door = vector3(354.3, 2619.83, 44.67) },
{ id = '4', door = vector3(359.82, 2622.81, 44.67) },
{ id = '5', door = vector3(367.2, 2624.53, 44.67) },
{ id = '6', door = vector3(372.54, 2627.56, 44.67) },
{ id = '7', door = vector3(379.89, 2629.25, 44.67) },
{ id = '8', door = vector3(385.27, 2632.34, 44.67) },
{ id = '9', door = vector3(392.63, 2634.01, 44.67) },
{ id = '10', door = vector3(398.0, 2637.22, 44.67) },
},
parking = {
vector4(336.83, 2619.06, 43.5, 207.68),
vector4(341.77, 2622.29, 43.51, 210.12),
vector4(348.36, 2624.71, 43.5, 209.53),
vector4(353.97, 2627.8, 43.5, 210.82),
vector4(360.88, 2629.57, 43.5, 210.82),
vector4(366.48, 2631.84, 43.5, 214.33),
vector4(373.86, 2634.07, 43.5, 210.59),
vector4(379.0, 2637.0, 43.5, 211.51),
vector4(386.37, 2638.51, 43.5, 212.29),
vector4(391.86, 2641.65, 43.49, 209.54),
},
},
{
id = 'dreamview',
label = 'Dream View',
price = 500, -- arrendar: preço por dia / rent: price per day
buyPrice = 25000, -- comprar: preço do quarto / buy: price of the room
interior = 'standard',
center = vector3(-81.11, 6340.18, 31.49),
radius = 30.0,
rooms = {
{ id = '1', door = vector3(-111.16, 6322.78, 31.58) },
{ id = '2', door = vector3(-114.33, 6326.08, 31.58) },
{ id = '3', door = vector3(-120.16, 6327.2, 31.58) },
{ id = '4', door = vector3(-111.06, 6322.73, 35.5) },
{ id = '5', door = vector3(-114.34, 6326.08, 35.5) },
{ id = '6', door = vector3(-120.23, 6327.27, 35.5) },
{ id = '7', door = vector3(-103.45, 6330.73, 31.58) },
{ id = '8', door = vector3(-106.71, 6333.93, 31.58) },
{ id = '9', door = vector3(-107.58, 6339.78, 31.58) },
{ id = '11', door = vector3(-99.01, 6348.49, 31.58) },
{ id = '12', door = vector3(-93.52, 6353.97, 31.58) },
{ id = '13', door = vector3(-90.22, 6357.23, 31.58) },
{ id = '14', door = vector3(-84.87, 6362.6, 31.58) },
{ id = '15', door = vector3(-103.42, 6330.65, 35.5) },
{ id = '16', door = vector3(-106.74, 6333.96, 35.5) },
{ id = '17', door = vector3(-107.52, 6339.82, 35.5) },
{ id = '18', door = vector3(-102.25, 6345.25, 35.5) },
{ id = '19', door = vector3(-98.93, 6348.43, 35.5) },
{ id = '20', door = vector3(-93.54, 6353.95, 35.5) },
{ id = '21', door = vector3(-90.2, 6357.16, 35.5) },
{ id = '22', door = vector3(-84.83, 6362.67, 35.5) },
},
parking = {
vector4(-100.84, 6339.27, 30.49, 44.01),
vector4(-98.22, 6342.0, 30.49, 44.18),
vector4(-95.55, 6344.58, 30.49, 43.43),
vector4(-92.92, 6347.16, 30.49, 44.47),
vector4(-90.33, 6349.89, 30.49, 44.85),
vector4(-87.41, 6352.4, 30.49, 46.06),
vector4(-84.48, 6355.16, 30.49, 46.06),
vector4(-81.79, 6358.05, 30.49, 46.06),
vector4(-72.34, 6358.36, 30.49, 314.27),
vector4(-69.69, 6355.42, 30.49, 313.46),
vector4(-66.73, 6352.75, 30.49, 313.97),
vector4(-64.01, 6349.93, 30.49, 313.14),
vector4(-61.33, 6347.22, 30.49, 313.73),
vector4(-58.59, 6344.58, 30.49, 313.84),
vector4(-72.03, 6342.08, 30.49, 44.35),
vector4(-74.67, 6339.12, 30.49, 43.52),
vector4(-77.23, 6336.39, 30.49, 43.49),
vector4(-79.86, 6333.63, 30.49, 43.49),
vector4(-85.37, 6338.87, 30.49, 223.05),
vector4(-82.88, 6341.74, 30.49, 222.98),
vector4(-80.18, 6344.5, 30.49, 223.2),
vector4(-77.42, 6347.11, 30.49, 223.01),
},
},
}#Base de dados
-- DRS Motel — as tabelas também são criadas sozinhas no arranque / tables are also created on start
-- quartos arrendados ou comprados (expires_at = 0: não acaba) / rented or bought rooms (expires_at = 0: never ends)
-- os preços estão no config.lua (price, buyPrice) ou no motel criado in-game / prices live in config.lua or the in-game motel
CREATE TABLE IF NOT EXISTS drs_motel_rooms (
id INT NOT NULL AUTO_INCREMENT,
motel VARCHAR(50) NOT NULL,
room VARCHAR(10) NOT NULL,
owner VARCHAR(64) NOT NULL,
owner_name VARCHAR(100) NOT NULL DEFAULT '',
expires_at INT NOT NULL,
created_at INT NOT NULL,
kind VARCHAR(10) NOT NULL DEFAULT 'rent', -- rent | buy | starter
paid INT NOT NULL DEFAULT 0, -- quanto foi pago / amount paid
PRIMARY KEY (id),
UNIQUE KEY motel_room (motel, room),
KEY owner (owner)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- chaves dadas pelo dono / keys given by the owner
CREATE TABLE IF NOT EXISTS drs_motel_keys (
room_id INT NOT NULL,
identifier VARCHAR(64) NOT NULL,
name VARCHAR(100) NOT NULL DEFAULT '',
PRIMARY KEY (room_id, identifier)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- roupas guardadas no roupeiro / outfits saved in the wardrobe
CREATE TABLE IF NOT EXISTS drs_motel_outfits (
id INT NOT NULL AUTO_INCREMENT,
room_id INT NOT NULL,
name VARCHAR(40) NOT NULL,
model BIGINT NOT NULL DEFAULT 0,
data LONGTEXT NOT NULL,
PRIMARY KEY (id),
KEY room_id (room_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- veículos estacionados (um por quarto) / parked vehicles (one per room)
CREATE TABLE IF NOT EXISTS drs_motel_parking (
room_id INT NOT NULL,
motel VARCHAR(50) NOT NULL,
spot INT NOT NULL,
plate VARCHAR(16) NOT NULL,
props LONGTEXT NOT NULL,
PRIMARY KEY (room_id),
UNIQUE KEY motel_spot (motel, spot)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- cofre DRS (Config.Stash = 'builtin') / DRS stash
CREATE TABLE IF NOT EXISTS drs_motel_stash (
room_id INT NOT NULL,
items LONGTEXT NOT NULL,
PRIMARY KEY (room_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- motéis feitos no criador in-game / motels made in the in-game creator
CREATE TABLE IF NOT EXISTS drs_motel_motels (
id VARCHAR(50) NOT NULL,
data LONGTEXT NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;#Para programadores
exports.drs_motel:GetPlayerRooms(identifier) -- { { motel, room, owner, expires } } (expires = 0: sem fim)
exports.drs_motel:GetInsideRoom(source) -- { motel, room } ou nilO server/editable.lua e o client/editable.lua não são encriptados: empresa, posse de veículos, garagem, chaves do carro, combustível, cofre e roupeiro próprios.
#Segurança
Tudo é validado no servidor: distância à porta, estar dentro do quarto, acesso (dono, chave ou rusga), dinheiro, itens e limites. A rusga tem de durar o tempo todo no servidor e a campainha só serve uma vez. Se dois jogadores arrendarem o mesmo quarto ao mesmo tempo, a base de dados só aceita um e o outro recebe o dinheiro de volta.
#Resolução de problemas
Não consigo abrir o cofre — o cofre só abre no ponto dele, dentro do quarto. Confirma que tens acesso (dono ou chave).
O jogador novo não recebeu quarto — confirma Config.StarterRoom.enabled = true e que o motel existe (no config.lua ou criado em jogo).
O /motelcriador não abre — falta a permissão: add_ace group.admin drs.motel allow.
A polícia não consegue arrombar — tem de ter um emprego de Config.Raid.jobs e o item police_stormram.