RE:CORD
REC_BusinessManager

Stracture

Installation, configuration, and usage for REC_BusinessManager.
Added
Updated

The following configuration files and manifest are taken from the current source.

config/sh_config.lua

---[[
---     REC_BusinessManager shared config
---     https://docs.re-cord.dev/en/resources/rec_businessmanager
---]]

---@class REC_BusinessManager.Shared.Config
local config = {}

---[[
---    Debug Mode
---]]
---@type boolean
config.debugMode = true

---[[
---     The tablet
---     The command is open to everybody: what a player may do inside is decided by the
---     server from the paperwork they own, and the staff pages come from config.web.grants.
---]]
config.tablet = {

    ---@type string
    command = "business",

    ---@type string
    help = "Open the business tablet",

    ---[[
    ---     Item that opens the same tablet.
    ---     Inventories disagree about how a usable item reaches a resource, so the
    ---     item definition points at the export instead:
    ---         ox_inventory items.lua -> server.export = "REC_BusinessManager.useTablet"
    ---]]
    ---@type string|nil
    item = "business_tablet",

    ---[[
    ---     A player standing next to an approved computer prop opens the tablet from
    ---     the target instead, without carrying anything.
    ---]]
    ---@type boolean
    useComputerTarget = true,
}

---[[
---     Zone builder
---     The applicant walks the outline and drops a point at their own feet, so the
---     polygon is always something they can physically stand on.
---]]
config.zoneBuilder = {

    ---@type integer
    minPoints = 3,

    ---@type integer
    maxPoints = 24,

    ---[[
    ---     Two points closer than this are refused, which keeps a held key from
    ---     filling the polygon with duplicates.
    ---]]
    ---@type number
    minPointDistance = 0.8,

    ---[[
    ---     How far the outline may reach from its first point. A business is a place,
    ---     not a district, and an unbounded polygon is the easiest way to grief this.
    ---]]
    ---@type number
    maxRadius = 120.0,

    ---[[
    ---     Height of the finished PolyZone, in metres, centred on the points.
    ---]]
    thickness = {

        ---@type number
        default = 6.0,

        ---@type number
        min = 2.0,

        ---@type number
        max = 30.0,
    },

    ---@type REC_Library.Shared.RGBA
    lineColour = { r = 0, g = 255, b = 136, a = 220, },

    ---@type REC_Library.Shared.RGBA
    pointColour = { r = 0, g = 255, b = 136, a = 160, },

    ---@type number
    pointScale = 0.35,
}

---[[
---     Door picker
---     Existing MLO doors are not props this resource owns, so they are picked out of
---     the world by looking at them rather than placed.
---]]
config.doorPicker = {

    ---@type number
    maxDistance = 6.0,

    ---[[
    ---     Model names the picker refuses. Everything else that is a door shaped
    ---     object may be claimed, as long as it sits inside one of the zones.
    ---]]
    ---@type table<string, boolean>
    blockedModels = {
        ["v_ilev_gtdoor"] = true,
    },
}

---[[
---     What a 起業届 has to contain before it can be submitted
---     required = false leaves the row visible on the checklist but never blocks the
---     submission, which is how the mailbox is made optional.
---]]
config.blueprint = {

    ---@type { min: integer, max: integer, }
    name = { min = 3, max = 48, },

    ---@type { min: integer, max: integer, }
    description = { min = 10, max = 1000, },

    ---[[
    ---     Placements outside every declared zone are refused on save.
    ---     Turn it off for businesses that own something across the street.
    ---]]
    ---@type boolean
    requirePlacementsInsideZone = true,

    ---@type { required: boolean, min: integer, max: integer, }
    zones = { required = true, min = 1, max = 3, },

    ---[[
    ---     One row per placement type.
    ---     models is the list the spawn panel of the world editor offers, and the
    ---     server refuses anything that is not on it, so this is the allowlist too.
    ---]]
    ---@type table<string, REC_BusinessManager.Shared.Config.Placement>
    placements = {

        ["mailbox"] = {
            required = true,
            min = 1,
            max = 1,
            models = {
                "prop_postbox_01a",
                "prop_mailbox_01a",
            },
        },

        ["computer"] = {
            required = true,
            min = 1,
            max = 2,
            models = {
                "prop_laptop_01a",
                "xm_prop_x17_computer_01",
                "prop_monitor_01a",
            },
        },

        ["stash"] = {
            required = true,
            min = 1,
            max = 4,
            models = {
                "prop_toolchest_01",
                "prop_boxpile_06b",
                "v_ret_gc_shelf01",
            },
        },

        ["trash"] = {
            required = false,
            min = 0,
            max = 4,
            models = {
                "prop_bin_07a",
                "prop_dumpster_01a",
            },
        },

        ---[[
        ---     Doors the applicant places themselves. Doors that already exist in an
        ---     MLO are claimed through the door picker instead and are not restricted
        ---     by this list.
        ---]]
        ["door"] = {
            required = false,
            min = 0,
            max = 8,
            models = {
                "v_ilev_ph_door01",
                "prop_gate_docks_ld",
            },
        },
    },
}

---[[
---     First entry camera tour
---     Plays once the paperwork is approved and the player walks in for the first time.
---     The business name stays on screen for the whole flight.
---]]
config.tour = {

    ---@type boolean
    enabled = true,

    ---[[
    ---     true plays the tour the first time a player walks in and never again while
    ---     they stay connected, false replays it on every entry.
    ---]]
    ---@type boolean
    onlyOnce = true,

    ---@type number
    fov = 50.0,

    ---[[
    ---     Where the camera sits relative to the thing it is showing.
    ---]]
    ---@type number
    distance = 3.5,

    ---@type number
    height = 1.6,

    ---[[
    ---     Blend time between two stops, and how long a stop is held afterwards.
    ---]]
    ---@type integer
    blendDuration = 1600,

    ---@type integer
    holdDuration = 1200,

    ---[[
    ---     Any control press ends the tour early.
    ---]]
    ---@type boolean
    skippable = true,
}

---[[
---     Runtime
---     What an approved business turns into once a player is standing in it.
---]]
config.runtime = {

    ---[[
    ---     Props are spawned client side, so they cost no network id.
    ---]]
    ---@type number
    targetDistance = 1.6,

    stash = {

        ---@type integer
        slots = 50,

        ---@type integer
        maxWeight = 100000,
    },

    ---[[
    ---     A marker on the map for every approved business.
    ---]]
    blip = {

        ---@type boolean
        enabled = true,

        ---@type integer
        sprite = 431,

        ---@type integer
        colour = 2,

        ---@type number
        scale = 0.7,
    },

    ---[[
    ---     Doors are registered with the game door system on entry and released on
    ---     exit. locked is the state an approved door starts in.
    ---]]
    door = {

        ---@type boolean
        register = true,

        ---@type boolean
        locked = false,
    },
}

return config

---@

---@class REC_BusinessManager.Shared.Config.Placement
---@field required boolean
---@field min integer
---@field max integer
---@field models string[]
©2026 RE:CORD Development Group. All rights reserved.