Developer
Overview
Other resources read camps through three server exports and the GlobalState snapshot of each camp. Permissions, loot and camp events are changed in open/handlers_server.lua and open/handlers_client.lua, which stay unencrypted.
Server Exports
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')GetCampStatus(campId):'idle','active','combat','cleared','cooldown'or'depleted'.nilfor an unknown campIsCampCleared(campId):truewhile the camp is'cleared'or'cooldown'. A spawn-once camp reports'depleted', so check it withGetCampStatusGetCampAliveCount(campId): enemies still alive
GlobalState
Each camp publishes a live snapshot under mlcamp_<campId>, readable on server and client:
lua
1local snap = GlobalState['mlcamp_bandit_grapeseed']status: same values asGetCampStatusalive,total: enemies alive and enemies spawnednextRespawn: unix time when the cooldown ends,0otherwisewave,waves: current wave and total waves of a horde camp
The HUD settings are published under mlcampcfg as { enabled, position, resetVisibilityDefault }.
Entity State
Camp NPCs carry these keys on their entity state:
mlCampPed:trueon every camp NPCmlCampId: ID of the camp the NPC belongs tomlCampZombie: set on NPCs of a zombie groupmlCampNoRagdoll,mlCampNoCrit: set when the group has ragdoll or headshot kills turned off
Server Handlers
Located in open/handlers_server.lua.
open/handlers_server.lua
1Handlers.HasCreatorPermission = function(source)
2 return checkPermissionTier(source, Config.Permissions.Creator)
3end
4
5Handlers.HasLivePermission = function(source)
6 return checkPermissionTier(source, Config.Permissions.LiveActions)
7end
8
9Handlers.OnCampActivated = function(campId, campData)
10end
11
12Handlers.OnCampWave = function(campId, campData, wave, totalWaves)
13end
14
15Handlers.OnCampCleared = function(campId, campData, raiders)
16end
17
18Handlers.ModifyLoot = function(campId, items, money)
19 return items, money
20endHasCreatorPermission,HasLivePermission: the two staff tiers. The shipped version readsConfig.Permissionsthroughml_bridge. Replace them to use your own permission systemOnCampActivated: a camp spawns its NPCsOnCampWave: a new wave of a horde camp spawnsOnCampCleared: the last enemy dies.raiderslists the credited player IDs in the order they enteredModifyLoot: runs on each raider's roll for direct delivery, and once on the shared pool for crates. Return theitemslist as{ name, count, metadata? }andmoneyas{ account, amount }ornil
Client Handlers
Located in open/handlers_client.lua.
open/handlers_client.lua
1Handlers.CanShowCampBlip = function(campId, campData)
2 return true
3end
4
5Handlers.IsPlayerDead = function()
6 return Bridge.IsPlayerDead() or IsPedDeadOrDying(cache.ped, true)
7end
8
9Handlers.OnCampEntered = function(campId, campData)
10end
11
12Handlers.OnEnemyPedReady = function(ped, weaponHash)
13endCanShowCampBlip: returnfalseto hide a camp blip for the local playerIsPlayerDead: camp NPCs stop targeting a player for whom this returnstrue. Change it if your death script uses its own stateOnCampEntered: the local player walks into a campOnEnemyPedReady: a camp NPC is set up and armed. Apply your own weapon damage rules to camp enemies here
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
7end)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 if value and (value.status == 'cooldown' or value.status == 'depleted') then
4 print(('camp %s cleared'):format(key:sub(8)))
5 end
6end)your_script/client.lua
1for _, ped in ipairs(GetGamePool('CPed')) do
2 if ped ~= cache.ped and not Entity(ped).state.mlCampPed then
3 print(ped)
4 end
5end