feat: Initialize core client and server systems for actor, bank, garage, locker, and notifications, including UI components and data models.

This commit is contained in:
Jacob Schmidt 2026-01-28 20:07:24 -06:00
parent 61a9741dc0
commit 9c09976ef2
40 changed files with 694 additions and 569 deletions

View File

@ -1,19 +1,25 @@
#include "..\script_component.hpp"
/*
* File: fnc_handleUIEvents.sqf
* Author: IDSolutions
* Date: 2026-01-28
* Last Update: 2026-01-28
* Public: No
*
* Description:
* Handles the UI events.
*
* Arguments:
* None
* 0: [CONTROL] - The control that triggered the event
* 1: [BOOL] - Whether the event is from a confirm dialog
* 2: [STRING] - The message containing the event data
*
* Return Value:
* None
* UI events handled [BOOL]
*
* Example:
* [] call forge_client_actor_fnc_handleUIEvents;
*
* Public: No
*/
params ["_control", "_isConfirmDialog", "_message"];

View File

@ -1,19 +1,24 @@
#include "..\script_component.hpp"
/*
* File: fnc_initActorClass.sqf
* Author: IDSolutions
* Initializes the actor class.
* Date: 2026-01-28
* Last Update: 2026-01-28
* Public: Yes
*
* Description:
* Initializes the actor class for managing player data.
* Provides methods for saving, loading, and applying actor data.
*
* Arguments:
* None
*
* Return Value:
* None
* Actor class object [HASHMAP OBJECT]
*
* Examples:
* Example:
* [] call forge_client_actor_fnc_initActorClass
*
* Public: Yes
*/
#pragma hemtt ignore_variables ["_self"]
@ -131,7 +136,7 @@ GVAR(ActorClass) = createHashMapObject [[
if (_isGarage) then { _nearbyActions pushBack ["garage", _garageType]; };
if (_isGarage && GVAR(enableVG)) then { _nearbyActions pushBack ["vg", true]; };
if (_deviceType isNotEqualTo "") then { _nearbyActions pushBack ["device", _deviceType]; };
if (_isPlayer) then { _nearbyActions pushBack ["player", name _x]; };
if (_isPlayer && { _x isNotEqualTo player }) then { _nearbyActions pushBack ["player", name _x]; };
} forEach (player nearObjects 5);
_control ctrlWebBrowserAction ["ExecJS", format ["updateAvailableActions(%1)", (toJSON _nearbyActions)]];

View File

@ -1,19 +1,23 @@
#include "..\script_component.hpp"
/*
* File: fnc_openUI.sqf
* Author: IDSolutions
* Date: 2026-01-28
* Last Update: 2026-01-28
* Public: No
*
* Description:
* Opens the player interaction interface.
*
* Arguments:
* None
*
* Return Value:
* None
* UI opened [BOOL]
*
* Example:
* [] call forge_client_actor_fnc_openUI;
*
* Public: No
*/
private _display = (findDisplay 46) createDisplay "RscActorMenu";

View File

@ -1,19 +1,25 @@
#include "..\script_component.hpp"
/*
* File: fnc_handleUIEvents.sqf
* Author: IDSolutions
* Date: 2025-12-16
* Last Update: 2026-01-28
* Public: No
*
* Description:
* Handles the UI events.
*
* Arguments:
* None
* 0: [CONTROL] - The control that triggered the event
* 1: [BOOL] - Whether the event is from a confirm dialog
* 2: [STRING] - The message containing the event data
*
* Return Value:
* None
* UI events handled [BOOL]
*
* Example:
* [] call forge_client_bank_fnc_handleUIEvents;
*
* Public: No
*/
params ["_control", "_isConfirmDialog", "_message"];

View File

@ -1,19 +1,23 @@
#include "..\script_component.hpp"
/*
* File: fnc_initBankClass.sqf
* Author: IDSolutions
* Date: 2025-12-16
* Last Update: 2026-01-28
* Public: No
*
* Description:
* Initializes the bank class.
*
* Arguments:
* None
*
* Return Value:
* None
* Bank class object [HASHMAP OBJECT]
*
* Examples:
* Example:
* [] call forge_client_bank_fnc_initBankClass
*
* Public: Yes
*/
#pragma hemtt ignore_variables ["_self"]
@ -24,23 +28,11 @@ GVAR(BankClass) = createHashMapObject [[
_self set ["account", createHashMap];
_self set ["isLoaded", false];
_self set ["lastSave", time];
private _account = createHashMap;
_account set ["uid", (getPlayerUID player)];
_account set ["name", (name player)];
_account set ["bank", 0];
_account set ["cash", 0];
_account set ["earnings", 0];
_account set ["pin", 1234];
_account set ["transactions", []];
_self set ["account", _account];
}],
["init", {
private _uid = _self get "uid";
private _account = _self get "account";
[SRPC(bank,requestInitBank), [_uid, _account]] call CFUNC(serverEvent);
[SRPC(bank,requestInitBank), [_uid]] call CFUNC(serverEvent);
systemChat format ["Bank loaded for %1", (name player)];
diag_log "[FORGE:Client:Bank] Bank Class Initialized!";
@ -80,5 +72,4 @@ GVAR(BankClass) = createHashMapObject [[
}]
]];
SETVAR(player,FORGE_BankClass,GVAR(BankClass));
GVAR(BankClass)

View File

@ -1,19 +1,23 @@
#include "..\script_component.hpp"
/*
* File: fnc_openUI.sqf
* Author: IDSolutions
* Date: 2026-01-28
* Last Update: 2026-01-28
* Public: No
*
* Description:
* Opens the player bank interaction interface.
*
* Arguments:
* None
* 0: [BOOL] - Whether to open the ATM interface
*
* Return Value:
* None
* UI opened [BOOL]
*
* Example:
* [] call forge_client_bank_fnc_openUI;
*
* Public: No
* [true] call forge_client_bank_fnc_openUI;
*/
params [["_isATM", false, [false]]];

View File

@ -94,12 +94,6 @@
<button class="menu-btn" onclick="showView('withdrawView')">
<span class="menu-text">Withdraw</span>
</button>
<!-- <button class="menu-btn" onclick="showView('depositView')"> -->
<!-- <span class="menu-text">Deposit</span> -->
<!-- </button> -->
<!-- <button class="menu-btn" onclick="showView('transferView')"> -->
<!-- <span class="menu-text">Transfer</span> -->
<!-- </button> -->
<button class="menu-btn" onclick="showView('balanceView')">
<span class="menu-text">Balance</span>
</button>
@ -135,59 +129,6 @@
</div>
</div>
<!-- Deposit Screen -->
<!-- <div class="atm-view" id="depositView" style="display: none;">
<h3>Deposit Cash</h3>
<div class="deposit-display">
<div class="deposit-info">
<p>Available Cash: <span id="availableCash">$2,500</span></p>
</div>
<div class="custom-amount">
<label>Amount to Deposit</label>
<input type="number" class="amount-input" id="depositInput" placeholder="0.00" min="0"
step="1">
</div>
</div>
<div class="atm-btn-group">
<button class="atm-btn atm-btn-primary" onclick="depositAmount()">
Deposit
</button>
<button class="atm-btn atm-btn-full" onclick="depositAll()">
Deposit All Cash
</button>
<button class="atm-btn atm-btn-secondary" onclick="showView('menuView')">
Back
</button>
</div>
</div> -->
<!-- Transfer Screen -->
<!-- <div class="atm-view" id="transferView" style="display: none;">
<h3>Transfer Funds</h3>
<div class="transfer-display">
<div class="transfer-form">
<div class="form-field">
<label>To Player ID</label>
<input type="text" class="text-input" id="transferPlayerId"
placeholder="Enter player ID">
</div>
<div class="form-field">
<label>Amount</label>
<input type="number" class="amount-input" id="transferAmount" placeholder="0.00" min="0"
step="1">
</div>
</div>
</div>
<div class="atm-btn-group">
<button class="atm-btn atm-btn-primary" onclick="transferFunds()">
Transfer
</button>
<button class="atm-btn atm-btn-secondary" onclick="showView('menuView')">
Back
</button>
</div>
</div> -->
<!-- Balance Screen -->
<div class="atm-view" id="balanceView" style="display: none;">
<h3>Account Balance</h3>

View File

@ -1,17 +1,23 @@
#include "..\script_component.hpp"
/*
* File: fnc_handleUIEvents.sqf
* Author: IDSolutions
* Date: 2025-12-16
* Last Update: 2026-01-28
* Public: No
*
* Description:
* Handles the UI events.
*
* Arguments:
* None
* 0: [CONTROL] - The control that triggered the event
* 1: [BOOL] - Whether the event is from a confirm dialog
* 2: [STRING] - The message containing the event data
*
* Return Value:
* None
* UI events handled [BOOL]
*
* Example:
* [] call forge_client_garage_fnc_handleUIEvents;
*
* Public: No
*/

View File

@ -1,19 +1,24 @@
#include "..\script_component.hpp"
/*
* File: fnc_initGarageClass.sqf
* Author: IDSolutions
* Initializes the garage class.
* Date: 2025-12-17
* Last Update: 2026-01-28
* Public: No
*
* Description:
* Initializes the Garage class for managing player vehicles.
* Provides methods for syncing, saving, and applying vehicles to the player's garage.
*
* Arguments:
* None
*
* Return Value:
* None
* Garage class object [HASHMAP OBJECT]
*
* Example:
* [] call forge_client_garage_fnc_initGarageClass;
*
* Public: No
* [] call forge_client_garage_fnc_initGarageClass
*/
#pragma hemtt ignore_variables ["_self"]
@ -35,15 +40,13 @@ GVAR(GarageClass) = createHashMapObject [[
diag_log "[FORGE:Client:Garage] Garage Class Initialized!";
}],
["save", {
params [["_sync", false, [false]]];
private _uid = _self get "uid";
[SRPC(garage,requestSaveGarage), [_uid, _sync]] call CFUNC(serverEvent);
[SRPC(garage,requestSaveGarage), [_uid]] call CFUNC(serverEvent);
_self set ["lastSave", time];
}],
["sync", {
params [["_data", createHashMap, [createHashMap]], ["_sync", false, [false]]];
params [["_data", createHashMap, [createHashMap]]];
private _garage = _self get "garage";
private _isLoaded = _self get "isLoaded";
@ -69,5 +72,4 @@ GVAR(GarageClass) = createHashMapObject [[
}]
]];
SETVAR(player,FORGE_GarageClass,GVAR(GarageClass));
GVAR(GarageClass)

View File

@ -1,24 +1,24 @@
#include "..\script_component.hpp"
/*
* File: fnc_initVGarageClass.sqf
* File: fnc_initVGClass.sqf
* Author: IDSolutions
* Date: 2025-12-16
* Last Update: 2025-12-19
* Last Update: 2026-01-28
* Public: No
*
* Description:
* Initializes the Virtual Garage class for managing player garage unlocks.
* Provides methods for syncing, saving, and applying virtual items to BIS Garage.
* Initializes the Virtual Garage class for managing player garage unlocks.
* Provides methods for syncing, saving, and applying virtual items to BIS Garage.
*
* Parameter(s):
* None
* Arguments:
* None
*
* Returns:
* vGarage class object [HASHMAP OBJECT]
* Return Value:
* vGarage class object [HASHMAP OBJECT]
*
* Example(s):
* [] call forge_client_locker_fnc_initVGClass;
* Example:
* [] call forge_client_garage_fnc_initVGClass;
*/
#pragma hemtt ignore_variables ["_self"]
@ -29,16 +29,6 @@ GVAR(VGarageClass) = createHashMapObject [[
_self set ["vGarage", createHashMap];
_self set ["isLoaded", false];
_self set ["lastSave", time];
private _vGarage = createHashMap;
_vGarage set ["cars", ["B_Quadbike_01_F"]];
_vGarage set ["armor", []];
_vGarage set ["helis", []];
_vGarage set ["planes", []];
_vGarage set ["naval", []];
_vGarage set ["other", []];
_self set ["vGarage", _vGarage];
}],
["init", {
private _uid = _self get "uid";
@ -50,10 +40,8 @@ GVAR(VGarageClass) = createHashMapObject [[
diag_log "[FORGE:Client:VGarage] VGarage Class Initialized!";
}],
["save", {
params [["_sync", false, [false]]];
private _uid = _self get "uid";
[SRPC(garage,requestSaveVG), [_uid, _sync]] call CFUNC(serverEvent);
[SRPC(garage,requestSaveVG), [_uid]] call CFUNC(serverEvent);
_self set ["lastSave", time];
}],
@ -112,5 +100,4 @@ GVAR(VGarageClass) = createHashMapObject [[
}]
]];
SETVAR(player,FORGE_VGarageClass,GVAR(VGarageClass));
GVAR(VGarageClass)

View File

@ -1,17 +1,21 @@
#include "..\script_component.hpp"
/*
* File: fnc_openUI.sqf
* Author: IDSolutions
* Date: 2025-12-16
* Last Update: 2026-01-28
* Public: No
*
* Description:
* Opens the garage UI.
*
* Arguments:
* None
*
* Return Value:
* None
* UI opened [BOOL]
*
* Example:
* [] call forge_client_garage_fnc_openUI;
*
* Public: No
*/

View File

@ -1,23 +1,23 @@
#include "..\script_component.hpp"
/*
* File: fnc_initVG.sqf
* File: fnc_openVG.sqf
* Author: IDSolutions
* Date: 2025-12-16
* Last Update: 2025-12-17
* Last Update: 2026-01-28
* Public: No
*
* Description:
* No description added yet.
* Opens the Virtual Garage.
*
* Parameter(s):
* N/A
* Arguments:
* None
*
* Returns:
* Something [BOOL]
* Return Value:
* None
*
* Example(s):
* [parameter] call forge_x_component_fnc_myFunction
* Example:
* [] call forge_client_garage_fnc_openVG
*/
private _locations = (missionConfigFile >> "FORGE_CfgGarages" >> "locations") call BFUNC(getCfgData);
@ -44,6 +44,9 @@ BIS_fnc_garage_center = createVehicle ["Land_HelipadEmpty_F", FORGE_VehSpawnPos,
lbClear (_display displayCtrl (960 + _forEachIndex));
} forEach BIS_fnc_garage_data;
_display displayAddEventHandler ["KeyDown", "_this select 3"];
{ (_display displayCtrl _x) ctrlShow false } forEach [44151, 44150, 44146, 44147, 44148, 44149, 44346, 44347, 978];
["ListAdd", [_display]] call BFUNC(garage);
}] call BFUNC(addScriptedEventHandler);

View File

@ -1 +1,8 @@
#include "script_component.hpp"
[missionNamespace, "arsenalOpened", {
disableSerialization;
params ["_display"];
_display displayAddEventHandler ["KeyDown", "_this select 3"];
{ (_display displayCtrl _x) ctrlShow false } forEach [44151, 44150, 44146, 44147, 44148, 44149, 44346];
}] call BIS_fnc_addScriptedEventHandler;

View File

@ -1,3 +1,2 @@
#include "script_component.hpp"
#include "XEH_PREP.hpp"

View File

@ -1,17 +1,23 @@
#include "..\script_component.hpp"
/*
* File: fnc_handleUIEvents.sqf
* Author: IDSolutions
* Date: 2026-01-28
* Last Update: 2026-01-28
* Public: No
*
* Description:
* Handles the UI events.
*
* Arguments:
* None
* 0: [CONTROL] - The control that triggered the event
* 1: [BOOL] - Whether the event is from a confirm dialog
* 2: [STRING] - The message containing the event data
*
* Return Value:
* None
* UI events handled [BOOL]
*
* Example:
* [] call forge_client_locker_fnc_handleUIEvents;
*
* Public: No
*/

View File

@ -1,19 +1,24 @@
#include "..\script_component.hpp"
/*
* File: fnc_initLockerClass.sqf
* Author: IDSolutions
* Initializes the locker class.
* Date: 2025-12-17
* Last Update: 2026-01-28
* Public: No
*
* Description:
* Initializes the Locker class for managing player locker items.
* Provides methods for syncing, saving, and applying locker items to the player's locker.
*
* Arguments:
* None
*
* Return Value:
* None
* Locker class object [HASHMAP OBJECT]
*
* Example:
* [] call forge_client_locker_fnc_initLockerClass;
*
* Public: No
* [] call forge_client_locker_fnc_initLockerClass
*/
#pragma hemtt ignore_variables ["_self"]
@ -35,26 +40,19 @@ GVAR(LockerClass) = createHashMapObject [[
diag_log "[FORGE:Client:Locker] Locker Class Initialized!";
}],
["save", {
params [["_sync", false, [false]]];
private _uid = _self get "uid";
[SRPC(locker,requestSaveLocker), [_uid, _sync]] call CFUNC(serverEvent);
[SRPC(locker,requestSaveLocker), [_uid]] call CFUNC(serverEvent);
_self set ["lastSave", time];
}],
["sync", {
params [["_data", createHashMap, [createHashMap]], ["_jip", false, [false]]];
params [["_data", createHashMap, [createHashMap]]];
private _locker = _self get "locker";
private _isLoaded = _self get "isLoaded";
if (_data isEqualTo createHashMap) exitWith {
diag_log "[FORGE:Client:Locker] Empty data received for sync, skipping.";
};
{
_locker set [_x, _y];
} forEach _data;
if (_data isEqualTo createHashMap) exitWith { diag_log "[FORGE:Client:Locker] Empty data received for sync, skipping."; };
{ _locker set [_x, _y]; } forEach _data;
_self set ["locker", _locker];
@ -69,5 +67,4 @@ GVAR(LockerClass) = createHashMapObject [[
}]
]];
SETVAR(player,FORGE_LockerClass,GVAR(LockerClass));
GVAR(LockerClass)

View File

@ -4,21 +4,21 @@
* File: fnc_initVAClass.sqf
* Author: IDSolutions
* Date: 2025-12-16
* Last Update: 2025-12-17
* Last Update: 2026-01-28
* Public: No
*
* Description:
* Initializes the Virtual Arsenal class for managing player arsenal unlocks.
* Provides methods for syncing, saving, and applying virtual items to BIS Arsenal.
* Initializes the Virtual Arsenal class for managing player arsenal unlocks.
* Provides methods for syncing, saving, and applying virtual items to BIS Arsenal.
*
* Parameter(s):
* None
* Arguments:
* None
*
* Returns:
* vArsenal class object [HASHMAP OBJECT]
* Return Value:
* vArsenal class object [HASHMAP OBJECT]
*
* Example(s):
* [] call forge_client_locker_fnc_initVAClass;
* Example:
* [] call forge_client_locker_fnc_initVAClass;
*/
#pragma hemtt ignore_variables ["_self"]
@ -29,14 +29,6 @@ GVAR(VArsenalClass) = createHashMapObject [[
_self set ["vArsenal", createHashMap];
_self set ["isLoaded", false];
_self set ["lastSave", time];
private _vArsenal = createHashMap;
_vArsenal set ["items", []];
_vArsenal set ["weapons", []];
_vArsenal set ["magazines", []];
_vArsenal set ["backpacks", []];
_self set ["vArsenal", _vArsenal];
}],
["init", {
private _uid = _self get "uid";
@ -49,10 +41,8 @@ GVAR(VArsenalClass) = createHashMapObject [[
diag_log "[FORGE:Client:VArsenal] VArsenal Class Initialized!";
}],
["save", {
params [["_sync", false, [false]]];
private _uid = _self get "uid";
[SRPC(locker,requestSaveVA), [_uid, _sync]] call CFUNC(serverEvent);
[SRPC(locker,requestSaveVA), [_uid]] call CFUNC(serverEvent);
_self set ["lastSave", time];
}],
@ -107,5 +97,4 @@ GVAR(VArsenalClass) = createHashMapObject [[
}]
]];
SETVAR(player,FORGE_VArsenalClass,GVAR(VArsenalClass));
GVAR(VArsenalClass)

View File

@ -1,17 +1,21 @@
#include "..\script_component.hpp"
/*
* File: fnc_openUI.sqf
* Author: IDSolutions
* Opens the locker UI.
* Date: 2026-01-28
* Last Update: 2026-01-28
* Public: No
*
* Description:
* Opens the player locker interaction interface.
*
* Arguments:
* None
*
* Return Value:
* None
* UI opened [BOOL]
*
* Example:
* [] call forge_client_locker_fnc_openUI;
*
* Public: No
*/

View File

@ -1,19 +1,25 @@
#include "..\script_component.hpp"
/*
* File: fnc_handleUIEvents.sqf
* Author: IDSolutions
* Handles UI events.
* Date: 2026-01-28
* Last Update: 2026-01-28
* Public: No
*
* Description:
* Handles the UI events.
*
* Arguments:
* None
* 0: [CONTROL] - The control that triggered the event
* 1: [BOOL] - Whether the event is from a confirm dialog
* 2: [STRING] - The message containing the event data
*
* Return Value:
* None
* UI events handled [BOOL]
*
* Example:
* [] call forge_client_notifications_fnc_handleUIEvents;
*
* Public: No
*/
params ["_control", "_isConfirmDialog", "_message"];

View File

@ -1,19 +1,24 @@
#include "..\script_component.hpp"
/*
* File: fnc_initNotificationClass.sqf
* Author: IDSolutions
* Initialize notification class
* Date: 2026-01-28
* Last Update: 2026-01-28
* Public: No
*
* Description:
* Initializes the notification class for managing player notifications.
* Provides methods for creating and displaying notifications.
*
* Arguments:
* N/A
* None
*
* Return Value:
* N/A
* Notification class object [HASHMAP OBJECT]
*
* Examples:
* Example:
* [] call forge_client_notifications_fnc_initNotificationClass
*
* Public: Yes
*/
#pragma hemtt ignore_variables ["_self"]
@ -50,5 +55,4 @@ GVAR(NotificationClass) = createHashMapObject [[
}]
]];
SETVAR(player,FORGE_NotificationClass,GVAR(NotificationClass));
GVAR(NotificationClass)

View File

@ -1,19 +1,23 @@
#include "..\script_component.hpp"
/*
* File: fnc_openUI.sqf
* Author: IDSolutions
* Open notification interface.
* Date: 2026-01-28
* Last Update: 2026-01-28
* Public: No
*
* Description:
* Opens the notification interface.
*
* Arguments:
* None
*
* Return Value:
* None
* UI opened [BOOL]
*
* Example:
* [] call forge_client_notifications_fnc_openUI;
*
* Public: No
*/
private _display = uiNamespace getVariable ["RscNotifications", nil];

View File

@ -78,5 +78,4 @@ GVAR(OrgClass) = createHashMapObject [[
}]
]];
SETVAR(player,FORGE_OrgClass,GVAR(OrgClass));
GVAR(OrgClass)

View File

@ -18,9 +18,6 @@ PREP_RECOMPILE_END;
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Actor] Empty/Invalid UID!" };
private _session = GVAR(PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Actor] Empty/Invalid Session!" };
private _finalData = GVAR(ActorStore) call ["get", [GVAR(ActorRegistry), "actor:get", _uid, _sync]];
private _player = [_uid] call EFUNC(common,getPlayer);
@ -32,9 +29,6 @@ PREP_RECOMPILE_END;
if (_uid isEqualTo "" || _key isEqualTo "") exitWith { diag_log "[FORGE:Server:Actor] Empty/Invalid UID or Key!" };
private _session = GVAR(PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Actor] Empty/Invalid Session!" };
private _hashMap = GVAR(ActorStore) call ["set", [GVAR(ActorRegistry), "actor:update", _uid, _key, _value, _sync]];
private _player = [_uid] call EFUNC(common,getPlayer);
@ -47,9 +41,6 @@ PREP_RECOMPILE_END;
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Actor] Empty/Invalid UID!" };
if ((_fieldValuePairs isEqualTo createHashMap) || !(_fieldValuePairs isEqualType createHashMap)) exitWith { diag_log "[FORGE:Server:Actor] Empty/Invalid field pairs!" };
private _session = GVAR(PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Actor] Empty/Invalid Session!" };
private _hashMap = GVAR(ActorStore) call ["mset", [GVAR(ActorRegistry), "actor:update", _uid, _fieldValuePairs, _sync]];
private _player = [_uid] call EFUNC(common,getPlayer);
@ -61,9 +52,6 @@ PREP_RECOMPILE_END;
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Actor] Empty/Invalid UID!" };
private _session = GVAR(PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Actor] Empty/Invalid Session!" };
private _finalData = GVAR(ActorStore) call ["save", [GVAR(ActorRegistry), "actor:update", _uid, _sync]];
private _player = [_uid] call EFUNC(common,getPlayer);
@ -74,6 +62,5 @@ PREP_RECOMPILE_END;
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Actor] Empty/Invalid UID!" };
GVAR(ActorStore) call ["remove", [GVAR(ActorRegistry), _uid]];
}] call CFUNC(addEventHandler);

View File

@ -1,19 +1,24 @@
#include "..\script_component.hpp"
/*
* File: fnc_initActorStore.sqf
* Author: IDSolutions
* Initializes the actor store.
* Date: 2025-12-17
* Last Update: 2026-01-28
* Public: Yes
*
* Description:
* Initializes the actor store for managing player actor data.
* Provides methods for creating, fetching, migrating, and validating actor data.
*
* Arguments:
* None
*
* Return Value:
* None
* Actor store object [HASHMAP OBJECT]
*
* Examples:
* Example:
* [] call forge_server_actor_fnc_initActorStore
*
* Public: Yes
*/
#pragma hemtt ignore_variables ["_self"]
@ -24,7 +29,7 @@ GVAR(ActorModel) = compileFinal createHashMapObject [[
_actor set ["uid", ""];
_actor set ["name", ""];
_actor set ["loadout", [[],[],[],["U_BG_Guerrilla_6_1",[]],[],[],"H_Cap_blk_ION","",[],["ItemMap","ItemGPS","ItemRadio","ItemCompass","ItemWatch",""]]];
_actor set ["loadout", [[],[],[],["U_BG_Guerrilla_6_1",[["FirstAidKit", 2]]],[],[],"H_Cap_blk_ION","",[],["ItemMap","ItemGPS","ItemRadio","ItemCompass","ItemWatch",""]]];
_actor set ["position", [0,0,0]];
_actor set ["direction", 0];
_actor set ["stance", "STAND"];
@ -124,6 +129,7 @@ GVAR(ActorRepository) = compileFinal createHashMapFromArray [
if (_result == "true") then {
_finalActor = _self call ["fetch", ["actor:get", _uid]];
["INFO", format ["Found actor for %1", _uid]] call EFUNC(common,log);
} else {
_finalActor = GVAR(ActorModel) call ["fromPlayer", [_player]];
_finalActor set ["uid", _uid];
@ -134,6 +140,8 @@ GVAR(ActorRepository) = compileFinal createHashMapFromArray [
["ERROR", format ["Failed to create actor %1!", _uid]] call EFUNC(common,log);
createHashMap
};
["INFO", format ["Created new actor for %1", _uid]] call EFUNC(common,log);
};
_finalActor = GVAR(ActorModel) call ["migrate", [_finalActor]];

View File

@ -7,22 +7,16 @@ PREP_RECOMPILE_END;
// private _category = [QUOTE(MOD_NAME), LLSTRING(displayName)];
[QGVAR(requestInitBank), {
params [["_uid", "", [""]], ["_bank", createHashMap, [createHashMap]]];
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid UID!" };
if (_bank isEqualTo createHashMap) exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid Bank data!" };
GVAR(BankStore) call ["init", [_uid, _bank]];
GVAR(BankStore) call ["init", [_uid]];
}] call CFUNC(addEventHandler);
[QGVAR(requestGetBank), {
params [["_uid", "", [""]], ["_sync", false, [false]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid UID!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid Session!" };
GVAR(BankStore) call ["get", [GVAR(BankRegistry), "bank:get", _uid, _sync]];
}] call CFUNC(addEventHandler);
@ -31,9 +25,6 @@ PREP_RECOMPILE_END;
if (_uid isEqualTo "" || _key isEqualTo "") exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid UID or Key!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid Session!" };
private _hashMap = GVAR(BankStore) call ["set", [GVAR(BankRegistry), "bank:update", _uid, _key, _value, _sync]];
private _player = [_uid] call EFUNC(common,getPlayer);
@ -46,9 +37,6 @@ PREP_RECOMPILE_END;
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid UID!" };
if ((_fieldValuePairs isEqualTo createHashMap) || !(_fieldValuePairs isEqualType createHashMap)) exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid field pairs!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid Session!" };
private _hashMap = GVAR(BankStore) call ["mset", [GVAR(BankRegistry), "bank:update", _uid, _fieldValuePairs, _sync]];
private _player = [_uid] call EFUNC(common,getPlayer);
@ -60,9 +48,6 @@ PREP_RECOMPILE_END;
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid UID!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid Session!" };
private _finalData = GVAR(BankStore) call ["save", [GVAR(BankRegistry), "bank:update", _uid, _sync]];
private _player = [_uid] call EFUNC(common,getPlayer);
@ -73,7 +58,6 @@ PREP_RECOMPILE_END;
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid UID!" };
GVAR(BankStore) call ["remove", [GVAR(BankRegistry), _uid]];
}] call CFUNC(addEventHandler);
@ -81,10 +65,6 @@ PREP_RECOMPILE_END;
params [["_uid", "", [""]], ["_amount", 0, [0]]];
if (_uid isEqualTo "" || _amount isEqualTo 0) exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid UID or Amount!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid Session!" };
GVAR(BankStore) call ["deposit", [_uid, _amount]];
}] call CFUNC(addEventHandler);
@ -92,10 +72,6 @@ PREP_RECOMPILE_END;
params [["_uid", "", [""]], ["_amount", 0, [0]]];
if (_uid isEqualTo "" || _amount isEqualTo 0) exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid UID or Amount!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid Session!" };
GVAR(BankStore) call ["payment", [_uid, _amount]];
}] call CFUNC(addEventHandler);
@ -113,9 +89,6 @@ PREP_RECOMPILE_END;
[CRPC(notifications,recieveNotification), ["error", "Bank", "Cannot transfer to yourself!"], _player] call CFUNC(targetEvent);
};
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid Session!" };
GVAR(BankStore) call ["transfer", [_uid, _target, _from, _amount]];
}] call CFUNC(addEventHandler);
@ -123,9 +96,5 @@ PREP_RECOMPILE_END;
params [["_uid", "", [""]], ["_amount", 0, [0]]];
if (_uid isEqualTo "" || _amount isEqualTo 0) exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid UID or Amount!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid Session!" };
GVAR(BankStore) call ["withdraw", [_uid, _amount]];
}] call CFUNC(addEventHandler);

View File

@ -1,71 +1,156 @@
#include "..\script_component.hpp"
/*
* File: fnc_initBankStore.sqf
* Author: IDSolutions
* Initializes the bank store.
* Date: 2025-12-17
* Last Update: 2026-01-28
* Public: Yes
*
* Description:
* Initializes the bank store for managing player bank accounts.
* Provides methods for syncing, saving, and applying bank accounts to the player.
*
* Arguments:
* None
*
* Return Value:
* None
* Bank store object [HASHMAP OBJECT]
*
* Examples:
* Example:
* [] call forge_server_bank_fnc_initBankStore
*
* Public: Yes
*/
#pragma hemtt ignore_variables ["_self"]
private _typeBank = compileFinal createHashMapFromArray [
GVAR(BankModel) = compileFinal createHashMapObject [[
["#type", "BankModel"],
["defaults", {
private _account = createHashMap;
_account set ["uid", ""];
_account set ["name", ""];
_account set ["bank", 0];
_account set ["cash", 0];
_account set ["earnings", 0];
_account set ["pin", 1234];
_account set ["transactions", []];
_account
}],
["fromPlayer", {
params [["_player", objNull, [objNull]]];
if (_player isEqualTo objNull) exitWith { _self call ["defaults", []] };
private _account = _self call ["defaults", []];
_account set ["uid", getPlayerUID _player];
_account set ["name", name _player];
_account set ["bank", 0];
_account set ["cash", 0];
_account set ["earnings", 0];
_account set ["pin", 1234];
_account set ["transactions", []];
_account
}],
["migrate", {
params [["_account", createHashMap, [createHashMap]]];
private _defaults = _self call ["defaults", []];
{
if !(_x in _account) then { _account set [_x, _y]; };
} forEach _defaults;
_account
}],
["validate", {
params [["_account", createHashMap, [createHashMap]]];
private _uid = _account getOrDefault ["uid", ""];
private _name = _account getOrDefault ["name", ""];
private _bank = _account getOrDefault ["bank", 0];
private _cash = _account getOrDefault ["cash", 0];
private _earnings = _account getOrDefault ["earnings", 0];
private _pin = _account getOrDefault ["pin", 1234];
[_uid, _name, _bank, _cash, _earnings, _pin] try {
if (_uid isEqualTo "" || !(_uid isEqualType "")) then { throw "Invalid UID!"; };
if (_name isEqualTo "" || !(_name isEqualType "")) then { throw "Invalid Name!"; };
if (_bank < 0 || !(_bank isEqualType 0)) then { throw "Invalid Bank!"; };
if (_cash < 0 || !(_cash isEqualType 0)) then { throw "Invalid Cash!"; };
if (_earnings < 0 || !(_earnings isEqualType 0)) then { throw "Invalid Earnings!"; };
if (_pin < 1000 || _pin > 9999 || !(_pin isEqualType 0)) then { throw "Invalid Pin!"; };
} catch {
["ERROR", format ["Failed to validate account %1!", _exception]] call EFUNC(common,log);
false
};
true
}]
]];
GVAR(BankRepository) = compileFinal createHashMapFromArray [
["#base", EGVAR(common,BaseStore)],
["#type", "IBaseBank"],
["init", {
params [["_uid", "", [""]], ["_defaultAccount", createHashMap, [createHashMap]]];
["#type", "BankRepository"],
["#create", {
GVAR(BankRegistry) = createHashMap;
GVAR(IndexRegistry) = createHashMap;
["INFO", "Bank Repository Initialized!"] call EFUNC(common,log);
}],
["get", {
params [["_uid", "", [""]]];
private _cached = GVAR(BankRegistry) getOrDefault [_uid, nil];
if !(isNil { _cached }) exitWith { _cached };
private _player = [_uid] call EFUNC(common,getPlayer);
["bank:exists", [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"];
if !(_isSuccess) exitWith {
["ERROR", format ["Failed to check if bank account %1 exists!", _uid]] call EFUNC(common,log);
createHashMap
};
private _finalAccount = createHashMap;
["bank:exists", [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"];
private _exists = _result == "true";
if !(_exists) then {
_finalAccount = _defaultAccount;
if (_result == "true") then {
_finalAccount = _self call ["fetch", ["bank:get", _uid]];
["INFO", format ["Found bank account for %1", _uid]] call EFUNC(common,log);
} else {
_finalAccount = GVAR(BankModel) call ["fromPlayer", [_player]];
_finalAccount set ["uid", _uid];
private _json = _self call ["toJSON", [_finalAccount]];
["bank:create", [_uid, _json]] call EFUNC(extension,extCall);
["bank:create", [_uid, _json]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"];
if !(_isSuccess) exitWith {
["ERROR", format ["Failed to create bank account %1!", _uid]] call EFUNC(common,log);
createHashMap
};
["INFO", format ["Created new bank account for %1", _uid], nil, nil] call EFUNC(common,log);
} else {
private _existingAccount = _self call ["fetch", ["bank:get", _uid]];
_finalAccount = _existingAccount;
{
if !(_x in _finalAccount) then { _finalAccount set [_x, _y]; };
} forEach _defaultAccount;
["INFO", format ["Found bank account for %1", _uid], nil, nil] call EFUNC(common,log);
["INFO", format ["Created new bank account for %1", _uid]] call EFUNC(common,log);
};
GVAR(BankRegistry) set [_uid, _finalAccount, true];
private _player = [_uid] call EFUNC(common,getPlayer);
private _regEntry = createHashMapFromArray [["uid", _uid], ["name", (name _player)]];
GVAR(IndexRegistry) set [_uid, _regEntry];
[CRPC(bank,responseInitBank), [_finalAccount], _player] call CFUNC(targetEvent);
// _finalAccount = GVAR(BankModel) call ["migrate", [_finalAccount]];
GVAR(BankRegistry) set [_uid, _finalAccount];
_finalAccount
}],
["deposit", {
params [["_uid", "", [""]], ["_amount", 0, [0]]];
["INFO", format ["Deposit %1, for %2", _amount, _uid], nil, nil] call EFUNC(common,log);
["INFO", format ["Deposit %1, for %2", _amount, _uid]] call EFUNC(common,log);
private _account = GVAR(BankRegistry) getOrDefault [_uid, nil];
if (isNil "_account") exitWith { ["ERROR", "Empty/Invalid Account!", nil, nil] call EFUNC(common,log); };
if (isNil "_account") exitWith { ["ERROR", "Empty/Invalid Account!"] call EFUNC(common,log); };
private _bank = _account getOrDefault ["bank", 0];
private _cash = _account getOrDefault ["cash", 0];
if (_cash < _amount) exitWith { ["WARNING", "Insufficient Funds!", nil, nil] call EFUNC(common,log); };
if (_cash < _amount) exitWith { ["WARNING", "Insufficient Funds!"] call EFUNC(common,log); };
private _finalAccount = createHashMapFromArray [["bank", (_bank + _amount)], ["cash", (_cash - _amount)]];
_self call ["mset", [_uid, _finalAccount]];
@ -78,10 +163,10 @@ private _typeBank = compileFinal createHashMapFromArray [
["payment", {
params [["_uid", "", [""]], ["_amount", 0, [0]]];
["INFO", format ["Payment %1, for %2", _amount, _uid], nil, nil] call EFUNC(common,log);
["INFO", format ["Payment %1, for %2", _amount, _uid]] call EFUNC(common,log);
private _account = GVAR(BankRegistry) getOrDefault [_uid, nil];
if (isNil "_account") exitWith { ["ERROR", "Empty/Invalid Account!", nil, nil] call EFUNC(common,log); };
if (isNil "_account") exitWith { ["ERROR", "Empty/Invalid Account!"] call EFUNC(common,log); };
private _bank = _account getOrDefault ["bank", 0];
private _finalAccount = createHashMapFromArray [["bank", (_bank + _amount)]];
@ -97,17 +182,17 @@ private _typeBank = compileFinal createHashMapFromArray [
params [["_uid", "", [""]], ["_target", "", [""]], ["_from", "", [""]], ["_amount", 0, [0]]];
if (_uid isEqualTo _target) exitWith {
["WARNING", format ["Self-transfer attempt blocked for %1", _uid], nil, nil] call EFUNC(common,log);
["WARNING", format ["Self-transfer attempt blocked for %1", _uid]] call EFUNC(common,log);
};
private _account = GVAR(BankRegistry) getOrDefault [_uid, nil];
if (isNil "_account") exitWith { ["ERROR", "Empty/Invalid Account!", nil, nil] call EFUNC(common,log); };
if (isNil "_account") exitWith { ["ERROR", "Empty/Invalid Account!"] call EFUNC(common,log); };
private _targetAccount = GVAR(BankRegistry) getOrDefault [_target, nil];
if (isNil "_targetAccount") exitWith { ["ERROR", "Empty/Invalid Target Account!", nil, nil] call EFUNC(common,log); };
if (isNil "_targetAccount") exitWith { ["ERROR", "Empty/Invalid Target Account!"] call EFUNC(common,log); };
private _bank = _account getOrDefault [_from, 0];
if (_bank < _amount) exitWith { ["WARNING", "Insufficient Funds!", nil, nil] call EFUNC(common,log); };
if (_bank < _amount) exitWith { ["WARNING", "Insufficient Funds!"] call EFUNC(common,log); };
private _targetBank = _targetAccount getOrDefault ["bank", 0];
private _finalAccount = createHashMapFromArray [[_from, (_bank - _amount)]];
@ -127,14 +212,14 @@ private _typeBank = compileFinal createHashMapFromArray [
["withdraw", {
params [["_uid", "", [""]], ["_amount", 0, [0]]];
["INFO", format ["Withdraw %1, for %2", _amount, _uid], nil, nil] call EFUNC(common,log);
["INFO", format ["Withdraw %1, for %2", _amount, _uid]] call EFUNC(common,log);
private _account = GVAR(BankRegistry) getOrDefault [_uid, nil];
if (isNil "_account") exitWith { ["ERROR", "Empty/Invalid Account!", nil, nil] call EFUNC(common,log); };
if (isNil "_account") exitWith { ["ERROR", "Empty/Invalid Account!"] call EFUNC(common,log); };
private _bank = _account getOrDefault ["bank", 0];
private _cash = _account getOrDefault ["cash", 0];
if (_bank < _amount) exitWith { ["WARNING", "Insufficient Funds!", nil, nil] call EFUNC(common,log); };
if (_bank < _amount) exitWith { ["WARNING", "Insufficient Funds!"] call EFUNC(common,log); };
private _finalAccount = createHashMapFromArray [["bank", (_bank - _amount)], ["cash", (_cash + _amount)]];
_self call ["mset", [_uid, _finalAccount]];
@ -147,15 +232,19 @@ private _typeBank = compileFinal createHashMapFromArray [
];
GVAR(BankStore) = createHashMapObject [[
["#base", _typeBank],
["#base", GVAR(BankRepository)],
["#type", "IBankStore"],
["#create", {
GVAR(BankRegistry) = createHashMap;
GVAR(IndexRegistry) = createHashMap;
["INFO", "Bank Store Initialized!"] call EFUNC(common,log);
}],
["init", {
params [["_uid", "", [""]]];
["INFO", "Bank Store Initialized!", nil, nil] call EFUNC(common,log);
private _account = _self call ["get", [_uid]];
private _player = [_uid] call EFUNC(common,getPlayer);
[CRPC(bank,responseInitBank), [_account], _player] call CFUNC(targetEvent);
}]
]];
SETMVAR(FORGE_BankStore,GVAR(BankStore));
GVAR(BankStore)

View File

@ -4,20 +4,20 @@
* File: fnc_baseStore.sqf
* Author: IDSolutions
* Date: 2026-01-08
* Last Update: 2026-01-10
* Last Update: 2026-01-28
* Public: No
*
* Description:
* No description added yet.
* No description added yet.
*
* Parameter(s):
* N/A
* Arguments:
* None
*
* Returns:
* Something [BOOL]
* Return Value:
* Base store [HASHMAP]
*
* Example(s):
* [parameter] call forge_x_component_fnc_myFunction
* Example:
* [] call forge_x_component_fnc_myFunction
*/
#pragma hemtt ignore_variables ["_self"]
@ -29,7 +29,7 @@ GVAR(BaseStore) = compileFinal createHashMapFromArray [
private _data = createHashMap;
[_function, [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"];
["INFO", format ["Data: %1", _result], nil, nil] call EFUNC(common,log);
["INFO", format ["Data: %1", _result]] call EFUNC(common,log);
if (count _result > 0) then { _data = _self call ["toHashMap", [_result]] };

View File

@ -4,7 +4,7 @@
* File: fnc_log.sqf
* Author: IDSolutions
* Date: 2026-01-03
* Last Update: 2026-01-03
* Last Update: 2026-01-18
* Public: No
*
* Description:
@ -35,19 +35,21 @@ if (_stackTrace) then {
_message = _traceText;
};
private _timestamp = format (["%1-%2-%3 %4:%5:%6:%7"] + systemTimeUTC);
// private _timestamp = format (["%1-%2-%3 %4:%5:%6:%7"] + systemTimeUTC);
if (isNil "_file") then { _file = ["", _fnc_scriptName] select (!isNil "_fnc_scriptName"); };
if (isNil "_callingFile" && !isNil "_fnc_scriptNameParent") then { _callingFile = _fnc_scriptNameParent; };
private _callingFileText = if !(isNil "_callingFile") then { format ["Called By: %1 |", _callingFile] } else { "" };
// private _callingFileText = if !(isNil "_callingFile") then { format ["Called By: %1", _callingFile] } else { "" };
diag_log text format [
"%1 | %2 | %3 | File: %4 | %5 | %6",
_timestamp,
_identifier,
_logLevel,
_file,
_callingFileText,
_message
];
// diag_log text format [
// "%1 | %2 | %3 | File: %4 | %5 | %6",
// _timestamp,
// _identifier,
// _logLevel,
// _file,
// _callingFileText,
// _message
// ];
diag_log text format ["[%1] %2: %3", _identifier, _logLevel, _message];

View File

@ -14,14 +14,10 @@ PREP_RECOMPILE_END;
}] call CFUNC(addEventHandler);
[QGVAR(requestGetGarage), {
params [["_uid", "", [""]], ["_sync", false, [false]]];
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Garage] Empty/Invalid UID!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Garage] Empty/Invalid Session!" };
GVAR(GarageStore) call ["get", [GVAR(GarageRegistry), "garage:get", _uid, _sync]];
GVAR(GarageStore) call ["get", [GVAR(GarageRegistry), "garage:get", _uid]];
}] call CFUNC(addEventHandler);
[QGVAR(requestSetGarage), {
@ -29,9 +25,6 @@ PREP_RECOMPILE_END;
if (_uid isEqualTo "" || _key isEqualTo "") exitWith { diag_log "[FORGE:Server:Garage] Empty/Invalid UID or Key!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Garage] Empty/Invalid Session!" };
private _hashMap = GVAR(GarageStore) call ["set", [GVAR(GarageRegistry), "garage:update", _uid, _key, _value, _sync]];
private _player = [_uid] call EFUNC(common,getPlayer);
@ -44,9 +37,6 @@ PREP_RECOMPILE_END;
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Garage] Empty/Invalid UID!" };
if ((_fieldValuePairs isEqualTo createHashMap) || !(_fieldValuePairs isEqualType createHashMap)) exitWith { diag_log "[FORGE:Server:Garage] Empty/Invalid field pairs!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Garage] Empty/Invalid Session!" };
private _hashMap = GVAR(GarageStore) call ["mset", [GVAR(GarageRegistry), "garage:update", _uid, _fieldValuePairs, _sync]];
private _player = [_uid] call EFUNC(common,getPlayer);
@ -54,14 +44,11 @@ PREP_RECOMPILE_END;
}] call CFUNC(addEventHandler);
[QGVAR(requestSaveGarage), {
params [["_uid", "", [""]], ["_sync", false, [false]]];
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Garage] Empty/Invalid UID!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Garage] Empty/Invalid Session!" };
private _finalData = GVAR(GarageStore) call ["save", [GVAR(GarageRegistry), "garage:update", _uid, _sync]];
private _finalData = GVAR(GarageStore) call ["save", [GVAR(GarageRegistry), "garage:update", _uid]];
private _player = [_uid] call EFUNC(common,getPlayer);
[CRPC(garage,responseSyncGarage), [_finalData], _player] call CFUNC(targetEvent);
@ -71,7 +58,6 @@ PREP_RECOMPILE_END;
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Garage] Empty/Invalid UID!" };
GVAR(GarageStore) call ["remove", [GVAR(GarageRegistry), _uid]];
}] call CFUNC(addEventHandler);
@ -85,14 +71,11 @@ PREP_RECOMPILE_END;
}] call CFUNC(addEventHandler);
[QGVAR(requestGetVG), {
params [["_uid", "", [""]], ["_sync", false, [false]]];
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:VGarage] Empty/Invalid UID!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:VGarage] Empty/Invalid Session!" };
private _hashMap = GVAR(VGarageStore) call ["get", [GVAR(VGarageRegistry), "owned:garage:fetch", _uid, _sync]];
private _hashMap = GVAR(VGarageStore) call ["get", [GVAR(VGarageRegistry), "owned:garage:fetch", _uid]];
private _player = [_uid] call EFUNC(common,getPlayer);
[CRPC(garage,responseSyncVG), [_hashMap], _player] call CFUNC(targetEvent);
@ -103,9 +86,6 @@ PREP_RECOMPILE_END;
if (_uid isEqualTo "" || _key isEqualTo "") exitWith { diag_log "[FORGE:Server:VGarage] Empty/Invalid UID or Key!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:VGarage] Empty/Invalid Session!" };
private _hashMap = GVAR(VGarageStore) call ["set", [GVAR(VGarageRegistry), "", _uid, _key, _value, _sync]];
private _player = [_uid] call EFUNC(common,getPlayer);
@ -118,9 +98,6 @@ PREP_RECOMPILE_END;
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:VGarage] Empty/Invalid UID!" };
if ((_fieldValuePairs isEqualTo createHashMap) || !(_fieldValuePairs isEqualType createHashMap)) exitWith { diag_log "[FORGE:Server:VGarage] Empty/Invalid field pairs!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:VGarage] Empty/Invalid Session!" };
private _hashMap = GVAR(VGarageStore) call ["mset", [GVAR(VGarageRegistry), "", _uid, _fieldValuePairs, _sync]];
private _player = [_uid] call EFUNC(common,getPlayer);
@ -128,14 +105,11 @@ PREP_RECOMPILE_END;
}] call CFUNC(addEventHandler);
[QGVAR(requestSaveVG), {
params [["_uid", "", [""]], ["_sync", false, [false]]];
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:VGarage] Empty/Invalid UID!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:VGarage] Empty/Invalid Session!" };
private _finalData = GVAR(VGarageStore) call ["save", [GVAR(VGarageRegistry), "", _uid, _sync]];
private _finalData = GVAR(VGarageStore) call ["save", [GVAR(VGarageRegistry), "", _uid]];
private _player = [_uid] call EFUNC(common,getPlayer);
[CRPC(garage,responseSyncVG), [_finalData], _player] call CFUNC(targetEvent);
@ -145,6 +119,5 @@ PREP_RECOMPILE_END;
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:VGarage] Empty/Invalid UID!" };
GVAR(VGarageStore) call ["remove", [GVAR(VGarageRegistry), _uid]];
}] call CFUNC(addEventHandler);

View File

@ -4,22 +4,24 @@
* File: fnc_initGarage.sqf
* Author: IDSolutions
* Date: 2025-12-17
* Last Update: 2025-12-19
* Last Update: 2026-01-28
* Public: No
*
* Description:
* No description added yet.
* Initializes all garages defined in the mission configuration.
*
* Parameter(s):
* N/A
* Arguments:
* None
*
* Returns:
* Something [BOOL]
* Return Value:
* None
*
* Example(s):
* [parameter] call forge_x_component_fnc_myFunction
* Example:
* [] call forge_server_garage_fnc_initGarage
*/
// TODO: Refactor to read from placed objects and their variables instead of missionConfig entries.
private _mC = "FORGE_CfgGarages";
private _garages = "true" configClasses (missionConfigFile >> "FORGE_CfgGarages" >> "garages");

View File

@ -4,63 +4,77 @@
* File: fnc_initGarageStore.sqf
* Author: IDSolutions
* Date: 2025-12-17
* Last Update: 2026-01-10
* Last Update: 2026-01-28
* Public: No
*
* Description:
* Initializes the Garage store for managing player vehicles.
* Provides methods for syncing, saving, and applying vehicles to the player's garage.
* Initializes the Garage store for managing player vehicles.
* Provides methods for syncing, saving, and applying vehicles to the player's garage.
*
* Parameter(s):
* N/A
* Arguments:
* None
*
* Returns:
* Something [BOOL]
* Return Value:
* Garage store object [HASHMAP OBJECT]
*
* Example(s):
* [parameter] call forge_x_component_fnc_myFunction
* Example:
* [] call forge_server_garage_fnc_initGarageStore
*/
#pragma hemtt ignore_variables ["_self"]
private _typeGarage = compileFinal createHashMapFromArray [
GVAR(GarageRepository) = compileFinal createHashMapFromArray [
["#base", EGVAR(common,BaseStore)],
["#type", "IGarageBase"],
["init", {
params [["_uid", "", [""]], ["_defaultGarage", createHashMap, [createHashMap]]];
["#type", "GarageRepository"],
["#create", {
GVAR(GarageRegistry) = createHashMap;
["INFO", "Garage Repository Initialized!"] call EFUNC(common,log);
}],
["get", {
params [["_uid", "", [""]]];
private _cached = GVAR(GarageRegistry) getOrDefault [_uid, nil];
if !(isNil { _cached }) exitWith { _cached };
["garage:exists", [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"];
if !(_isSuccess) exitWith {
["ERROR", format ["Failed to check if garage %1 exists!", _uid]] call EFUNC(common,log);
createHashMap
};
private _finalGarage = createHashMap;
["garage:exists", [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"];
private _exists = _result == "true";
if !(_exists) then {
_finalGarage = _defaultGarage;
["garage:create", [_uid]] call EFUNC(extension,extCall);
["INFO", format ["Created new garage for %1", _uid], nil, nil] call EFUNC(common,log);
} else {
if (_result == "true") then {
_finalGarage = _self call ["fetch", ["garage:get", _uid]];
["INFO", format ["Found garage for %1", _uid], nil, nil] call EFUNC(common,log);
["INFO", format ["Found garage for %1", _uid]] call EFUNC(common,log);
} else {
["garage:create", [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"];
if !(_isSuccess) exitWith {
["ERROR", format ["Failed to create garage for %1!", _uid]] call EFUNC(common,log);
createHashMap
};
["INFO", format ["Created new garage for %1", _uid]] call EFUNC(common,log);
};
GVAR(GarageRegistry) set [_uid, _finalGarage];
private _player = [_uid] call EFUNC(common,getPlayer);
[CRPC(garage,responseInitGarage), [_finalGarage], _player] call CFUNC(targetEvent);
_finalGarage
}]
];
GVAR(GarageStore) = createHashMapObject [[
["#base", _typeGarage],
["#base", GVAR(GarageRepository)],
["#type", "IGarageStore"],
["#create", {
GVAR(GarageRegistry) = createHashMap;
["INFO", "Garage Store Initialized!"] call EFUNC(common,log);
}],
["init", {
params [["_uid", "", [""]]];
["INFO", "Garage Store Initialized!", nil, nil] call EFUNC(common,log);
private _garage = _self call ["get", [_uid]];
private _player = [_uid] call EFUNC(common,getPlayer);
[CRPC(garage,responseInitGarage), [_garage], _player] call CFUNC(targetEvent);
}]
]];
SETMVAR(FORGE_GarageStore,GVAR(GarageStore));
GVAR(GarageStore)

View File

@ -4,67 +4,95 @@
* File: fnc_initVGStore.sqf
* Author: IDSolutions
* Date: 2025-12-17
* Last Update: 2026-01-10
* Last Update: 2026-01-28
* Public: No
*
* Description:
* Initializes the Virtual Garage store for managing player vehicle unlocks.
* Provides methods for syncing, saving, and applying virtual vehicles to BIS Garage.
* Initializes the Virtual Garage store for managing player vehicle unlocks.
* Provides methods for syncing, saving, and applying virtual vehicles to BIS Garage.
*
* Parameter(s):
* N/A
* Arguments:
* None
*
* Returns:
* Something [BOOL]
* Return Value:
* VG store object [HASHMAP OBJECT]
*
* Example(s):
* [parameter] call forge_x_component_fnc_myFunction
* Example:
* [] call forge_server_garage_fnc_initVGStore
*/
#pragma hemtt ignore_variables ["_self"]
private _typeVGarage = compileFinal createHashMapFromArray [
GVAR(VGarageModel) = compileFinal createHashMapObject [[
["#type", "VGarageModel"],
["defaults", {
private _vGarage = createHashMap;
_vGarage set ["armor", []];
_vGarage set ["cars", []];
_vGarage set ["helis", []];
_vGarage set ["naval", []];
_vGarage set ["other", []];
_vGarage set ["planes", []];
_vGarage
}]
]];
GVAR(VGarageRepository) = compileFinal createHashMapFromArray [
["#base", EGVAR(common,BaseStore)],
["#type", "IVGarageBase"],
["init", {
params [["_uid", "", [""]], ["_defaultVGarage", createHashMap, [createHashMap]]];
["#type", "VGarageRepository"],
["#create", {
GVAR(VGarageRegistry) = createHashMap;
["INFO", "VGarage Repository Initialized!"] call EFUNC(common,log);
}],
["get", {
params [["_uid", "", [""]]];
private _cached = GVAR(VGarageRegistry) getOrDefault [_uid, nil];
if !(isNil { _cached }) exitWith { _cached };
["owned:garage:exists", [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"];
if !(_isSuccess) exitWith {
["ERROR", format ["Failed to check if virtual garage %1 exists!", _uid]] call EFUNC(common,log);
createHashMap
};
private _finalVGarage = createHashMap;
["owned:garage:exists", [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"];
private _exists = _result == "true";
if !(_exists) then {
_finalVGarage = _defaultVGarage;
["owned:garage:create", [_uid]] call EFUNC(extension,extCall);
["INFO", format ["Created new VGarage for %1", _uid], nil, nil] call EFUNC(common,log);
if (_result == "true") then {
_finalVGarage = _self call ["fetch", ["owned:garage:fetch", _uid]];
["INFO", format ["Found virtual garage for %1", _uid]] call EFUNC(common,log);
} else {
private _existingVGarage = _self call ["fetch", ["owned:garage:fetch", _uid]];
_finalVGarage = _existingVGarage;
_finalVGarage = GVAR(VGarageModel) call ["defaults", []];
{
if !(_x in _finalVGarage) then { _finalVGarage set [_x, _y]; };
} forEach _defaultVGarage;
["owned:garage:create", [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"];
if !(_isSuccess) exitWith {
["ERROR", format ["Failed to create virtual garage for %1!", _uid]] call EFUNC(common,log);
createHashMap
};
["INFO", format ["Created new virtual garage for %1", _uid]] call EFUNC(common,log);
};
GVAR(VGarageRegistry) set [_uid, _finalVGarage];
private _player = [_uid] call EFUNC(common,getPlayer);
[CRPC(garage,responseInitVG), [_finalVGarage], _player] call CFUNC(targetEvent);
_finalVGarage
}]
];
GVAR(VGarageStore) = createHashMapObject [[
["#base", _typeVGarage],
["#type", "IVGarageStore"],
["#base", GVAR(VGarageRepository)],
["#type", "VGarageStore"],
["#create", {
GVAR(VGarageRegistry) = createHashMap;
["INFO", "VGarage Store Initialized!"] call EFUNC(common,log);
}],
["init", {
params [["_uid", "", [""]]];
["INFO", "VGarage Store Initialized!", nil, nil] call EFUNC(common,log);
private _vGarage = _self call ["get", [_uid]];
private _player = [_uid] call EFUNC(common,getPlayer);
[CRPC(garage,responseInitVG), [_vGarage], _player] call CFUNC(targetEvent);
}]
]];
SETMVAR(FORGE_VGarageStore,GVAR(VGarageStore));
GVAR(VGarageStore)

View File

@ -14,14 +14,10 @@ PREP_RECOMPILE_END;
}] call CFUNC(addEventHandler);
[QGVAR(requestGetLocker), {
params [["_uid", "", [""]], ["_sync", false, [false]]];
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Locker] Empty/Invalid UID!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Locker] Empty/Invalid Session!" };
GVAR(LockerStore) call ["get", [GVAR(LockerRegistry), "locker:get", _uid, _sync]];
GVAR(LockerStore) call ["get", [GVAR(LockerRegistry), "locker:get", _uid]];
}] call CFUNC(addEventHandler);
[QGVAR(requestSetLocker), {
@ -29,9 +25,6 @@ PREP_RECOMPILE_END;
if (_uid isEqualTo "" || _key isEqualTo "") exitWith { diag_log "[FORGE:Server:Locker] Empty/Invalid UID or Key!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Locker] Empty/Invalid Session!" };
private _hashMap = GVAR(LockerStore) call ["set", [GVAR(LockerRegistry), "locker:update", _uid, _key, _value, _sync]];
private _player = [_uid] call EFUNC(common,getPlayer);
@ -44,9 +37,6 @@ PREP_RECOMPILE_END;
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Locker] Empty/Invalid UID!" };
if ((_fieldValuePairs isEqualTo createHashMap) || !(_fieldValuePairs isEqualType createHashMap)) exitWith { diag_log "[FORGE:Server:Locker] Empty/Invalid field pairs!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Locker] Empty/Invalid Session!" };
private _hashMap = GVAR(LockerStore) call ["mset", [GVAR(LockerRegistry), "locker:update", _uid, _fieldValuePairs, _sync]];
private _player = [_uid] call EFUNC(common,getPlayer);
@ -54,14 +44,11 @@ PREP_RECOMPILE_END;
}] call CFUNC(addEventHandler);
[QGVAR(requestSaveLocker), {
params [["_uid", "", [""]], ["_sync", false, [false]]];
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Locker] Empty/Invalid UID!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Locker] Empty/Invalid Session!" };
private _finalData = GVAR(LockerStore) call ["save", [GVAR(LockerRegistry), "locker:update", _uid, _sync]];
private _finalData = GVAR(LockerStore) call ["save", [GVAR(LockerRegistry), "locker:update", _uid]];
private _player = [_uid] call EFUNC(common,getPlayer);
[CRPC(locker,responseSyncLocker), [_finalData], _player] call CFUNC(targetEvent);
@ -71,7 +58,6 @@ PREP_RECOMPILE_END;
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Locker] Empty/Invalid UID!" };
GVAR(LockerStore) call ["remove", [_uid]];
}] call CFUNC(addEventHandler);
@ -85,14 +71,14 @@ PREP_RECOMPILE_END;
}] call CFUNC(addEventHandler);
[QGVAR(requestGetVA), {
params [["_uid", "", [""]], ["_sync", false, [false]]];
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid UID!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid Session!" };
GVAR(VArsenalStore) call ["get", [GVAR(VArsenalRegistry), "owned:locker:fetch", _uid, _sync]];
GVAR(VArsenalStore) call ["get", [GVAR(VArsenalRegistry), "owned:locker:fetch", _uid]];
}] call CFUNC(addEventHandler);
[QGVAR(requestSetVA), {
@ -125,14 +111,14 @@ PREP_RECOMPILE_END;
}] call CFUNC(addEventHandler);
[QGVAR(requestSaveVA), {
params [["_uid", "", [""]], ["_sync", false, [false]]];
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid UID!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid Session!" };
private _finalData = GVAR(VArsenalStore) call ["save", [GVAR(VArsenalRegistry), "owned:locker:update", _uid, _sync]];
private _finalData = GVAR(VArsenalStore) call ["save", [GVAR(VArsenalRegistry), "owned:locker:update", _uid]];
private _player = [_uid] call EFUNC(common,getPlayer);
[CRPC(locker,responseSyncVArsenal), [_finalData], _player] call CFUNC(targetEvent);
@ -142,6 +128,5 @@ PREP_RECOMPILE_END;
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid UID!" };
GVAR(VArsenalStore) call ["remove", [GVAR(VArsenalRegistry), _uid]];
}] call CFUNC(addEventHandler);

View File

@ -4,22 +4,24 @@
* File: fnc_initLocker.sqf
* Author: IDSolutions
* Date: 2025-12-17
* Last Update: 2025-12-19
* Last Update: 2026-01-28
* Public: No
*
* Description:
* No description added yet.
* Initializes all lockers defined in the mission configuration.
*
* Parameter(s):
* N/A
* Arguments:
* None
*
* Returns:
* Something [BOOL]
* Return Value:
* None
*
* Example(s):
* [parameter] call forge_x_component_fnc_myFunction
* Example:
* [] call forge_server_locker_fnc_initLocker
*/
// TODO: Refactor to read from placed objects and their variables instead of missionConfig entries.
private _mC = "FORGE_CfgLockers";
private _lockers = "true" configClasses (missionConfigFile >> "FORGE_CfgLockers" >> "lockers");
@ -28,12 +30,56 @@ private _lockers = "true" configClasses (missionConfigFile >> "FORGE_CfgLockers"
private _className = (missionConfigFile >> _mC >> "lockers" >> _configName >> "className") call BFUNC(getCfgData);
private _pos = (missionConfigFile >> _mC >> "lockers" >> _configName >> "pos") call BFUNC(getCfgData);
private _dir = (missionConfigFile >> _mC >> "lockers" >> _configName >> "dir") call BFUNC(getCfgData);
private _locker = createSimpleObject [_className, [0, 0, 0]];
private _locker = createVehicle [_className, [0, 0, 0]];
// private _prefix = "FORGE_Locker";
// private _varName = format ["%1_%2", _prefix, _forEachIndex];
_locker setPosATL _pos;
_locker setDir _dir;
_locker allowDamage false;
_locker setVariable ["isLocker", true, true];
diag_log format ["[FORGE:Server:Locker] ClassName: %1 Pos: %2 Dir: %3", _className, _pos, _dir];
clearBackpackCargoGlobal _locker;
clearItemCargoGlobal _locker;
clearMagazineCargoGlobal _locker;
clearWeaponCargoGlobal _locker;
// private _pLocker = vehicle _locker;
// _pLocker setVehicleVarName _varName;
// missionNamespace setVariable [_varName, _pLocker, true];
// _locker addEventHandler ["ContainerOpened", {
// params ["_container", "_unit"];
// private _uid = getPlayerUID _unit;
// private _pLocker = GVAR(LockerRegistry) get _uid;
// diag_log text format ["[FORGE] (locker) INFO: Container opened, refreshing inventory: %1 w/ %2", _container, _pLocker];
// // Clear existing cargo
// clearBackpackCargo _container;
// clearItemCargo _container;
// clearMagazineCargo _container;
// clearWeaponCargo _container;
// // Repopulate with current locker items
// {
// private _amount = _y get "amount";
// private _category = _y get "category";
// private _className = _y get "classname";
// switch (_category) do {
// case "backpack": { _container addBackpackCargo [_className, _amount]; };
// case "item": { _container addItemCargo [_className, _amount]; };
// case "magazine": { _container addMagazineCargo [_className, _amount]; };
// case "weapon": { _container addWeaponCargo [_className, _amount]; };
// default { _container addItemCargo [_className, _amount]; };
// };
// } forEach _pLocker;
// diag_log text format ["[FORGE] (locker) INFO: Inventory refreshed"];
// }];
diag_log format ["[FORGE:Server:Locker] ClassName: %1 Pos: %2 Dir: %3", _className, _pos, _dir];
} forEach _lockers;

View File

@ -4,63 +4,77 @@
* File: fnc_initLockerStore.sqf
* Author: IDSolutions
* Date: 2025-12-17
* Last Update: 2026-01-10
* Last Update: 2026-01-28
* Public: No
*
* Description:
* Initializes the Locker store for managing player locker items.
* Provides methods for syncing, saving, and applying locker items to the player's locker.
* Initializes the Locker store for managing player locker items.
* Provides methods for syncing, saving, and applying locker items to the player's locker.
*
* Parameter(s):
* N/A
* Arguments:
* None
*
* Returns:
* vArsenal class object [HASHMAP OBJECT]
* Return Value:
* Locker store object [HASHMAP OBJECT]
*
* Example(s):
* [parameter] call forge_client_locker_fnc_initVAStore;
* Example:
* [] call forge_server_locker_fnc_initLockerStore
*/
#pragma hemtt ignore_variables ["_self"]
private _typeLocker = compileFinal createHashMapFromArray [
GVAR(LockerRepository) = compileFinal createHashMapFromArray [
["#base", EGVAR(common,BaseStore)],
["#type", "ILockerBase"],
["init", {
params [["_uid", "", [""]], ["_defaultLocker", createHashMap, [createHashMap]]];
["#type", "LockerRepository"],
["#create", {
GVAR(LockerRegistry) = createHashMap;
["INFO", "Locker Repository Initialized!"] call EFUNC(common,log);
}],
["get", {
params [["_uid", "", [""]]];
private _cached = GVAR(LockerRegistry) getOrDefault [_uid, nil];
if !(isNil { _cached }) exitWith { _cached };
["locker:exists", [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"];
if !(_isSuccess) exitWith {
["ERROR", format ["Failed to check if locker %1 exists!", _uid]] call EFUNC(common,log);
createHashMap
};
private _finalLocker = createHashMap;
["locker:exists", [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"];
private _exists = _result == "true";
if !(_exists) then {
_finalLocker = _defaultLocker;
["locker:create", [_uid]] call EFUNC(extension,extCall);
["INFO", format ["Created new locker for %1", _uid], nil, nil] call EFUNC(common,log);
if (_result == "true") then {
_finalLocker = _self call ["fetch", ["locker:get", _uid]];
["INFO", format ["Found locker for %1", _uid]] call EFUNC(common,log);
} else {
_finalLocker = _self call ["fetch", [_uid]];
["INFO", format ["Found locker for %1", _uid], nil, nil] call EFUNC(common,log);
["locker:create", [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"];
if !(_isSuccess) exitWith {
["ERROR", format ["Failed to create locker for %1!", _uid]] call EFUNC(common,log);
createHashMap
};
["INFO", format ["Created new locker for %1", _uid]] call EFUNC(common,log);
};
GVAR(LockerRegistry) set [_uid, _finalLocker];
private _player = [_uid] call EFUNC(common,getPlayer);
[CRPC(locker,responseInitLocker), [_finalLocker], _player] call CFUNC(targetEvent);
_finalLocker
}]
];
GVAR(LockerStore) = createHashMapObject [[
["#base", _typeLocker],
["#type", "ILockerStore"],
["#base", GVAR(LockerRepository)],
["#type", "LockerStore"],
["#create", {
GVAR(LockerRegistry) = createHashMap;
["INFO", "Locker Store Initialized!"] call EFUNC(common,log);
}],
["init", {
params [["_uid", "", [""]]];
["INFO", "Locker Store Initialized!", nil, nil] call EFUNC(common,log);
private _locker = _self call ["get", [_uid]];
private _player = [_uid] call EFUNC(common,getPlayer);
[CRPC(locker,responseInitLocker), [_locker], _player] call CFUNC(targetEvent);
}]
]];
SETMVAR(FORGE_LockerStore,GVAR(LockerStore));
GVAR(LockerStore)

View File

@ -4,67 +4,93 @@
* File: fnc_initVAStore.sqf
* Author: IDSolutions
* Date: 2025-12-17
* Last Update: 2026-01-10
* Last Update: 2026-01-28
* Public: No
*
* Description:
* Initializes the Virtual Arsenal store for managing player arsenal unlocks.
* Provides methods for syncing, saving, and applying virtual items to BIS Arsenal.
* Initializes the Virtual Arsenal store for managing player arsenal unlocks.
* Provides methods for syncing, saving, and applying virtual items to BIS Arsenal.
*
* Parameter(s):
* N/A
* Arguments:
* None
*
* Returns:
* vArsenal class object [HASHMAP OBJECT]
* Return Value:
* VA store object [HASHMAP OBJECT]
*
* Example(s):
* [parameter] call forge_client_locker_fnc_initVAStore;
* Example:
* [] call forge_server_locker_fnc_initVAStore
*/
#pragma hemtt ignore_variables ["_self"]
private _typeVArsenal = compileFinal createHashMapFromArray [
GVAR(VArsenalModel) = compileFinal createHashMapObject [[
["#type", "VArsenalModel"],
["defaults", {
private _vArsenal = createHashMap;
_vArsenal set ["backpacks", ["B_AssaultPack_rgr"]];
_vArsenal set ["items", ["FirstAidKit", "G_Combat", "H_Cap_blk_ION", "H_HelmetB", "ItemCompass", "ItemGPS", "ItemMap", "ItemRadio", "ItemWatch", "U_IG_Guerrilla_6_1", "V_TacVest_oli"]];
_vArsenal set ["magazines", ["16Rnd_9x21_Mag", "30Rnd_65x39_caseless_black_mag", "Chemlight_blue", "Chemlight_green", "Chemlight_red", "Chemlight_yellow", "HandGrenade", "SmokeShell", "SmokeShellBlue", "SmokeShellGreen", "SmokeShellOrange", "SmokeShellPurple", "SmokeShellRed", "SmokeShellYellow"]];
_vArsenal set ["weapons", ["arifle_MX_F", "hgun_P07_F"]];
_vArsenal
}]
]];
GVAR(VArsenalRepository) = compileFinal createHashMapFromArray [
["#base", EGVAR(common,BaseStore)],
["#type", "IVArsenalBase"],
["init", {
params [["_uid", "", [""]], ["_defaultVArsenal", createHashMap, [createHashMap]]];
["#type", "VArsenalRepository"],
["#create", {
GVAR(VArsenalRegistry) = createHashMap;
["INFO", "VArsenal Repository Initialized!"] call EFUNC(common,log);
}],
["get", {
params [["_uid", "", [""]]];
private _cached = GVAR(VArsenalRegistry) getOrDefault [_uid, nil];
if !(isNil { _cached }) exitWith { _cached };
["owned:locker:exists", [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"];
if !(_isSuccess) exitWith {
["ERROR", format ["Failed to check if virtual arsenal %1 exists!", _uid]] call EFUNC(common,log);
createHashMap
};
private _finalVArsenal = createHashMap;
["owned:locker:exists", [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"];
private _exists = _result == "true";
if !(_exists) then {
_finalVArsenal = _defaultVArsenal;
["owned:locker:create", [_uid]] call EFUNC(extension,extCall);
["INFO", format ["Created new VArsenal for %1", _uid], nil, nil] call EFUNC(common,log);
if (_result == "true") then {
_finalVArsenal = _self call ["fetch", ["owned:locker:fetch", _uid]];
["INFO", format ["Found virtual arsenal for %1", _uid]] call EFUNC(common,log);
} else {
private _existingVArsenal = _self call ["fetch", [_uid]];
_finalVArsenal = _existingVArsenal;
_finalVArsenal = GVAR(VArsenalModel) call ["defaults", []];
{
if !(_x in _finalVArsenal) then { _finalVArsenal set [_x, _y]; };
} forEach _defaultVArsenal;
["owned:locker:create", [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"];
if !(_isSuccess) exitWith {
["ERROR", format ["Failed to create virtual arsenal for %1!", _uid]] call EFUNC(common,log);
createHashMap
};
["INFO", format ["Created new virtual arsenal for %1", _uid]] call EFUNC(common,log);
};
GVAR(VArsenalRegistry) set [_uid, _finalVArsenal];
private _player = [_uid] call EFUNC(common,getPlayer);
[CRPC(locker,responseInitVA), [_finalVArsenal], _player] call CFUNC(targetEvent);
_finalVArsenal
}]
];
GVAR(VArsenalStore) = createHashMapObject [[
["#base", _typeVArsenal],
["#type", "IVArsenalStore"],
["#base", GVAR(VArsenalRepository)],
["#type", "VArsenalStore"],
["#create", {
GVAR(VArsenalRegistry) = createHashMap;
["INFO", "VArsenal Store Initialized!"] call EFUNC(common,log);
}],
["init", {
params [["_uid", "", [""]]];
["INFO", "VArsenal Store Initialized!", nil, nil] call EFUNC(common,log);
private _vArsenal = _self call ["get", [_uid]];
private _player = [_uid] call EFUNC(common,getPlayer);
[CRPC(locker,responseInitVA), [_vArsenal], _player] call CFUNC(targetEvent);
}]
]];
SETMVAR(FORGE_VArsenalStore,GVAR(VArsenalStore));
GVAR(VArsenalStore)

View File

@ -19,10 +19,6 @@ PREP_RECOMPILE_END;
params [["_uid", "", [""]], ["_sync", false, [false]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Org] Empty/Invalid UID!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Org] Empty/Invalid Session!" };
GVAR(OrgStore) call ["get", [_uid, _sync]];
}] call CFUNC(addEventHandler);
@ -30,10 +26,6 @@ PREP_RECOMPILE_END;
params [["_uid", "", [""]], ["_key", "", [""]], ["_value", nil, [[], "", 0, false, createHashMap]], ["_sync", false, [false]]];
if (_uid isEqualTo "" || _key isEqualTo "") exitWith { diag_log "[FORGE:Server:Org] Empty/Invalid UID or Key!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Org] Empty/Invalid Session!" };
GVAR(OrgStore) call ["set", [_uid, _key, _value, _sync]];
}] call CFUNC(addEventHandler);
@ -43,9 +35,6 @@ PREP_RECOMPILE_END;
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Org] Empty/Invalid UID!" };
if ((_fieldValuePairs isEqualTo createHashMap) || !(_fieldValuePairs isEqualType createHashMap)) exitWith { diag_log "[FORGE:Server:Org] Empty/Invalid field pairs!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Org] Empty/Invalid Session!" };
GVAR(OrgStore) call ["mset", [_uid, _fieldValuePairs, _sync]];
}] call CFUNC(addEventHandler);
@ -53,10 +42,6 @@ PREP_RECOMPILE_END;
params [["_uid", "", [""]], ["_sync", false, [false]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Org] Empty/Invalid UID!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:Org] Empty/Invalid Session!" };
GVAR(OrgStore) call ["save", [_uid, _sync]];
}] call CFUNC(addEventHandler);
@ -64,6 +49,5 @@ PREP_RECOMPILE_END;
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Org] Empty/Invalid UID!" };
GVAR(OrgStore) call ["remove", [_uid]];
}] call CFUNC(addEventHandler);

View File

@ -1,6 +1,6 @@
use arma_rs::{
FromArma, IntoArma,
loadout::{AssignedItems, Loadout as ArmaLoadout},
loadout::{AssignedItems, InventoryItem, Loadout as ArmaLoadout},
};
use forge_shared::{
ActorValidationError, arma_value_to_json, generate_email, generate_phone_number,
@ -135,6 +135,9 @@ impl Actor {
let uniform = loadout.uniform_mut();
uniform.set_class("U_BG_Guerrilla_6_1".to_string());
let uniform_items = uniform.items_mut().unwrap();
uniform_items.push(InventoryItem::new_item("FirstAidKit".to_string(), 1));
loadout.set_headgear("H_Cap_blk_ION".to_string());
let mut items = AssignedItems::default();

View File

@ -24,7 +24,7 @@ pub struct VGarage {
impl VGarage {
pub fn new() -> Self {
Self {
cars: Vec::new(),
cars: vec!["B_Quadbike_01_F".to_string()],
armor: Vec::new(),
helis: Vec::new(),
planes: Vec::new(),
@ -79,12 +79,6 @@ impl VGarage {
}
}
impl Default for VGarage {
fn default() -> Self {
Self::new()
}
}
impl FromArma for VGarage {
fn from_arma(s: String) -> Result<Self, arma_rs::FromArmaError> {
serde_json::from_str(&s)

View File

@ -20,10 +20,37 @@ pub struct VLocker {
impl VLocker {
pub fn new() -> Self {
Self {
items: Vec::new(),
weapons: Vec::new(),
magazines: Vec::new(),
backpacks: Vec::new(),
items: vec![
"FirstAidKit".to_string(),
"G_Combat".to_string(),
"H_Cap_blk_ION".to_string(),
"H_HelmetB".to_string(),
"ItemCompass".to_string(),
"ItemGPS".to_string(),
"ItemMap".to_string(),
"ItemRadio".to_string(),
"ItemWatch".to_string(),
"U_IG_Guerrilla_6_1".to_string(),
"V_TacVest_oli".to_string(),
],
weapons: vec!["arifle_MX_F".to_string(), "hgun_P07_F".to_string()],
magazines: vec![
"16Rnd_9x21_Mag".to_string(),
"30Rnd_65x39_caseless_black_mag".to_string(),
"Chemlight_blue".to_string(),
"Chemlight_green".to_string(),
"Chemlight_red".to_string(),
"Chemlight_yellow".to_string(),
"HandGrenade".to_string(),
"SmokeShell".to_string(),
"SmokeShellBlue".to_string(),
"SmokeShellGreen".to_string(),
"SmokeShellOrange".to_string(),
"SmokeShellPurple".to_string(),
"SmokeShellRed".to_string(),
"SmokeShellYellow".to_string(),
],
backpacks: vec!["B_AssaultPack_rgr".to_string()],
}
}