Developer

4 min readUpdated 3 weeks ago

Overview

Integration uses server exports for zone state, handler hooks in open/handlers_server.lua for loot flow and access control, and open/handlers_client.lua for interaction and UI customization.

Server Exports

lua
1local zoneData = exports['ml_lootzones']:GetZoneData(areaId)
2local allZones = exports['ml_lootzones']:GetAllZones()
3local inZone = exports['ml_lootzones']:IsPlayerInZone(source, areaId)
4local refreshed = exports['ml_lootzones']:RefreshZoneLoot(areaId)
5local toggled = exports['ml_lootzones']:SetZoneEnabled(areaId, enabled)
  • GetZoneData(areaId): Returns the zone's configuration data, or nil
  • GetAllZones(): Returns array of { id, name, category }
  • IsPlayerInZone(source, areaId): Returns true if the player is inside the zone
  • RefreshZoneLoot(areaId): Forces a respawn of loot in a zone. Returns true on success
  • SetZoneEnabled(areaId, enabled): Temporarily enable/disable a zone. Returns true on success

Server Handlers

Located in open/handlers_server.lua.

Loot Flow

open/handlers_server.lua
1function Handlers.OnBeforeClaim(source, areaId, lootIndex, lootConfig, areaData)
2    return true -- return false to block
3end
4
5function Handlers.OnAfterClaim(source, areaId, lootIndex, itemsGiven, areaData)
6end
7
8function Handlers.GetLootMultiplier(source, areaId, areaData)
9    return 1.0 -- 2.0 = double loot
10end
11
12function Handlers.ModifyLoot(source, areaId, fixedLoots, probabilityLoots, areaData)
13    return fixedLoots, probabilityLoots
14end
15
16function Handlers.GetBonusLoot(source, areaId, areaData)
17    return nil -- return { {name='item', amount=1} } for extra items
18end
  • OnBeforeClaim: Called before loot is given. Return false to block.
  • OnAfterClaim: Called after items are distributed. itemsGiven contains the awarded items.
  • GetLootMultiplier: Multiply item amounts. 2.0 = double loot.
  • ModifyLoot: Intercept and modify loot tables before generation.
  • GetBonusLoot: Return extra items to add on top of normal loot.

Access Control

open/handlers_server.lua
1function Handlers.CanPlayerLootZone(source, areaId, areaData)
2    return true, nil -- return false, 'reason' to block
3end
4
5function Handlers.CanPlayerClaimLoot(source, areaId, lootIndex, lootConfig)
6    return true, nil
7end
8
9function Handlers.OnClaimBlocked(source, areaId, lootIndex, reason)
10end
  • CanPlayerLootZone: Gate access to a zone. Return false + reason string to block.
  • CanPlayerClaimLoot: Gate access to a specific loot point.
  • OnClaimBlocked: Fires when a claim is blocked by cooldown, distance, or access hooks.

Dispatch

open/handlers_server.lua
1function Handlers.ShouldTriggerDispatch(source, areaId, areaData)
2    return nil -- true/false to override, nil for default
3end
4
5function Handlers.ModifyDispatchData(source, areaId, dispatchData)
6    return dispatchData
7end
  • ShouldTriggerDispatch: Override dispatch trigger. nil = use default chance.
  • ModifyDispatchData: Modify dispatch data before sending.

Tools

open/handlers_server.lua
1function Handlers.ValidateTool(source, areaId, toolName, lootConfig)
2    return nil -- true (allow), false (reject), nil (default)
3end
4
5function Handlers.GetToolDurabilityDrain(source, areaId, toolName, baseDrain)
6    return nil -- return a number to override drain amount
7end

Regeneration

open/handlers_server.lua
1function Handlers.GetRegenOverride(areaId, lootIndex, baseRegen, areaData)
2    return nil -- return seconds to override regen time
3end
4
5function Handlers.OnLootRegenerated(areaId, lootIndex)
6end
  • GetRegenOverride: Override the regeneration timer for a specific loot point.
  • OnLootRegenerated: Fires when a loot point regenerates.

Configuration Events

open/handlers_server.lua
1function Handlers.OnZoneSaved(source, areaId, areaData, isNew)
2end
3
4function Handlers.OnZoneDeleted(source, areaId)
5end
6
7function Handlers.OnCategorySaved(source, categoryId, categoryData, isNew)
8end

Client Handlers

Located in open/handlers_client.lua.

Interaction

open/handlers_client.lua
1function Handlers.CanInteractWithLoot(areaId, lootIndex, lootConfig, entity)
2    return true -- return false to hide target
3end
4
5function Handlers.GetCustomTargetLabel(areaId, lootIndex, lootConfig)
6    return nil -- return string to override
7end
8
9function Handlers.GetCustomTargetIcon(areaId, lootIndex, lootConfig)
10    return nil -- return string to override
11end
12
13function Handlers.AddCustomTargetOptions(areaId, lootIndex, lootConfig, entity)
14    return {} -- return extra target options
15end

Loot Lifecycle

open/handlers_client.lua
1function Handlers.CanLootFromZone(areaId, lootIndex, lootConfig)
2    return true, nil
3end
4
5function Handlers.OnBeforeLoot(areaId, lootIndex, lootConfig)
6end
7
8function Handlers.OnAfterProgress(areaId, lootIndex, lootConfig)
9    return true -- return false to cancel claim
10end
11
12function Handlers.OnLootClaimed(data)
13    -- data = { zoneId, zoneName, category, propModel, propIndex, coords, isLootBox }
14end
15
16function Handlers.OnLootFailed(areaId, lootIndex, reason)
17end

Stash & Animation

open/handlers_client.lua
1function Handlers.OnBeforeOpenStash(stashId, areaId, lootIndex)
2end
3
4function Handlers.OnAfterCloseStash(stashId, areaId)
5end
6
7function Handlers.GetCustomAnimation(areaId, lootConfig)
8    return nil -- return animation table to override
9end

Zone Tracking

open/handlers_client.lua
1function Handlers.OnZoneEnter(areaId, areaData)
2end
3
4function Handlers.OnZoneExit(areaId)
5end
6
7function Handlers.OnLootSpawned(areaId, lootTable)
8end
9
10function Handlers.OnLootDespawned(areaId)
11end

Examples

open/handlers_server.lua
1local eventActive = false
2
3Handlers.CanPlayerLootZone = function(source, areaId, areaData)
4    if eventActive then
5        return false, 'Looting is disabled during an active event'
6    end
7    return true
8end
open/handlers_server.lua
1Handlers.GetLootMultiplier = function(source, areaId, areaData)
2    local job = Bridge.GetJob(source)
3    if job and job.name == 'vip' then
4        return 2.0
5    end
6    return 1.0
7end
open/handlers_client.lua
1Handlers.GetCustomTargetLabel = function(areaId, lootIndex, lootConfig)
2    if areaId == 'military_zone' then
3        return 'Search Military Crate'
4    end
5    return nil
6end