# Locker System Integration Guide ## Overview The locker system provides persistent item storage for Arma 3 players. Each player can store multiple items (weapons, magazines, equipment) with quantity tracking. ## Data Storage - Each player's locker is persisted by the server extension through SurrealDB. - The map is keyed by the item's **classname** (String) - Each item tracks: `category`, `classname`, and `amount` - **Maximum Capacity**: 25 unique items per locker - **Empty lockers are auto-created** when a player first fetches their locker if it doesn't exist ## Extension Commands All commands are accessed via the `locker` group: ### Create Locker Creates a new empty locker for a player. Should be called when initializing a new player if one doesn't exist. ```sqf private _result = "forge_server" callExtension ["locker:create", [getPlayerUID player]]; // Returns: {} (empty map) or Error message ``` ### Get Locker Retrieves all items in a player's locker. ```sqf private _result = "forge_server" callExtension ["locker:get", [getPlayerUID player]]; private _lockerMap = fromJSON (_result select 0); // Returns: {"arifle_MX_F": {"classname":"arifle_MX_F","category":"Weapon","amount":1}, ...} ``` ### Add Item Adds a new item to the locker or updates the amount if it already exists. **Checks capacity limit (25 items).** ```sqf private _data = createHashMapFromArray [ ["classname", "arifle_MX_F"], ["category", "Weapon"], ["amount", 1] ]; private _result = "forge_server" callExtension ["locker:add", [ getPlayerUID player, toJSON _data ]]; private _updatedLocker = fromJSON (_result select 0); // Returns updated locker map ``` ### Update Locker (Sync) Updates the entire locker state. Useful for syncing changes made locally (e.g., bulk moves). **Replaces the entire locker content.** ```sqf // _lockerMap is the local HashMap of items private _result = "forge_server" callExtension ["locker:update", [ getPlayerUID player, toJSON _lockerMap ]]; private _updatedLocker = fromJSON (_result select 0); ``` ### Patch Item Updates specific fields (currently `amount`) of an existing item without sending the entire locker. **Efficient for quantity changes.** ```sqf private _classname = "arifle_MX_F"; private _data = createHashMapFromArray [ ["classname", _classname], ["amount", 5] // New amount ]; private _result = "forge_server" callExtension ["locker:patch", [ getPlayerUID player, toJSON _data ]]; private _updatedLocker = fromJSON (_result select 0); ``` ### Remove Item Removes a specific item from the locker by classname. ```sqf private _classname = "arifle_MX_F"; private _data = createHashMapFromArray [ ["classname", _classname] ]; private _result = "forge_server" callExtension ["locker:remove", [ getPlayerUID player, toJSON _data ]]; private _updatedLocker = fromJSON (_result select 0); ``` ### Delete Locker Permanently deletes all items from a player's locker. ```sqf private _result = "forge_server" callExtension ["locker:delete", [getPlayerUID player]]; // Returns: "OK" or "Error: ..." ``` ### Check Existence Checks if a player has a locker created. ```sqf private _result = "forge_server" callExtension ["locker:exists", [getPlayerUID player]]; private _exists = (_result select 0) == "true"; ``` ## Complete Integration Example ### Storing an Item ```sqf fnc_storeCurrentWeapon = { private _weapon = currentWeapon player; if (_weapon == "") exitWith { hint "No weapon in hand!"; }; // Create item data private _data = createHashMapFromArray [ ["classname", _weapon], ["category", "Weapon"], ["amount", 1] ]; // Add to locker private _result = "forge_server" callExtension ["locker:add", [ getPlayerUID player, toJSON _data ]]; // Check for error (e.g., full locker) if ((_result select 0) find "Error:" == 0) exitWith { hint format ["Failed to store item: %1", _result select 0]; false }; // Remove weapon from player player removeWeapon _weapon; hint format ["Stored %1 in locker!", _weapon]; true }; ``` ### Retrieving an Item ```sqf fnc_retrieveItem = { params ["_classname"]; // Get locker private _result = "forge_server" callExtension ["locker:get", [getPlayerUID player]]; private _locker = fromJSON (_result select 0); // Check if item exists private _item = _locker getOrDefault [_classname, locationNull]; if (_item isEqualTo locationNull) exitWith { hint "Item not found in locker!"; false }; // Get amount private _amount = _item get "amount"; if (_amount <= 0) exitWith { // Should not happen, but safe to handle hint "Item out of stock!"; false }; // Add to player if (player canAdd _classname) then { player addItem _classname; // Decrement amount or remove if 0 if (_amount > 1) then { private _patchData = createHashMapFromArray [ ["classname", _classname], ["amount", _amount - 1] ]; "forge_server" callExtension ["locker:patch", [getPlayerUID player, toJSON _patchData]]; } else { private _removeData = createHashMapFromArray [ ["classname", _classname] ]; "forge_server" callExtension ["locker:remove", [getPlayerUID player, toJSON _removeData]]; }; hint format ["Retrieved %1 from locker!", _classname]; true } else { hint "Not enough space in inventory!"; false }; }; ``` ## Error Handling All commands return errors in the format `"Error: "`. ```sqf private _result = "forge_server" callExtension ["locker:add", ...]; private _data = _result select 0; if (_data find "Error:" == 0) then { systemChat format ["Locker error: %1", _data]; }; ```