# 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 persisted by the server extension through SurrealDB.
- 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
