Skip to content

Apartments: config files ​

These files stay readable in every build (escrow too), so you can change them. Shown as shipped in version 1.0.1.

config.lua ​

lua
-- ============================================================================
--  Lumo Apartments · configuration
--  Everything a server owner normally changes is in this file. Walk-in room
--  coordinates live in data/walkin.lua; texts in locales/.
--
--  Spawn and character selectors (lumo-spawn, qb-spawn, qb-multicharacter, Qbox)
--  read the `Apartments` table at the bottom of this file. Keep this file
--  self-contained: it must not call anything defined in another file.
-- ============================================================================
Config = {}

-- 'auto' detects Qbox, QBCore, ESX or none (standalone).
Config.Framework = 'auto'      -- 'auto' | 'qbx' | 'qb' | 'esx' | 'standalone'
-- Interaction: 'auto' = lumo-interact, then a real qb-target, then ox_target, else a built-in [E] prompt.
Config.Target = 'auto'         -- 'auto' | 'lumo-interact' | 'qb' | 'ox' | 'none'
-- Apartment storage. 'auto' = lumo-inventory, ox_inventory, qb-inventory, then the older
-- qb-style inventory events (ps-inventory, lj-inventory). 'custom' = Config.Hooks.openStash.
Config.Inventory = 'auto'      -- 'auto' | 'lumo-inventory' | 'ox_inventory' | 'qb-inventory' | 'qb-legacy' | 'custom'
-- Wardrobe. 'auto' = lumo-clothing, illenium-appearance, qb-clothing. 'custom' = Config.Hooks.openWardrobe.
Config.Wardrobe = 'auto'       -- 'auto' | 'lumo-clothing' | 'illenium-appearance' | 'qb-clothing' | 'custom'

Config.Locale = 'en'
Config.Debug = false           -- true: /aptcoords and /aptdoor diagnostics for everyone, extra console output

-- NUI look: 'auto' follows lumo-ui's HUD preset (Classic = lime, Circle = white),
-- or pin 'classic' / 'circle'.
Config.Theme = 'auto'
Config.HideHud = true          -- hide the HUD and minimap while an apartments panel is open

-- Who counts as an admin (/aptmap). Framework groups, or the ACE below.
Config.Admin = {
    permissions = { 'admin', 'god' },
    ace = 'lumoapartments.admin',
}

-- ── New characters ──────────────────────────────────────────────────────────
Config.Starter = {
    enabled = true,            -- new characters pick a starter building in the spawn menu
    -- No spawn menu running (e.g. ESX without a spawn selector, or standalone): give every
    -- character without an apartment one in this building on first load.
    autoAssign = true,
    default = 'integrity',
}

-- Money is taken from these accounts, in this order. Standalone servers have no money:
-- every price is free there.
Config.Payment = { 'bank', 'cash' }

Config.Stash = { slots = 50, weight = 250000 }

-- ── Blips ───────────────────────────────────────────────────────────────────
Config.Blips = {
    enabled = true,
    building = { sprite = 476, colour = 0, scale = 0.7 },  -- every building you can live in
    home = { sprite = 475, colour = 3, scale = 0.8 },       -- your own home
}

-- ── Instanced flats ─────────────────────────────────────────────────────────
-- Each apartment gets its own private copy of a base-game interior (a routing
-- bucket). Works on any server: no map needed.
Config.Instanced = {
    bucketBase = 20000,        -- apartment N lives in routing bucket bucketBase + N
    doorbellSeconds = 60,      -- how long a ring stays answerable
    -- Leave your flat from anywhere inside it. Also gets a player out who was put back
    -- inside an apartment interior with no session (e.g. ESX restoring a saved position).
    leaveCommand = 'aptleave',
}

-- Interiors an instanced building can use. All points are world coordinates.
-- To add one: stand on each spot with Config.Debug = true and run /aptcoords.
Config.Interiors = {
    delperro = {
        label = 'Del Perro Heights',
        spawn = vector4(-1451.97, -523.55, 56.93, 36.84),   -- arrival, by the elevator
        exit = vector3(-1451.97, -523.55, 56.93),           -- leave / answer the door
        stash = vector3(-1469.31, -533.83, 50.72),
        wardrobe = vector3(-1466.68, -536.89, 50.73),
        bed = vector3(-1471.30, -531.08, 50.72),             -- sleep = log out
        interiorLoad = vector3(-1465.20, -535.70, 55.53),   -- streams the furniture in
        radius = 1.4,
    },
}

-- ── Buildings ───────────────────────────────────────────────────────────────
-- type = 'instanced': a street entrance into a private interior (any server).
-- type = 'walkin':    real doors in a map you own; rooms are in data/walkin.lua.
--                     Used only while `resource` (the map) is started.
-- starter = offered to new characters.   price = cost to move your home here
-- (a character's first apartment is free).   enabled = false hides a building.
Config.Buildings = {
    rockford = {
        type = 'instanced', label = 'South Rockford Drive', interior = 'delperro',
        entrance = vector4(-667.02, -1105.24, 14.63, 242.32), starter = true, price = 5000,
    },
    morningwood = {
        type = 'instanced', label = 'Morningwood Blvd', interior = 'delperro',
        entrance = vector4(-1288.52, -430.51, 35.15, 124.81), starter = true, price = 5000,
    },
    integrity = {
        type = 'instanced', label = 'Integrity Way', interior = 'delperro',
        entrance = vector4(269.73, -640.75, 42.02, 249.07), starter = true, price = 5000,
    },
    tinsel = {
        type = 'instanced', label = 'Tinsel Towers', interior = 'delperro',
        entrance = vector4(-619.29, 37.69, 43.59, 181.03), starter = true, price = 5000,
    },
    fantastic = {
        type = 'instanced', label = 'Fantastic Plaza', interior = 'delperro',
        entrance = vector4(291.517, -1078.674, 29.405, 270.75), starter = true, price = 5000,
    },

    -- Walk-in presets for third-party maps. Each turns itself on when its map runs.
    starlite = {
        type = 'walkin', label = 'Starlite Motel', resource = 'zydrec-starlitemotel',
        starter = true, price = 2500, roomRadius = 5.0,
        offices = { vector4(960.27, -192.1, 73.11, 161.71) },
    },
    littleseoul = {
        type = 'walkin', label = 'Little Seoul Apartments', resource = 'zydrec-littleseoul',
        starter = true, price = 7500, roomRadius = 6.5,
        offices = { vector4(-833.13, -796.0, 22.23, 272.4) },
    },
    lapuerta = {
        type = 'walkin', label = 'La Puerta Apartments', resource = 'kiiya_lapuerta',
        starter = true, price = 15000, mappable = true,
        offices = { vector4(-461.84, -917.17, 28.1, 87.76), vector4(-471.4, -1038.97, 24.31, 6.84) },
    },
}

-- ── Radial menu ─────────────────────────────────────────────────────────────
-- An "Apartment" ring while you are in your own flat (panel, decorate, lock, storage…).
-- resource: anything that exports qb-radialmenu's AddOption / RemoveOption.
Config.Radial = {
    enabled = true,
    resource = 'qb-radialmenu',
}

-- ── Walk-in buildings ───────────────────────────────────────────────────────
-- The character owns a home (building, storage, keys, furniture) and a room in it.
-- keepRoom = true: the room stays theirs through logouts and restarts until they move,
-- so furniture stays where it was placed. false: rooms per session; each spawn gives
-- the last room if it is free, else a random vacant one (furniture follows the door).
Config.WalkIn = {
    enabled = true,
    keepRoom = true,           -- your flat is yours for good (a building holds as many homes as rooms)
    holdMinutes = 15,          -- keepRoom = false: a room stays yours this long after you log out or crash
    moveFee = 1000,            -- switch to another vacant flat in the same building
    autoLockSeconds = 30,      -- an unlocked door locks itself again
    officePed = 'a_f_y_business_02',
    -- Every walk-in room taken: the character gets this instanced interior instead.
    fallbackInterior = 'delperro',
    -- In-room menu at the door (storage, wardrobe, log out). 'auto' turns it off while a
    -- furniture resource that places those as furniture is running.
    roomServices = 'auto',     -- 'auto' | true | false
}

-- ── Custom hooks (Config.Inventory / Config.Wardrobe = 'custom') ────────────
Config.Hooks = {
    -- Server side. Open stash `id` for player `src`. Access is already checked.
    openStash = function(src, id, label, slots, weight) end,
    -- Client side. Open the outfit wardrobe for apartment `id`.
    openWardrobe = function(id) end,
}

-- ============================================================================
--  Spawn-menu view of the buildings (read by spawn/character selectors).
--  Rebuilt on every read, so a map that starts later still appears.
-- ============================================================================
Apartments = { Starting = Config.Starter.enabled, Locations = {} }

function Apartments.Refresh()
    local locations = {}
    for key, b in pairs(Config.Buildings) do
        local usable = b.enabled ~= false and (b.type ~= 'walkin'
            or (Config.WalkIn.enabled and GetResourceState(b.resource) == 'started'))
        if usable and b.starter ~= false then
            local p = b.type == 'walkin' and b.offices[1] or b.entrance
            locations[key] = { name = key, label = b.label, coords = { enter = vector4(p.x, p.y, p.z, p.w) } }
        end
    end
    Apartments.Locations = locations
    return locations
end

Apartments.Refresh()