6.1 KiB
title, description
| title | description |
|---|---|
| Store Usage Guide | The store module processes checkout requests. It charges a payment source and grants purchased items to the player locker, virtual arsenal locker, virtual garage unlocks, and immediate unit spawn grants. |
Server SQF Module
The server addon uses two long-lived module objects:
StorefrontStoreis the storefront workflow facade. It builds hydrate payloads, validates checkout requests, calls the Ruststore:checkoutcommand, syncs UI patches, asks related module stores to save hot state, and spawns purchased units at discoveredunit_spawnmarkers after the backend charge succeeds.StoreCatalogServicescans configured item and vehicle categories, builds catalog responses, resolves checkout entries, and calculates authoritative prices. It also applies the optional missionCfgStorefilter and overrides before payloads or checkout validation use catalog entries.
Editor-placed store entities are initialized by fnc_initStore during store
post-init. The initializer matches non-null mission namespace objects whose
variable names contain store and sets isStore = true, following the same
pattern used by garage entities.
Mission Catalog Filter
The store catalog is generated from loaded Arma config classes, then an
optional mission CfgStore filter can allow or deny classnames per category.
Include CfgStore.hpp from description.ext:
#include "CfgStore.hpp"
class CfgStore {
mode = "allowlist"; // dynamic, allowlist, or denylist
class Categories {
primary[] = {"arifle_MX_F", "arifle_MXC_F"};
cars[] = {"B_MRAP_01_F"};
units[] = {"B_Soldier_F"};
};
class Overrides {
class arifle_MX_F {
price = 2500;
displayName = "MX Rifle";
description = "Approved PMC service rifle.";
};
};
};
dynamic keeps the full generated catalog. allowlist only shows classnames
listed for each category. denylist removes listed classnames. Overrides are
server-side and are used by both the UI payload and checkout validation.
units[] follows the same filter behavior and is fulfilled as an immediate
server-side unit spawn at a discovered unit_spawn marker after checkout
succeeds.
The current filter is global for the mission. Revisit per-store profile support if individual vendors need different inventories.
Unit Spawn Markers
Purchased units spawn at mission markers named unit_spawn, unit_spawn_1,
unit_spawn_2, and so on. The store resolves the closest initialized store
object to the requesting player, scans allMapMarkers when checkout fulfillment
runs, and uses the closest matching marker within 25 meters of that store.
If no matching marker exists within 25 meters, the store falls back to spawning units around the store object. If no store object can be resolved, it falls back to the requesting player.
Checkout Model
store:checkout accepts one JSON context.
{
"requesterUid": "76561198000000000",
"requesterName": "Player Name",
"orgId": "default",
"requesterIsDefaultOrgCeo": false,
"paymentMethod": "bank",
"items": [
{
"classname": "arifle_MX_F",
"category": "weapon",
"priceValue": 500,
"quantity": 1
}
],
"vehicles": [
{
"classname": "B_Quadbike_01_F",
"category": "cars",
"priceValue": 1500
}
],
"units": [
{
"classname": "B_Soldier_F",
"category": "units",
"priceValue": 2500
}
]
}
Rules validated by the Rust service:
requesterUidis required.- At least one item, vehicle, or unit is required.
- The checkout total must be greater than zero.
- Item categories must be
item,attachment,weapon,magazine, orbackpack. - Vehicle categories must be
cars,armor,helis,planes,naval, orother. - Unit categories must be
unitsorunit. - Payment method must be
cash,bank,org_funds, orcredit_line. - Player locker capacity cannot exceed 25 unique items after checkout.
- Organization funds can only be charged by the org owner or the default org CEO flag.
Command
| Command | Arguments | Returns |
|---|---|---|
store:checkout |
checkout_json |
Checkout result JSON. |
Result Model
{
"chargedTotal": 4500.0,
"paymentMethod": "bank",
"message": "Checkout completed. $4,500 charged, 1 locker grant(s), 1 vehicle unlock(s), 1 unit grant(s).",
"lockerGranted": [],
"vehicleGranted": [],
"unitGranted": [],
"lockerPatch": {},
"vaPatch": {},
"vgaragePatch": {},
"bankPatch": {},
"orgPatch": {},
"orgTargetUids": []
}
Patch fields are intended for UI updates after checkout. The service commits all grants and payment changes together, and attempts rollback if a later write fails.
Player Bank Checkout
private _item = createHashMapFromArray [
["classname", "arifle_MX_F"],
["category", "weapon"],
["priceValue", 500],
["quantity", 1]
];
private _checkout = createHashMapFromArray [
["requesterUid", getPlayerUID player],
["requesterName", name player],
["orgId", "default"],
["requesterIsDefaultOrgCeo", false],
["paymentMethod", "bank"],
["items", [_item]],
["vehicles", []],
["units", []]
];
private _result = "forge_server" callExtension ["store:checkout", [toJSON _checkout]];
Organization Funds Checkout
When paymentMethod is org_funds, vehicles are also added to the
organization fleet patch.
private _vehicle = createHashMapFromArray [
["classname", "B_Quadbike_01_F"],
["category", "cars"],
["priceValue", 1500]
];
private _checkout = createHashMapFromArray [
["requesterUid", getPlayerUID player],
["requesterName", name player],
["orgId", _orgId],
["requesterIsDefaultOrgCeo", false],
["paymentMethod", "org_funds"],
["items", []],
["vehicles", [_vehicle]],
["units", []]
];
private _result = "forge_server" callExtension ["store:checkout", [toJSON _checkout]];
Error Handling
private _payload = _result select 0;
if (_payload find "Error:" == 0) exitWith {
hint format ["Checkout failed: %1", _payload];
};
private _checkoutResult = fromJSON _payload;