Gun Rack
Gameplay

Gameplay

Medit8z Gun Rack has two access paths — the officer path for on-duty allowed jobs, and the civilian path for any player who has acquired a gunrack_key. Every action is server-validated.

Officer flow

Install

  1. An on-duty officer (job in Config.AllowedJobs) stands within MaxInstallDistance of a parked vehicle whose class matches Config.AllowedVehicleClass.
  2. The officer uses the gunrack item from inventory.
  3. The driver door opens and a 5-second ox_lib progress bar runs.
  4. On completion the gunrack item is consumed, a row is inserted into the gunracks table keyed by plate, and a fresh Ox Inventory stash is registered for the plate.

If the player isn't on an allowed job, isn't near an allowed-class vehicle, or the plate already has a rack, the install is rejected and the item is not consumed.

Open (authorized)

On-duty officers open the stash from inside the vehicle, typically via your target script firing the medit8z_gunrack:server:open event with the plate. Officers do not need a gunrack_key.

Uninstall

  1. An on-duty officer sits inside the vehicle.
  2. The officer runs /removegunrack.
  3. The server validates job, plate, and stash contents.
  4. If the stash is empty, the rack is removed from the database and the gunrack item is returned to the officer's inventory.
⚠️

Uninstall is rejected if the stash contains any items. Move all weapons out first — this is a safety guard, not a bug.

CommandEffect
/removegunrackUninstall the rack from the current vehicle. Job-locked, empty-only.

Civilian flow

Civilians (any player whose job is not in Config.AllowedJobs) interact with installed racks via the gunrack_key item.

  1. The civilian sits inside a vehicle that already has a rack installed on its plate.
  2. The civilian uses a gunrack_key.
  3. The key is consumed and the stash opens for one access.
  4. Closing the stash ends access — opening it again requires another key.

This is intended to drive the "stolen squad car / lost equipment" RP loop: officers leave weapons in the rack, the vehicle gets jacked, the thief needs a key (loot, craft, or buy) to crack it, and every key is one-shot.

Persistence

  • Each plate maps to exactly one rack — the gunracks.plate column has a UNIQUE constraint, and the script also rejects double-installs at the application layer.
  • Stash contents are owned by Ox Inventory and persist across restarts via its standard stash storage.
  • On every server start, every row in gunracks is re-registered as an Ox Inventory stash, so the rack is immediately accessible after a restart.
  • Removing a vehicle from the world does not remove its rack — only /removegunrack (with an empty stash) deletes the row.

Edge cases

SituationBehavior
Two racks on the same vehicleRejected — UNIQUE plate constraint plus app-level guard.
Lightbar utility prop is class 18Add its model prefix to Config.IgnoredModelPrefixes.
Civilian uses a key with no installed rackRejected — key is not consumed.
Officer uninstalls a rack with weapons insideRejected — must empty first.
Vehicle is destroyed / impoundedRack row remains; reissuing the same plate restores access to the original stash.

See Troubleshooting for failure-case fixes.