- Rework org and store UI state modules (rename/move store/getter files, add runtime and bridge wiring) - Update store UI components and page structure (navbar/cart split, new StoreView flow) - Apply broad markdown/YAML/HTML/CSS/JS formatting cleanup across docs, templates, and workflows
275 lines
7.9 KiB
Markdown
275 lines
7.9 KiB
Markdown
# Garage System Integration Guide
|
|
|
|
## Overview
|
|
|
|
The garage system provides complete vehicle storage, retrieval, and management for Arma 3 players. Each player can store multiple vehicles with full damage and hit point tracking.
|
|
|
|
## Data Storage
|
|
|
|
- Each player's garage is stored as a single JSON object (map) at Redis key: `garage:{playerUID}`
|
|
- The map is keyed by the vehicle's unique plate (UUID)
|
|
- Each vehicle tracks: plate (UUID), classname, overall damage, fuel, and detailed hit points
|
|
- **Plates are auto-generated** when vehicles are added via `garage:add`
|
|
- **Empty garages are auto-created** when a player first fetches their garage
|
|
|
|
## Extension Commands
|
|
|
|
All commands are accessed via the `garage` group:
|
|
|
|
### Create Garage
|
|
|
|
Creates a new empty garage for a player. Should be called when initializing a new player.
|
|
|
|
```sqf
|
|
private _result = "forge_server" callExtension ["garage:create", [getPlayerUID player]];
|
|
private _emptyGarage = fromJSON (_result select 0);
|
|
// Returns: {} (empty map)
|
|
```
|
|
|
|
### Get Garage
|
|
|
|
Retrieves all vehicles in a player's garage.
|
|
|
|
```sqf
|
|
private _result = "forge_server" callExtension ["garage:get", [getPlayerUID player]];
|
|
private _garageMap = fromJSON (_result select 0);
|
|
// Returns: {"plate_uuid": {"plate":"plate_uuid","classname":"...","damage":0.0,"hit_points":{...}}, ...}
|
|
```
|
|
|
|
### Add Vehicle
|
|
|
|
Adds a new vehicle to the garage. The system automatically generates a unique plate (UUID) for the vehicle.
|
|
|
|
```sqf
|
|
private _data = createHashMapFromArray [
|
|
["classname", "B_Quadbike_01_F"],
|
|
["fuel", 1.0],
|
|
["damage", 0.0],
|
|
["hit_points", createHashMap] // Optional hit points map
|
|
];
|
|
|
|
private _result = "forge_server" callExtension ["garage:add", [
|
|
getPlayerUID player,
|
|
toJSON _data
|
|
]];
|
|
|
|
private _updatedGarage = fromJSON (_result select 0);
|
|
// Returns updated garage map
|
|
```
|
|
|
|
### Update Garage (Sync)
|
|
|
|
Updates the entire garage state. Useful for syncing changes made locally.
|
|
|
|
```sqf
|
|
// _garageMap is the local HashMap of vehicles
|
|
private _result = "forge_server" callExtension ["garage:update", [
|
|
getPlayerUID player,
|
|
toJSON _garageMap
|
|
]];
|
|
|
|
private _updatedGarage = fromJSON (_result select 0);
|
|
```
|
|
|
|
### Patch Vehicle
|
|
|
|
Updates specific fields of a vehicle without sending the entire garage. Useful for frequent updates like fuel or damage.
|
|
|
|
```sqf
|
|
private _plate = "some-plate-uuid";
|
|
private _data = createHashMapFromArray [
|
|
["plate", _plate],
|
|
["fuel", 0.8],
|
|
["damage", 0.1],
|
|
// "hit_points" is optional
|
|
];
|
|
|
|
private _result = "forge_server" callExtension ["garage:patch", [
|
|
getPlayerUID player,
|
|
toJSON _data
|
|
]];
|
|
|
|
private _updatedGarage = fromJSON (_result select 0);
|
|
```
|
|
|
|
### Remove Vehicle
|
|
|
|
Removes a specific vehicle from the garage by plate number.
|
|
Note: If using the GarageStore, removing a vehicle locally and saving/syncing will also remove it from the server.
|
|
|
|
```sqf
|
|
private _plate = "some-plate-uuid";
|
|
|
|
private _data = createHashMapFromArray [
|
|
["plate", _plate]
|
|
];
|
|
|
|
private _result = "forge_server" callExtension ["garage:remove", [
|
|
getPlayerUID player,
|
|
toJSON _data
|
|
]];
|
|
|
|
private _updatedGarage = fromJSON (_result select 0);
|
|
```
|
|
|
|
### Delete Garage
|
|
|
|
Permanently deletes all vehicles from a player's garage.
|
|
|
|
```sqf
|
|
private _result = "forge_server" callExtension ["garage:delete", [getPlayerUID player]];
|
|
// Returns: "OK" or "Error: ..."
|
|
```
|
|
|
|
### Check Existence
|
|
|
|
Checks if a player has any vehicles in their garage.
|
|
|
|
```sqf
|
|
private _result = "forge_server" callExtension ["garage:exists", [getPlayerUID player]];
|
|
private _exists = (_result select 0) == "true";
|
|
```
|
|
|
|
## Complete Integration Example
|
|
|
|
### Storing a Vehicle
|
|
|
|
```sqf
|
|
fnc_storeVehicle = {
|
|
params ["_vehicle"];
|
|
|
|
// Get vehicle data
|
|
private _hitPointsData = getAllHitPointsDamage _vehicle;
|
|
private _hitPoints = createHashMapFromArray [
|
|
["names", _hitPointsData select 0],
|
|
["selections", _hitPointsData select 1],
|
|
["values", _hitPointsData select 2]
|
|
];
|
|
|
|
// Create data hashMap
|
|
private _data = createHashMapFromArray [
|
|
["classname", typeOf _vehicle],
|
|
["damage", damage _vehicle],
|
|
["hit_points", _hitPoints]
|
|
];
|
|
|
|
// Add to garage (plate is auto-generated)
|
|
private _result = "forge_server" callExtension ["garage:add", [
|
|
getPlayerUID player,
|
|
toJSON _data
|
|
]];
|
|
|
|
// Check for error
|
|
if ((_result select 0) find "Error:" == 0) exitWith {
|
|
hint format ["Failed to store vehicle: %1", _result select 0];
|
|
false
|
|
};
|
|
|
|
// Parse result to get the new vehicle's plate
|
|
private _updatedGarage = fromJSON (_result select 0);
|
|
private _newVehicle = _updatedGarage select ((count _updatedGarage) - 1);
|
|
private _assignedPlate = _newVehicle get "plate";
|
|
|
|
// Delete the actual vehicle from game world
|
|
deleteVehicle _vehicle;
|
|
|
|
hint format ["Vehicle %1 stored with plate %2!", _data get "classname", _assignedPlate];
|
|
true
|
|
};
|
|
```
|
|
|
|
### Retrieving and Spawning a Vehicle
|
|
|
|
```sqf
|
|
fnc_spawnVehicleFromGarage = {
|
|
params ["_vehicleIndex"];
|
|
|
|
// Get garage
|
|
private _result = "forge_server" callExtension ["garage:get", [getPlayerUID player]];
|
|
private _garage = fromJSON (_result select 0);
|
|
|
|
// Validate index
|
|
if (_vehicleIndex >= count _garage) exitWith {
|
|
hint "Invalid vehicle index!";
|
|
objNull
|
|
};
|
|
|
|
// Get vehicle data
|
|
private _vehicleData = _garage select _vehicleIndex;
|
|
private _classname = _vehicleData get "classname";
|
|
private _storedDamage = _vehicleData get "damage";
|
|
private _hitPoints = _vehicleData get "hit_points";
|
|
|
|
// Spawn vehicle
|
|
private _spawnPos = player getPos [10, getDir player];
|
|
private _vehicle = _classname createVehicle _spawnPos;
|
|
|
|
// Apply damage
|
|
_vehicle setDamage _storedDamage;
|
|
|
|
// Apply hit point damage
|
|
private _names = _hitPoints get "names";
|
|
private _values = _hitPoints get "values";
|
|
|
|
{
|
|
_vehicle setHitPointDamage [_x, _values select _forEachIndex];
|
|
} forEach _names;
|
|
|
|
// Store plate on vehicle for future updates
|
|
private _plate = _vehicleData get "plate";
|
|
_vehicle setVariable ["garagePlate", _plate];
|
|
|
|
// Remove from garage
|
|
private _removeData = createHashMapFromArray [["plate", _plate]];
|
|
"forge_server" callExtension ["garage:remove", [getPlayerUID player, toJSON _removeData]];
|
|
|
|
hint format ["Vehicle %1 spawned with plate %2!", _classname, _plate];
|
|
_vehicle
|
|
};
|
|
```
|
|
|
|
## Hit Points Data Format
|
|
|
|
The hit points data matches Arma 3's `getAllHitPointsDamage` return format:
|
|
|
|
```json
|
|
{
|
|
"names": ["hitlfwheel", "hitlf2wheel", "hitfuel", "hitengine", "hitbody", ...],
|
|
"selections": ["wheel_1_1_steering", "wheel_1_2_steering", "fuel_hitpoint", "engine_hitpoint", "body_hitpoint", ...],
|
|
"values": [0, 0, 0.1, 0.2, 0, ...]
|
|
}
|
|
```
|
|
|
|
- **names**: Hit point identifiers
|
|
- **selections**: Physical selection names (can be empty strings `""`)
|
|
- **values**: Damage values from 0.0 (no damage) to 1.0 (destroyed)
|
|
|
|
## Error Handling
|
|
|
|
All commands return errors in the format `"Error: <message>"`. Always check for this:
|
|
|
|
```sqf
|
|
private _result = "forge_server" callExtension ["garage:get", [getPlayerUID player]];
|
|
private _data = _result select 0;
|
|
|
|
if (_data find "Error:" == 0) then {
|
|
// Handle error
|
|
systemChat format ["Garage error: %1", _data];
|
|
} else {
|
|
// Parse and use data
|
|
private _garage = fromJSON _data;
|
|
};
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
1. **Track Vehicle Plates**: When spawning vehicles from the garage, store the plate (UUID) as a variable so you can update them later:
|
|
```sqf
|
|
_vehicle setVariable ["garagePlate", _plate];
|
|
```
|
|
2. **Auto-Creation**: The system automatically creates an empty garage for new players on first access
|
|
3. **Validate Before Storage**: Check that vehicles are in good condition before allowing storage
|
|
4. **Limit Garage Size**: Implement a maximum number of vehicles per player
|
|
5. **Regular Updates**: Update vehicle damage periodically while in use
|
|
6. **Clean Deleted Vehicles**: Remove vehicles from garage when they're destroyed or sold
|