forge/arma/client/addons/garage/functions/fnc_initSessionService.sqf
Jacob Schmidt bdc1e36e63 Implement interactive garage UI with service-based client bridge
- replace placeholder garage interaction with real UI open flow
- add catalog/session/UI bridge services for hydrate, sync, store, and retrieve actions
- migrate garage web UI bundle to new app shell/runtime structure
- align org/store function naming with shared init and UI bridge patterns
2026-03-14 03:06:18 -05:00

299 lines
11 KiB
Plaintext

#include "..\script_component.hpp"
/*
* File: fnc_initSessionService.sqf
* Author: IDSolutions
* Date: 2026-03-14
* Public: No
*
* Description:
* Initializes the typed garage session service responsible for resolving the
* active garage context and building the browser hydrate payload.
*/
#pragma hemtt ignore_variables ["_self"]
GVAR(GarageSessionServiceBaseClass) = compileFinal createHashMapFromArray [
["#type", "GarageSessionServiceBaseClass"],
["#create", compileFinal {
_self set ["lastContext", createHashMap];
}],
["#delete", compileFinal {
_self set ["lastContext", createHashMap];
}],
["createDefaultContext", compileFinal {
createHashMapFromArray [
["name", "Vehicle Garage"],
["anchorPosition", getPosATL player],
["sourceObject", objNull],
["spawnHeading", getDir player],
["spawnPosition", player getPos [8, getDir player]],
["spawnRadius", 6],
["nearbyRadius", 30]
]
}],
["scanEntryValues", compileFinal {
params [
["_values", [], [[]]],
["_state", createHashMap, [createHashMap]]
];
{
if (_x isEqualType "" && { (_state getOrDefault ["name", "Vehicle Garage"]) isEqualTo "Vehicle Garage" }) then {
_state set ["name", _x];
};
if (_x isEqualType "") then {
private _resolvedObject = _state getOrDefault ["sourceObject", objNull];
if (isNull _resolvedObject) then {
private _namedObject = missionNamespace getVariable [_x, objNull];
if (!isNull _namedObject) then {
_state set ["sourceObject", _namedObject];
};
};
if ((_state getOrDefault ["anchorPosition", []]) isEqualTo [] && { _x in allMapMarkers }) then {
_state set ["anchorPosition", markerPos _x];
};
continue;
};
if (_x isEqualType objNull && { isNull (_state getOrDefault ["sourceObject", objNull]) }) then {
_state set ["sourceObject", _x];
if ((_state getOrDefault ["anchorPosition", []]) isEqualTo []) then {
_state set ["anchorPosition", getPosATL _x];
};
continue;
};
if (_x isEqualType 0 && { (_state getOrDefault ["spawnHeading", -1]) < 0 }) then {
_state set ["spawnHeading", _x];
continue;
};
if (_x isEqualType [] && { count _x > 0 }) then {
if (
{ _x isEqualType 0 } count _x >= 2 &&
{
((_state getOrDefault ["offset", []]) isEqualTo []) ||
((_state getOrDefault ["anchorPosition", []]) isEqualTo [])
}
) then {
if ((_state getOrDefault ["anchorPosition", []]) isEqualTo []) then {
_state set ["anchorPosition", _x];
} else {
_state set ["offset", _x];
};
continue;
};
_self call ["scanEntryValues", [_x, _state]];
};
} forEach _values;
_state
}],
["resolveEntry", compileFinal {
params [["_entry", [], [[]]]];
private _state = createHashMapFromArray [
["name", "Vehicle Garage"],
["anchorPosition", []],
["sourceObject", objNull],
["offset", []],
["spawnHeading", -1]
];
_self call ["scanEntryValues", [_entry, _state]];
private _anchorPosition = _state getOrDefault ["anchorPosition", []];
private _offset = _state getOrDefault ["offset", []];
private _spawnPosition = if (_anchorPosition isEqualTo []) then {
[]
} else {
if (_offset isEqualTo []) then {
_anchorPosition
} else {
_anchorPosition vectorAdd _offset
}
};
createHashMapFromArray [
["name", _state getOrDefault ["name", "Vehicle Garage"]],
["anchorPosition", _anchorPosition],
["sourceObject", _state getOrDefault ["sourceObject", objNull]],
["spawnHeading", _state getOrDefault ["spawnHeading", -1]],
["spawnPosition", _spawnPosition]
]
}],
["resolveContext", compileFinal {
private _context = _self call ["createDefaultContext", []];
private _locations = (missionConfigFile >> "FORGE_CfgGarages" >> "locations") call BFUNC(getCfgData);
if !(_locations isEqualType []) exitWith {
_self set ["lastContext", _context];
_context
};
private _nearestEntry = [];
private _nearestDistance = 1e10;
{
private _entry = _self call ["resolveEntry", [_x]];
private _anchorPosition = _entry getOrDefault ["anchorPosition", []];
if (_anchorPosition isEqualTo []) then {
continue;
};
private _distance = player distance2D _anchorPosition;
if (_distance < _nearestDistance) then {
_nearestDistance = _distance;
_nearestEntry = _entry;
};
} forEach _locations;
if (_nearestEntry isEqualTo []) exitWith {
_self set ["lastContext", _context];
_context
};
private _anchorPosition = _nearestEntry getOrDefault ["anchorPosition", []];
private _garageObject = _nearestEntry getOrDefault ["sourceObject", objNull];
private _garageName = _nearestEntry getOrDefault ["name", "Vehicle Garage"];
private _spawnHeading = _nearestEntry getOrDefault ["spawnHeading", getDir player];
if (_spawnHeading < 0) then {
_spawnHeading = if (!isNull _garageObject) then { getDir _garageObject } else { getDir player };
};
private _spawnPosition = _nearestEntry getOrDefault ["spawnPosition", []];
if (_spawnPosition isEqualTo []) then {
_spawnPosition = if (_anchorPosition isEqualTo []) then {
player getPos [8, _spawnHeading]
} else {
_anchorPosition
};
};
_context set ["name", _garageName];
_context set ["anchorPosition", _anchorPosition];
_context set ["sourceObject", _garageObject];
_context set ["spawnHeading", _spawnHeading];
_context set ["spawnPosition", _spawnPosition];
_self set ["lastContext", _context];
_context
}],
["getContext", compileFinal {
_self call ["resolveContext", []]
}],
["buildPayload", compileFinal {
private _context = _self call ["getContext", []];
private _garageMap = if (isNil QGVAR(GarageClass)) then {
createHashMap
} else {
GVAR(GarageClass) call ["getGarageState", []]
};
private _anchorPosition = _context getOrDefault ["anchorPosition", []];
private _spawnPosition = _context getOrDefault ["spawnPosition", getPosATL player];
private _spawnRadius = _context getOrDefault ["spawnRadius", 6];
private _nearbyRadius = _context getOrDefault ["nearbyRadius", 30];
private _nearbyOrigin = [_anchorPosition, _spawnPosition] select (_anchorPosition isEqualTo []);
private _storedVehicles = [];
private _nearbyVehicles = [];
private _nearbyEntities = [];
private _candidateVehicles = [];
{
_candidateVehicles pushBackUnique _x;
} forEach (_nearbyOrigin nearEntities [["Car", "Tank", "Air", "Ship"], _nearbyRadius]);
{
_candidateVehicles pushBackUnique _x;
} forEach ((getPosATL player) nearEntities [["Car", "Tank", "Air", "Ship"], _nearbyRadius]);
{
_candidateVehicles pushBackUnique _x;
} forEach (nearestObjects [_nearbyOrigin, ["AllVehicles"], _nearbyRadius]);
{
_candidateVehicles pushBackUnique _x;
} forEach (nearestObjects [getPosATL player, ["AllVehicles"], _nearbyRadius]);
{
if (isNull _x) then {
continue;
};
if (_x isKindOf "CAManBase") then {
continue;
};
if !(
_x isKindOf "Car" ||
_x isKindOf "Tank" ||
_x isKindOf "Air" ||
_x isKindOf "Ship"
) then {
continue;
};
_nearbyEntities pushBackUnique _x;
} forEach _candidateVehicles;
{
_storedVehicles pushBack (
GVAR(GarageCatalogService) call ["buildStoredVehicle", [_x, _y]]
);
} forEach _garageMap;
private _storedVehiclePairs = _storedVehicles apply {
[toLowerANSI (_x getOrDefault ["displayName", ""]), _x]
};
_storedVehiclePairs sort true;
_storedVehicles = _storedVehiclePairs apply { _x param [1, createHashMap] };
{
if (isNull _x) then {
continue;
};
private _builtVehicle = GVAR(GarageCatalogService) call ["buildNearbyVehicle", [_x, _nearbyOrigin]];
if (_builtVehicle isEqualTo createHashMap) then {
continue;
};
_nearbyVehicles pushBack _builtVehicle;
} forEach _nearbyEntities;
private _nearbyVehiclePairs = _nearbyVehicles apply {
[_x getOrDefault ["distance", 0], _x]
};
_nearbyVehiclePairs sort true;
_nearbyVehicles = _nearbyVehiclePairs apply { _x param [1, createHashMap] };
private _spawnBlocked = (
(_spawnPosition nearEntities [["Car", "Tank", "Air", "Ship"], _spawnRadius]) +
(nearestObjects [_spawnPosition, ["Car", "Tank", "Air", "Ship"], _spawnRadius])
) isNotEqualTo [];
createHashMapFromArray [
["session", createHashMapFromArray [
["garageName", _context getOrDefault ["name", "Vehicle Garage"]],
["capacityUsed", count _storedVehicles],
["capacityMax", 5],
["nearbyCount", count _nearbyVehicles],
["spawnBlocked", _spawnBlocked],
["spawnStatus", ["Ready", "Blocked"] select _spawnBlocked]
]],
["garage", createHashMapFromArray [
["vehicles", _storedVehicles]
]],
["nearby", createHashMapFromArray [
["vehicles", _nearbyVehicles]
]]
]
}]
];
GVAR(GarageSessionService) = createHashMapObject [GVAR(GarageSessionServiceBaseClass)];
GVAR(GarageSessionService)