Developer
Overview
Integration runs through three server exports, replicated GlobalState keys any resource can read, and handler hooks in the open/ folder (shipped unescrowed).
Server Exports
GetCampStatus(campId): Returns the runtime status string, or nil for an unknown camp: 'idle' | 'active' | 'combat' | 'cleared' | 'cooldown' | 'depleted'IsCampCleared(campId): Returns true while the camp status is 'cleared' or 'cooldown'. Spawn-once camps report 'depleted' instead; checkGetCampStatusfor thoseGetCampAliveCount(campId): Number of hostiles still alive
lua
1local status = exports.ml_camps:GetCampStatus('bandit_grapeseed')
2local cleared = exports.ml_camps:IsCampCleared('bandit_grapeseed')
3local alive = exports.ml_camps:GetCampAliveCount('bandit_grapeseed')GlobalState
Every camp replicates a live snapshot under mlcamp_<campId>, readable on both sides:
lua
1local snap = GlobalState['mlcamp_bandit_grapeseed']
2-- {
3-- status = 'combat', -- idle | active | combat | cleared | cooldown | depleted
4-- alive = 3, -- hostiles alive
5-- total = 6, -- hostiles spawned
6-- nextRespawn = 0, -- unix timestamp when the cooldown ends, 0 otherwise
7-- }The active raid HUD settings are replicated under mlcampcfg as { enabled, position, resetVisibilityDefault }. Camp NPCs carry mlCampPed = true and mlCampId on their entity state bag, so other scripts can recognize them.
Server Handlers
Located in open/handlers_server.lua.
open/handlers_server.lua
1Handlers.HasCreatorPermission = function(source)
2 -- return true to allow the admin panel
3end
4
5Handlers.HasLivePermission = function(source)
6 -- return true to allow force clear / force reset / teleport
7end
8
9Handlers.OnCampActivated = function(campId, campData)
10end
11
12Handlers.OnCampCleared = function(campId, campData, raiders)
13 -- raiders: array of credited server ids, entry order
14end
15
16Handlers.ModifyLoot = function(campId, items, money)
17 return items, money
18endHasCreatorPermission/HasLivePermission: Permission gates for the two staff tiers. The default implementation checksConfig.Permissionsthrough ml_bridge; replace it to plug in any permission systemOnCampActivated: Fires when a camp spawns its NPCsOnCampCleared: Fires when the last hostile dies.raidersholds the credited player idsModifyLoot: Called before every loot payout (direct and per crate). Return the modifieditemsarray ({ name, count, metadata? }) andmoneytable ({ account, amount }or nil)
Client Handlers
Located in open/handlers_client.lua.
open/handlers_client.lua
1Handlers.CanShowCampBlip = function(campId, campData)
2 return true -- return false to hide this camp's blip for the local player
3end
4
5Handlers.OnCampEntered = function(campId, campData)
6endCanShowCampBlip: Per-player blip filter, evaluated when camps loadOnCampEntered: Fires when the local player crosses into a camp radius
Examples
open/handlers_server.lua
1Handlers.OnCampCleared = function(campId, campData, raiders)
2 for _, src in ipairs(raiders) do
3 Bridge.GiveItem(src, 'water', 1)
4 end
5endopen/handlers_server.lua
1Handlers.ModifyLoot = function(campId, items, money)
2 local camp = Config.Camps[campId]
3 if camp and camp.type == 'military' and money then
4 money.amount = math.floor(money.amount * 1.5)
5 end
6 return items, money
7endyour_script/server.lua
1RegisterNetEvent('myscript:enterBunker', function()
2 local src = source
3 if not exports.ml_camps:IsCampCleared('military_zancudo') then
4 Bridge.NotifyPlayer(src, 'error', 'Clear the outpost first.')
5 return
6 end
7 -- open the bunker
8end)your_script/client.lua
1AddStateBagChangeHandler(nil, 'global', function(_, key, value)
2 if type(key) ~= 'string' or key:sub(1, 7) ~= 'mlcamp_' then return end
3 local campId = key:sub(8)
4 if value and value.status == 'cleared' then
5 print(('camp %s cleared near %s'):format(campId, tostring(cache.ped)))
6 end
7end)your_script/client.lua
1local function isCampNpc(ped)
2 return Entity(ped).state.mlCampPed == true
3end
4
5-- e.g. skip camp NPCs in a ped-scanning loop
6for _, ped in ipairs(GetGamePool('CPed')) do
7 if ped ~= cache.ped and not isCampNpc(ped) then
8 -- safe to process
9 end
10end