Secret Hideout
Secret Hideout is a map: a phone repair shop and, under a hatch in its technical room, a lower level of three rooms that comes in five setups. The setups are dressing, not gameplay. What the script runs is the hatch and its two levers, the switch between setups and the people working downstairs.
Requirements#
- Game build 3717 or newer. Some of the props come from recent DLCs.
- OneSync, recommended. The server uses it for two checks: that the player who pulls a lever is standing next to it, and that nobody is in the shaft when the hatch closes. Without OneSync the resource still runs, prints a warning on start and skips both checks.
- No framework and no other resources. It’s standalone.
- Built and tested on FiveM (GTA V Legacy).
Install#
- Get the files. Owner: under Granted Assets in your Cfx.re Portal. Developer: the download link in the Tebex email.
- Put the
secret_mlofolder in your server resources. Keep that name: the export uses it. - Add these lines to your
server.cfgand restart, or runrefreshandensure secret_mloin the server console:
sv_enforceGameBuild 3717
ensure secret_mloWhere it is#
The interior is smlo_hackshop. Its door is the basement door of the building in the alley, at about 2.4, -1215.1, 25.9. In the game that door is painted on the wall; this resource cuts it out of the building so you can walk in (see Conflicts with other maps).
The upper level sits just below the street, down a short stairway from the alley door: the shop, its counter and stock room, a toilet, a workshop, a storeroom and the technical room. The way down is the hatch in the technical room: it opens onto a shaft with a ladder, and at the bottom there are the three rooms of the lower level.
The resource also streams the floor plan of the interior for the radar and the pause map.
Setups#
The lower level comes in five setups. Only one shows at a time, for every player.
| Setup | What’s in it |
|---|---|
blackhat |
The default. Desks, a map table and an operations desk |
meth |
A meth lab |
coke |
Tables for cutting, bagging and weighing coke |
weed |
A weed farm |
empty |
Bare concrete: the doors, the ladder and the hatch with its levers, the wire cage and grille of the middle room, the ducts and the strip lights, lit plain white. For servers that want to furnish it with their own props |
See all five in the video on the product page.
Each setup is an entity set of the interior (smlo_meth, smlo_coke and so on). None of them comes with a job, a drug system or a hack: that’s up to your scripts.
Pick the one it starts with#
When the resource starts, it uses the first of these that is set:
- The convar
smlo_variant, inserver.cfgbeforeensure secret_mlo. Config.Variantinconfig.lua, which isblackhatout of the box.
set smlo_variant meth
ensure secret_mloIf the convar names a setup that doesn’t exist, the server says so in its console and uses Config.Variant.
Switch it live#
With the command:
smlo_variant cokeFrom the server console it always works. Players need the ace command.smlo_variant:
add_ace group.admin command.smlo_variant allowWithout a name, the command prints the setup in use.
From another server script, with the export:
local ok = exports.secret_mlo:setVariant('weed')| Export | Side | Returns |
|---|---|---|
setVariant(name) |
Server | true, or false if name isn’t one of the five setups |
Players near the MLO reload the interior on the spot when the setup changes. Nobody needs to leave or reconnect.
Switching with players on the lower level can leave someone inside a piece of furniture of the new setup. It’s best to switch while the lower level is empty.
A live change lasts until the resource restarts. Then the convar, or Config.Variant if the convar isn’t set, applies again.
Read it from your scripts#
The setup in use is in GlobalState.smlo_variant, and GlobalState.smlo_hatch is true while the hatch is open. Your scripts can read them, for instance to start a job only when the lab is there:
if GlobalState.smlo_variant == 'meth' then
-- your code
endOnly this resource should write them.
The hatch and the levers#
There are two levers: one in the technical room, out of sight on the side of the big electrical cabinet, and one on the wall at the bottom of the shaft. Walking up to either shows a prompt, “Press E to pull the lever.” Pulling it opens or closes the hatch for everyone: the server holds its state, so all players see the same hatch. Other players see the pull too. The hatch takes about 6 seconds to move, and the ladder can be climbed once it has fully opened.
An open hatch closes by itself Config.AutoCloseSeconds after it finishes opening: 45 by default, 0 for never. With OneSync it won’t close while a player is in the shaft; it waits until the shaft is empty. A lever pulled while the hatch is moving shows “The hatch is already moving.”
Settings#
These are in config.lua, which is open in both editions:
| Setting | Default | What it does |
|---|---|---|
Config.AutoCloseSeconds |
45 |
Seconds before an open hatch closes by itself. 0 = never |
Config.Key |
51, ~INPUT_CONTEXT~ |
Control that pulls a lever (51 = E) and the label shown in the prompt |
Config.Distance.prompt |
0.9 |
Metres from the spot in front of a lever at which the prompt shows |
Config.Distance.pull |
2.0 |
Metres from a lever the server accepts a pull from (needs OneSync) |
Config.Locale |
'en' |
Language of the prompts: en or es |
To add a language, copy locales/en.lua to locales/<code>.lua, change Locales.en to Locales.<code>, translate the four lines and set Config.Locale to that code.
The positions of the hatch, the levers, the ladder and the shaft are in shared/mlo.lua. They belong to the interior: moving them breaks the hatch.
Who can use the levers#
server/permissions.lua holds canUse(source, lever). source is the player’s server id and lever is 1 for the one in the technical room or 2 for the one at the bottom of the shaft. Return true to let the pull through. Out of the box it lets everyone through. The file is open in both editions and has commented examples for an ace, an ESX job, a QBCore job and an ox_inventory item.
With an ace, no framework needed:
function canUse(source, lever)
return IsPlayerAceAllowed(source, 'secret_mlo.hatch')
endadd_ace group.admin secret_mlo.hatch allowWith a keycard in ox_inventory, only to go down (anyone can open it from below):
function canUse(source, lever)
if lever == 2 then return true end
return exports.ox_inventory:Search(source, 'count', 'keycard') > 0
endA refused player sees “The lever won’t move.” With OneSync, so does a player further from the lever than Config.Distance.pull.
People downstairs#
Each furnished setup has six people working on the lower level: in the hall, the middle room and the camera room, and a guard in the shaft room. Upstairs, in every setup, someone behind the counter and someone at the computer of the workshop. They exist only on each player’s own game, appear when the player comes near the MLO and go away when they leave, change with the setup, can’t be hurt and don’t react to anything. empty has nobody downstairs.
| Setting | Default | What it does |
|---|---|---|
Config.Ambience.enabled |
true |
Everyone on or off |
Config.Ambience.perVariant |
all four true |
The crew of each furnished setup on or off |
Config.Ambience.shopkeeper |
true |
Someone behind the counter upstairs |
Config.Ambience.workshop |
true |
Someone at the computer of the workshop upstairs |
Their places are in shared/ambience.lua, open in both editions. Each group there is one scene, placed by the at of its first ped: moving it moves the people and their props together, so a group moved by hand no longer lines up with its chair or table.
Conflicts with other maps#
To make the basement door walkable, stream/ carries two of the game’s own files with that door cut out:
sc1_00b_bld2.ydr, the building;lr_sc1_00b_0.ybn, its collision.
If another resource on your server also replaces either of them, only one version loads. With the other version, the door of this MLO shows painted shut or its collision blocks the way in.
To check, search your resources folder for those two file names. Keep one copy: remove them from the other resource if it doesn’t need them, or ask its author for a version without them. Both files are left unencrypted so you can swap them.
stream/int721482162.gfx is the floor plan on the radar and the pause map. Deleting it removes only that.
Debug mode#
Add this to server.cfg, before ensure secret_mlo:
setr smlo_debug 1The server and the client then print what they do (pulls, refusals, setup changes, props created) to their consoles, and three commands become available:
| Command | Side | What it does |
|---|---|---|
smlo_hatch |
Server | Opens or closes the hatch without a lever |
smlo_ladder |
Client (F8) | Creates or removes the ladder of the shaft |
smlo_crewreport |
Server console, or the ace command.smlo_crewreport |
Every client near the MLO reports where each ped and prop of the crew really is. Printed with the prefix [secret_mlo] crew and written to crew_report.txt in the resource folder |
Debug mode is for setting up. Leave it off on a live server: while it’s on, anyone can run smlo_hatch.
Reference#
| Kind | Name | Side | What it is |
|---|---|---|---|
| Command | smlo_variant <name> |
Server | Changes the setup. Ace command.smlo_variant |
| Command | smlo_hatch |
Server | Debug only. Toggles the hatch |
| Command | smlo_ladder |
Client | Debug only. Toggles the ladder |
| Export | setVariant(name) |
Server | Changes the setup. Returns true or false |
| Event | secret_mlo:pull (index) |
Client to server | A player asks to pull lever 1 or 2 |
| Event | secret_mlo:lever (index, source) |
Server to all | A pull was accepted: play the lever animation |
| Event | secret_mlo:refused (label) |
Server to client | A pull was refused, with the text label to show |
| State bag | GlobalState.smlo_hatch |
Shared | true while the hatch is open |
| State bag | GlobalState.smlo_variant |
Shared | Name of the setup in use |
| Convar | smlo_variant |
Server | Setup on start, wins over Config.Variant |
| Convar | smlo_debug |
Both | 1 = debug prints and commands. Use setr |