feat: Implement core game systems for actor, garage, organization, bank, locker, and notifications with client-side UI and server-side data stores.

This commit is contained in:
Jacob Schmidt 2026-01-30 20:19:29 -06:00
parent 9c09976ef2
commit aef7f9ae48
49 changed files with 384 additions and 254 deletions

View File

@ -23,7 +23,7 @@ player addEventHandler ["Respawn", {
[SRPC(economy,onRespawn), [_unit, _corpse, _uid]] call CFUNC(serverEvent); [SRPC(economy,onRespawn), [_unit, _corpse, _uid]] call CFUNC(serverEvent);
}]; }];
if (isNil QGVAR(ActorClass)) then { [] call FUNC(initActorClass); }; if (isNil QGVAR(ActorClass)) then { call FUNC(initActorClass); };
[QGVAR(initActor), { [QGVAR(initActor), {
GVAR(ActorClass) call ["init", []]; GVAR(ActorClass) call ["init", []];

View File

@ -4,7 +4,7 @@
* File: fnc_handleUIEvents.sqf * File: fnc_handleUIEvents.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2026-01-28 * Date: 2026-01-28
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -19,7 +19,7 @@
* UI events handled [BOOL] * UI events handled [BOOL]
* *
* Example: * Example:
* [] call forge_client_actor_fnc_handleUIEvents; * call forge_client_actor_fnc_handleUIEvents;
*/ */
params ["_control", "_isConfirmDialog", "_message"]; params ["_control", "_isConfirmDialog", "_message"];
@ -27,7 +27,7 @@ params ["_control", "_isConfirmDialog", "_message"];
private _alert = fromJSON _message; private _alert = fromJSON _message;
private _event = _alert get "event"; private _event = _alert get "event";
private _data = _alert get "data"; private _data = _alert get "data";
private _display = displayChild findDisplay 46; // private _display = displayChild findDisplay 46;
diag_log format ["[FORGE:Client:Actor] Handling UI event: %1 with data: %2", _event, _data]; diag_log format ["[FORGE:Client:Actor] Handling UI event: %1 with data: %2", _event, _data];
@ -35,19 +35,20 @@ switch (_event) do {
case "actor::get::actions": { GVAR(ActorClass) call ["getNearbyActions", [_control]]; }; case "actor::get::actions": { GVAR(ActorClass) call ["getNearbyActions", [_control]]; };
case "actor::open::atm": { [true] spawn EFUNC(bank,openUI); }; case "actor::open::atm": { [true] spawn EFUNC(bank,openUI); };
case "actor::open::bank": { [] spawn EFUNC(bank,openUI); }; case "actor::open::bank": { [] spawn EFUNC(bank,openUI); };
case "actor::open::device": { hint "Device interaction is not yet implemented."; }; // TODO: Implement device interaction case "actor::open::device": { hint "Device interaction is not yet implemented."; };
case "actor::open::garage": { hint "Garage interaction is not yet implemented."; }; // TODO: Implement garage interaction case "actor::open::garage": { hint "Garage interaction is not yet implemented."; };
case "actor::open::vgarage": { [] spawn EFUNC(garage,openVG); }; case "actor::open::vgarage": { [] spawn EFUNC(garage,openVG); };
case "actor::open::org": { [] spawn EFUNC(org,openUI); }; case "actor::open::org": { [] spawn EFUNC(org,openUI); };
case "actor::open::locker": { hint "Locker interaction is not yet implemented."; }; // TODO: Implement locker interaction // case "actor::open::locker": { hint "Locker interaction is not yet implemented."; };
case "actor::open::vlocker": { ["Open", [false, FORGE_Locker_Box, player]] spawn BFUNC(arsenal) }; case "actor::open::vlocker": { ["Open", [false, FORGE_Locker_Box, player]] spawn BFUNC(arsenal) };
// case "actor::open::phone": { [] spawn EFUNC(phone,openUI) }; // case "actor::open::phone": { [] spawn EFUNC(phone,openUI) };
case "actor::open::phone": { hint "Phone interaction is not yet implemented."; }; // TODO: Implement phone interaction case "actor::open::phone": { hint "Phone interaction is not yet implemented."; };
case "actor::open::iplayer": { hint "Player interaction is not yet implemented." }; // TODO: Implement player interaction case "actor::open::iplayer": { hint "Player interaction is not yet implemented." };
case "actor::open::store": { hint "Store interaction is not yet implemented."; }; // TODO: Implement store interaction case "actor::open::store": { hint "Store interaction is not yet implemented."; };
default { hint format ["Unhandled UI event: %1", _event]; }; default { hint format ["Unhandled UI event: %1", _event]; };
}; };
if (_event isNotEqualTo "actor::get::actions") then { _display closeDisplay 1; }; // if (_event isNotEqualTo "actor::get::actions") then { _display closeDisplay 1; };
if (_event isNotEqualTo "actor::get::actions") then { closeDialog 1; };
true; true;

View File

@ -4,7 +4,7 @@
* File: fnc_initActorClass.sqf * File: fnc_initActorClass.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2026-01-28 * Date: 2026-01-28
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: Yes * Public: Yes
* *
* Description: * Description:
@ -18,7 +18,7 @@
* Actor class object [HASHMAP OBJECT] * Actor class object [HASHMAP OBJECT]
* *
* Example: * Example:
* [] call forge_client_actor_fnc_initActorClass * call forge_client_actor_fnc_initActorClass
*/ */
#pragma hemtt ignore_variables ["_self"] #pragma hemtt ignore_variables ["_self"]
@ -131,7 +131,7 @@ GVAR(ActorClass) = createHashMapObject [[
if (_storeType isNotEqualTo "") then { _nearbyActions pushBack ["store", _storeType]; }; if (_storeType isNotEqualTo "") then { _nearbyActions pushBack ["store", _storeType]; };
if (_isBank) then { _nearbyActions pushBack ["bank", true]; }; if (_isBank) then { _nearbyActions pushBack ["bank", true]; };
if (_isLocker) then { _nearbyActions pushBack ["locker", true]; }; // if (_isLocker) then { _nearbyActions pushBack ["locker", true]; };
if (_isLocker && GVAR(enableVA)) then { _nearbyActions pushBack ["va", true]; }; if (_isLocker && GVAR(enableVA)) then { _nearbyActions pushBack ["va", true]; };
if (_isGarage) then { _nearbyActions pushBack ["garage", _garageType]; }; if (_isGarage) then { _nearbyActions pushBack ["garage", _garageType]; };
if (_isGarage && GVAR(enableVG)) then { _nearbyActions pushBack ["vg", true]; }; if (_isGarage && GVAR(enableVG)) then { _nearbyActions pushBack ["vg", true]; };

View File

@ -4,7 +4,7 @@
* File: fnc_openUI.sqf * File: fnc_openUI.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2026-01-28 * Date: 2026-01-28
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -17,11 +17,11 @@
* UI opened [BOOL] * UI opened [BOOL]
* *
* Example: * Example:
* [] call forge_client_actor_fnc_openUI; * call forge_client_actor_fnc_openUI;
*/ */
private _display = (findDisplay 46) createDisplay "RscActorMenu"; private _display = createDialog ["RscActorMenu", true];
private _ctrl = (_display displayCtrl 1001); private _ctrl = _display displayCtrl 1001;
_ctrl ctrlAddEventHandler ["JSDialog", { _ctrl ctrlAddEventHandler ["JSDialog", {
params ["_control", "_isConfirmDialog", "_message"]; params ["_control", "_isConfirmDialog", "_message"];

View File

@ -92,13 +92,13 @@ const actionDefinitions = {
icon: "", icon: "",
action: "actor::open::garage", action: "actor::open::garage",
}, },
locker: { // locker: {
id: "locker", // id: "locker",
title: "Locker", // title: "Locker",
description: "Access your personal locker for storage", // description: "Access your personal locker for storage",
icon: "", // icon: "",
action: "actor::open::locker", // action: "actor::open::locker",
}, // },
player: { player: {
id: "player", id: "player",
title: "Player Interaction", title: "Player Interaction",

View File

@ -1,6 +1,6 @@
#include "script_component.hpp" #include "script_component.hpp"
if (isNil QGVAR(BankClass)) then { [] call FUNC(initBankClass); }; if (isNil QGVAR(BankClass)) then { call FUNC(initBankClass); };
[QGVAR(initBank), { [QGVAR(initBank), {
GVAR(BankClass) call ["init", []]; GVAR(BankClass) call ["init", []];

View File

@ -4,7 +4,7 @@
* File: fnc_handleUIEvents.sqf * File: fnc_handleUIEvents.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2025-12-16 * Date: 2025-12-16
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -19,7 +19,7 @@
* UI events handled [BOOL] * UI events handled [BOOL]
* *
* Example: * Example:
* [] call forge_client_bank_fnc_handleUIEvents; * call forge_client_bank_fnc_handleUIEvents;
*/ */
params ["_control", "_isConfirmDialog", "_message"]; params ["_control", "_isConfirmDialog", "_message"];

View File

@ -4,7 +4,7 @@
* File: fnc_initBankClass.sqf * File: fnc_initBankClass.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2025-12-16 * Date: 2025-12-16
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -17,7 +17,7 @@
* Bank class object [HASHMAP OBJECT] * Bank class object [HASHMAP OBJECT]
* *
* Example: * Example:
* [] call forge_client_bank_fnc_initBankClass * call forge_client_bank_fnc_initBankClass
*/ */
#pragma hemtt ignore_variables ["_self"] #pragma hemtt ignore_variables ["_self"]

View File

@ -4,7 +4,7 @@
* File: fnc_openUI.sqf * File: fnc_openUI.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2026-01-28 * Date: 2026-01-28
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -22,8 +22,8 @@
params [["_isATM", false, [false]]]; params [["_isATM", false, [false]]];
private _display = (findDisplay 46) createDisplay "RscBank"; private _display = createDialog ["RscBank", true];
private _ctrl = (_display displayCtrl 1002); private _ctrl = _display displayCtrl 1002;
_ctrl ctrlAddEventHandler ["JSDialog", { _ctrl ctrlAddEventHandler ["JSDialog", {
params ["_control", "_isConfirmDialog", "_message"]; params ["_control", "_isConfirmDialog", "_message"];

View File

@ -1,7 +1,7 @@
#include "script_component.hpp" #include "script_component.hpp"
if (isNil QGVAR(GarageClass)) then { [] call FUNC(initGarageClass); }; if (isNil QGVAR(GarageClass)) then { call FUNC(initGarageClass); };
if (isNil QGVAR(VGarageClass)) then { [] call FUNC(initVGClass); }; if (isNil QGVAR(VGarageClass)) then { call FUNC(initVGClass); };
[QGVAR(initGarage), { [QGVAR(initGarage), {
GVAR(GarageClass) call ["init", []]; GVAR(GarageClass) call ["init", []];

View File

@ -4,7 +4,7 @@
* File: fnc_handleUIEvents.sqf * File: fnc_handleUIEvents.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2025-12-16 * Date: 2025-12-16
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -19,5 +19,5 @@
* UI events handled [BOOL] * UI events handled [BOOL]
* *
* Example: * Example:
* [] call forge_client_garage_fnc_handleUIEvents; * call forge_client_garage_fnc_handleUIEvents;
*/ */

View File

@ -4,7 +4,7 @@
* File: fnc_initGarageClass.sqf * File: fnc_initGarageClass.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2025-12-17 * Date: 2025-12-17
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -18,7 +18,7 @@
* Garage class object [HASHMAP OBJECT] * Garage class object [HASHMAP OBJECT]
* *
* Example: * Example:
* [] call forge_client_garage_fnc_initGarageClass * call forge_client_garage_fnc_initGarageClass
*/ */
#pragma hemtt ignore_variables ["_self"] #pragma hemtt ignore_variables ["_self"]

View File

@ -4,7 +4,7 @@
* File: fnc_initVGClass.sqf * File: fnc_initVGClass.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2025-12-16 * Date: 2025-12-16
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -18,7 +18,7 @@
* vGarage class object [HASHMAP OBJECT] * vGarage class object [HASHMAP OBJECT]
* *
* Example: * Example:
* [] call forge_client_garage_fnc_initVGClass; * call forge_client_garage_fnc_initVGClass;
*/ */
#pragma hemtt ignore_variables ["_self"] #pragma hemtt ignore_variables ["_self"]

View File

@ -4,7 +4,7 @@
* File: fnc_openUI.sqf * File: fnc_openUI.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2025-12-16 * Date: 2025-12-16
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -17,5 +17,5 @@
* UI opened [BOOL] * UI opened [BOOL]
* *
* Example: * Example:
* [] call forge_client_garage_fnc_openUI; * call forge_client_garage_fnc_openUI;
*/ */

View File

@ -4,7 +4,7 @@
* File: fnc_openVG.sqf * File: fnc_openVG.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2025-12-16 * Date: 2025-12-16
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -17,7 +17,7 @@
* None * None
* *
* Example: * Example:
* [] call forge_client_garage_fnc_openVG * call forge_client_garage_fnc_openVG
*/ */
private _locations = (missionConfigFile >> "FORGE_CfgGarages" >> "locations") call BFUNC(getCfgData); private _locations = (missionConfigFile >> "FORGE_CfgGarages" >> "locations") call BFUNC(getCfgData);

View File

@ -1,7 +1,7 @@
#include "script_component.hpp" #include "script_component.hpp"
if (isNil QGVAR(LockerClass)) then { [] call FUNC(initLockerClass); }; if (isNil QGVAR(LockerClass)) then { call FUNC(initLockerClass); };
if (isNil QGVAR(VArsenalClass)) then { [] call FUNC(initVAClass); }; if (isNil QGVAR(VArsenalClass)) then { call FUNC(initVAClass); };
[QGVAR(initLocker), { [QGVAR(initLocker), {
GVAR(LockerClass) call ["init", []]; GVAR(LockerClass) call ["init", []];

View File

@ -1,23 +0,0 @@
#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:
* 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:
* UI events handled [BOOL]
*
* Example:
* [] call forge_client_locker_fnc_handleUIEvents;
*/

View File

@ -4,7 +4,7 @@
* File: fnc_initLockerClass.sqf * File: fnc_initLockerClass.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2025-12-17 * Date: 2025-12-17
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -18,26 +18,164 @@
* Locker class object [HASHMAP OBJECT] * Locker class object [HASHMAP OBJECT]
* *
* Example: * Example:
* [] call forge_client_locker_fnc_initLockerClass * call forge_client_locker_fnc_initLockerClass
*/ */
#pragma hemtt ignore_variables ["_self"] #pragma hemtt ignore_variables ["_self"]
GVAR(LockerClass) = createHashMapObject [[ GVAR(LockerRepository) = compileFinal createHashMapFromArray [
["#type", "ILockerClass"], ["#type", "LockerRepository"],
["#create", { ["get", {
_self set ["uid", (getPlayerUID player)]; params [["_key", "", [""]], ["_default", nil, [[], "", 0, false, createHashMap]]];
_self set ["locker", createHashMap];
_self set ["isLoaded", false];
_self set ["lastSave", time];
}],
["init", {
private _uid = _self get "uid";
private _locker = _self get "locker"; private _locker = _self get "locker";
_locker getOrDefault [_key, _default];
}],
["getCargo", {
params [["_container", objNull, [objNull]], ["_locker", createHashMap, [createHashMap]]];
[SRPC(locker,requestInitLocker), [_uid, _locker]] call CFUNC(serverEvent); private _cargoData = [
["item", getItemCargo _container],
["weapon", getWeaponCargo _container],
["magazine", getMagazineCargo _container],
["backpack", getBackpackCargo _container]
];
systemChat format ["Locker loaded for %1", (name player)]; {
diag_log "[FORGE:Client:Locker] Locker Class Initialized!"; _x params ["_category", "_data"];
_data params ["_classes", "_counts"];
{
private _class = _x;
private _count = _counts select _forEachIndex;
_locker set [_class, createHashMapFromArray [
["amount", _count],
["classname", _class],
["category", _category]
]];
} forEach _classes;
} forEach _cargoData;
_locker
}],
["getContainerItems", {
params [["_container", objNull, [objNull]], ["_locker", createHashMap, [createHashMap]]];
private _allContainers = everyContainer _container;
{
_x params ["_containerClass", "_containerObj"];
private _isBackpack = isClass (configFile >> "CfgVehicles" >> _containerClass);
private _cfgWeapons = configFile >> "CfgWeapons" >> _containerClass;
private _itemInfoType = getNumber (_cfgWeapons >> "ItemInfo" >> "type");
private _isVest = isClass _cfgWeapons && {_itemInfoType == 701};
private _isUniform = isClass _cfgWeapons && {_itemInfoType == 801};
if (!_isBackpack && !_isVest && !_isUniform) then { continue; };
private _containerItems = getItemCargo _containerObj;
_containerItems params ["_classes", "_counts"];
{
private _class = _x;
private _count = _counts select _forEachIndex;
private _existing = _locker getOrDefault [_class, createHashMap];
private _existingCount = _existing getOrDefault ["amount", 0];
_locker set [_class, createHashMapFromArray [
["amount", _existingCount + _count],
["classname", _class],
["category", "item"]
]];
} forEach _classes;
private _containerMags = getMagazineCargo _containerObj;
_containerMags params ["_classes", "_counts"];
{
private _class = _x;
private _count = _counts select _forEachIndex;
private _existing = _locker getOrDefault [_class, createHashMap];
private _existingCount = _existing getOrDefault ["amount", 0];
_locker set [_class, createHashMapFromArray [
["amount", _existingCount + _count],
["classname", _class],
["category", "magazine"]
]];
} forEach _classes;
private _containerWeapons = getWeaponCargo _containerObj;
_containerWeapons params ["_classes", "_counts"];
{
private _class = _x;
private _count = _counts select _forEachIndex;
private _existing = _locker getOrDefault [_class, createHashMap];
private _existingCount = _existing getOrDefault ["amount", 0];
_locker set [_class, createHashMapFromArray [
["amount", _existingCount + _count],
["classname", _class],
["category", "weapon"]
]];
} forEach _classes;
} forEach _allContainers;
_locker
}],
["getAttachments", {
params [["_container", objNull, [objNull]], ["_locker", createHashMap, [createHashMap]]];
private _weaponItems = weaponsItemsCargo _container;
{
// private _weapon = _x param [0, ""];
private _muzzle = _x param [1, ""];
private _pointer = _x param [2, ""];
private _optic = _x param [3, ""];
private _primaryMag = _x param [4, ["", 0]];
private _underbarrel = _x param [5, ""];
private _bipod = _x param [6, ""];
private _secondaryMag = _x param [7, ["", 0]];
private _attachments = [_muzzle, _pointer, _optic, _underbarrel, _bipod] select {(_x isEqualType "") && {_x != ""}};
{
private _existing = _locker getOrDefault [_x, createHashMap];
private _existingCount = _existing getOrDefault ["amount", 0];
_locker set [_x, createHashMapFromArray [
["amount", _existingCount + 1],
["classname", _x],
["category", "item"]
]];
} forEach _attachments;
if (_primaryMag isNotEqualTo ["", 0]) then {
_primaryMag params ["_magClass", "_ammoCount"];
if (_magClass != "") then {
private _existing = _locker getOrDefault [_magClass, createHashMap];
private _existingCount = _existing getOrDefault ["amount", 0];
_locker set [_magClass, createHashMapFromArray [
["amount", _existingCount + 1],
["classname", _magClass],
["category", "magazine"]
]];
};
};
if (_secondaryMag isNotEqualTo ["", 0]) then {
_secondaryMag params ["_magClass", "_ammoCount"];
if (_magClass != "") then {
private _existing = _locker getOrDefault [_magClass, createHashMap];
private _existingCount = _existing getOrDefault ["amount", 0];
_locker set [_magClass, createHashMapFromArray [
["amount", _existingCount + 1],
["classname", _magClass],
["category", "magazine"]
]];
};
};
} forEach _weaponItems;
_locker
}], }],
["save", { ["save", {
private _uid = _self get "uid"; private _uid = _self get "uid";
@ -45,25 +183,109 @@ GVAR(LockerClass) = createHashMapObject [[
_self set ["lastSave", time]; _self set ["lastSave", time];
}], }],
["setEventHandlers", {
params [["_locker", objNull, [objNull]]];
_locker addEventHandler ["ContainerOpened", {
params ["_container", "_unit"];
private _index = GVAR(LockerClass) get "locker";
clearBackpackCargo _container;
clearItemCargo _container;
clearMagazineCargo _container;
clearWeaponCargo _container;
{
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 _index;
}];
_locker addEventHandler ["ContainerClosed", {
params ["_container", "_unit"];
private _newLocker = createHashMap;
_newLocker = GVAR(LockerClass) call ["getCargo", [_container, _newLocker]];
_newLocker = GVAR(LockerClass) call ["getContainerItems", [_container, _newLocker]];
_newLocker = GVAR(LockerClass) call ["getAttachments", [_container, _newLocker]];
private _uid = getPlayerUID _unit;
[SRPC(locker,requestOverrideLocker), [_uid, _newLocker]] call CFUNC(serverEvent);
GVAR(LockerClass) set ["locker", _newLocker];
}];
}],
["setup", {
private _lockers = (allVariables missionNamespace) select {
private _var = missionNamespace getVariable _x;
("locker" in _x) && { _var isEqualType objNull } && { !isNull _var } && { _x isNotEqualTo "forge_locker_box" }
};
if (_lockers isEqualTo []) exitWith { diag_log "[FORGE:Client:Locker] No lockers found in missionNamespace."; };
{
private _globalLocker = missionNamespace getVariable _x;
private _pos = getPosASL _globalLocker;
private _vDir = vectorDir _globalLocker;
private _vUp = vectorUp _globalLocker;
private _localLocker = createVehicleLocal ["Box_NATO_Equip_F", [0, 0, 0]];
_localLocker setPosASL _pos;
_localLocker setVectorDirAndUp [_vDir, _vUp];
_localLocker allowDamage false;
_localLocker setVariable ["isLocker", true];
clearBackpackCargo _localLocker;
clearItemCargo _localLocker;
clearMagazineCargo _localLocker;
clearWeaponCargo _localLocker;
private _localVarName = format ["FORGE_Locker_Local_%1", _forEachIndex];
_localLocker setVehicleVarName _localVarName;
missionNamespace setVariable [_localVarName, _localLocker];
_self call ["setEventHandlers", [_localLocker]];
} forEach _lockers;
}],
["sync", { ["sync", {
params [["_data", createHashMap, [createHashMap]]]; params [["_data", createHashMap, [createHashMap]]];
private _locker = _self get "locker";
private _isLoaded = _self get "isLoaded"; private _isLoaded = _self get "isLoaded";
private _locker = _self get "locker";
if (_data isEqualTo createHashMap) exitWith { diag_log "[FORGE:Client:Locker] Empty data received for sync, skipping."; }; if (_data isEqualTo createHashMap) exitWith { diag_log "[FORGE:Client:Locker] Empty data received for sync, skipping."; };
{ _locker set [_x, _y]; } forEach _data; { _locker set [_x, _y]; } forEach _data;
_self set ["locker", _locker]; if !(_isLoaded) then { _self set ["isLoaded", true]; _self call ["setup", []]; };
if !(_isLoaded) then { _self set ["isLoaded", true]; };
diag_log "[FORGE:Client:Locker] Sync completed"; diag_log "[FORGE:Client:Locker] Sync completed";
}], }]
["get", { ];
params [["_key", "", [""]], ["_default", nil, [[], "", 0, false, createHashMap]]];
private _locker = _self get "locker"; GVAR(LockerClass) = createHashMapObject [[
_locker getOrDefault [_key, _default]; ["#base", GVAR(LockerRepository)],
["#type", "ILockerClass"],
["#create", {
_self set ["uid", (getPlayerUID player)];
_self set ["isLoaded", false];
_self set ["lastSave", time];
_self set ["locker", createHashMap];
}],
["init", {
private _uid = _self get "uid";
[SRPC(locker,requestInitLocker), [_uid]] call CFUNC(serverEvent);
systemChat format ["Locker loaded for %1", (name player)];
diag_log "[FORGE:Client:Locker] Locker Class Initialized!";
}] }]
]]; ]];

View File

@ -4,7 +4,7 @@
* File: fnc_initVAClass.sqf * File: fnc_initVAClass.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2025-12-16 * Date: 2025-12-16
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -18,7 +18,7 @@
* vArsenal class object [HASHMAP OBJECT] * vArsenal class object [HASHMAP OBJECT]
* *
* Example: * Example:
* [] call forge_client_locker_fnc_initVAClass; * call forge_client_locker_fnc_initVAClass;
*/ */
#pragma hemtt ignore_variables ["_self"] #pragma hemtt ignore_variables ["_self"]
@ -32,9 +32,8 @@ GVAR(VArsenalClass) = createHashMapObject [[
}], }],
["init", { ["init", {
private _uid = _self get "uid"; private _uid = _self get "uid";
private _vArsenal = _self get "vArsenal";
[SRPC(locker,requestInitVA), [_uid, _vArsenal]] call CFUNC(serverEvent); [SRPC(locker,requestInitVA), [_uid]] call CFUNC(serverEvent);
FORGE_Locker_Box = "ReammoBox_F" createVehicleLocal [0, 0, -999]; FORGE_Locker_Box = "ReammoBox_F" createVehicleLocal [0, 0, -999];
systemChat format ["VArsenal loaded for %1", (name player)]; systemChat format ["VArsenal loaded for %1", (name player)];

View File

@ -1,21 +0,0 @@
#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 locker interaction interface.
*
* Arguments:
* None
*
* Return Value:
* UI opened [BOOL]
*
* Example:
* [] call forge_client_locker_fnc_openUI;
*/

View File

@ -4,8 +4,8 @@
EGVAR(actor,ActorClass) get "isLoaded"; EGVAR(actor,ActorClass) get "isLoaded";
}, { }, {
("NotificationHudLayer" call BFUNC(rscLayer)) cutRsc ["RscNotifications", "PLAIN"]; ("NotificationHudLayer" call BFUNC(rscLayer)) cutRsc ["RscNotifications", "PLAIN"];
[] call FUNC(openUI); call FUNC(openUI);
if (isNil QGVAR(NotificationClass)) then { [] call FUNC(initNotificationClass); }; if (isNil QGVAR(NotificationClass)) then { call FUNC(initNotificationClass); };
}] call CFUNC(waitUntilAndExecute); }] call CFUNC(waitUntilAndExecute);
[QGVAR(recieveNotification), { [QGVAR(recieveNotification), {

View File

@ -4,7 +4,7 @@
* File: fnc_handleUIEvents.sqf * File: fnc_handleUIEvents.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2026-01-28 * Date: 2026-01-28
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -19,7 +19,7 @@
* UI events handled [BOOL] * UI events handled [BOOL]
* *
* Example: * Example:
* [] call forge_client_notifications_fnc_handleUIEvents; * call forge_client_notifications_fnc_handleUIEvents;
*/ */
params ["_control", "_isConfirmDialog", "_message"]; params ["_control", "_isConfirmDialog", "_message"];

View File

@ -4,7 +4,7 @@
* File: fnc_initNotificationClass.sqf * File: fnc_initNotificationClass.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2026-01-28 * Date: 2026-01-28
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -18,7 +18,7 @@
* Notification class object [HASHMAP OBJECT] * Notification class object [HASHMAP OBJECT]
* *
* Example: * Example:
* [] call forge_client_notifications_fnc_initNotificationClass * call forge_client_notifications_fnc_initNotificationClass
*/ */
#pragma hemtt ignore_variables ["_self"] #pragma hemtt ignore_variables ["_self"]

View File

@ -4,7 +4,7 @@
* File: fnc_openUI.sqf * File: fnc_openUI.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2026-01-28 * Date: 2026-01-28
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -17,7 +17,7 @@
* UI opened [BOOL] * UI opened [BOOL]
* *
* Example: * Example:
* [] call forge_client_notifications_fnc_openUI; * call forge_client_notifications_fnc_openUI;
*/ */
private _display = uiNamespace getVariable ["RscNotifications", nil]; private _display = uiNamespace getVariable ["RscNotifications", nil];

View File

@ -1,6 +1,6 @@
#include "script_component.hpp" #include "script_component.hpp"
if (isNil QGVAR(OrgClass)) then { [] call FUNC(initOrgClass); }; if (isNil QGVAR(OrgClass)) then { call FUNC(initOrgClass); };
[QGVAR(initOrg), { [QGVAR(initOrg), {
GVAR(OrgClass) call ["init", []]; GVAR(OrgClass) call ["init", []];

View File

@ -11,7 +11,7 @@
* None * None
* *
* Example: * Example:
* [] call forge_client_org_fnc_handleUIEvents; * call forge_client_org_fnc_handleUIEvents;
* *
* Public: No * Public: No
*/ */

View File

@ -11,7 +11,7 @@
* None * None
* *
* Examples: * Examples:
* [] call forge_client_org_fnc_initOrgClass * call forge_client_org_fnc_initOrgClass
* *
* Public: Yes * Public: Yes
*/ */

View File

@ -11,13 +11,13 @@
* None * None
* *
* Example: * Example:
* [] call forge_client_org_fnc_openUI; * call forge_client_org_fnc_openUI;
* *
* Public: No * Public: No
*/ */
private _display = (findDisplay 46) createDisplay "RscOrg"; private _display = createDialog ["RscOrg", true];
private _ctrl = (_display displayCtrl 1003); private _ctrl = _display displayCtrl 1003;
_ctrl ctrlAddEventHandler ["JSDialog", { _ctrl ctrlAddEventHandler ["JSDialog", {
params ["_control", "_isConfirmDialog", "_message"]; params ["_control", "_isConfirmDialog", "_message"];

View File

@ -10,7 +10,7 @@
* None * None
* *
* Example: * Example:
* [] call forge_client_addonName_fnc_empty; * call forge_client_addonName_fnc_empty;
* *
* Public: No * Public: No
*/ */

View File

@ -4,7 +4,7 @@
* File: fnc_initActorStore.sqf * File: fnc_initActorStore.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2025-12-17 * Date: 2025-12-17
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: Yes * Public: Yes
* *
* Description: * Description:
@ -18,7 +18,7 @@
* Actor store object [HASHMAP OBJECT] * Actor store object [HASHMAP OBJECT]
* *
* Example: * Example:
* [] call forge_server_actor_fnc_initActorStore * call forge_server_actor_fnc_initActorStore
*/ */
#pragma hemtt ignore_variables ["_self"] #pragma hemtt ignore_variables ["_self"]

View File

@ -4,7 +4,7 @@
* File: fnc_initBankStore.sqf * File: fnc_initBankStore.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2025-12-17 * Date: 2025-12-17
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: Yes * Public: Yes
* *
* Description: * Description:
@ -18,7 +18,7 @@
* Bank store object [HASHMAP OBJECT] * Bank store object [HASHMAP OBJECT]
* *
* Example: * Example:
* [] call forge_server_bank_fnc_initBankStore * call forge_server_bank_fnc_initBankStore
*/ */
#pragma hemtt ignore_variables ["_self"] #pragma hemtt ignore_variables ["_self"]

View File

@ -4,7 +4,7 @@
* File: fnc_baseStore.sqf * File: fnc_baseStore.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2026-01-08 * Date: 2026-01-08
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -17,7 +17,7 @@
* Base store [HASHMAP] * Base store [HASHMAP]
* *
* Example: * Example:
* [] call forge_x_component_fnc_myFunction * call forge_x_component_fnc_myFunction
*/ */
#pragma hemtt ignore_variables ["_self"] #pragma hemtt ignore_variables ["_self"]

View File

@ -6,9 +6,9 @@ PREP_RECOMPILE_END;
// private _category = [QUOTE(MOD_NAME), LLSTRING(displayName)]; // private _category = [QUOTE(MOD_NAME), LLSTRING(displayName)];
if (isNil QGVAR(MEconomyStore)) then { [] call FUNC(initMEconomyStore); }; if (isNil QGVAR(MEconomyStore)) then { call FUNC(initMEconomyStore); };
if (isNil QGVAR(FEconomyStore)) then { [] call FUNC(initFEconomyStore); }; if (isNil QGVAR(FEconomyStore)) then { call FUNC(initFEconomyStore); };
// if (isNil QGVAR(SEconomyStore)) then { [] call FUNC(initSEconomyStore); }; // if (isNil QGVAR(SEconomyStore)) then { call FUNC(initSEconomyStore); };
[QGVAR(FuelStart), { [QGVAR(FuelStart), {
params ["_source", "_target", "_unit"]; params ["_source", "_target", "_unit"];

View File

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

View File

@ -1,3 +1,3 @@
#include "script_component.hpp" #include "script_component.hpp"
[] call FUNC(initGarage); call FUNC(initGarage);

View File

@ -7,10 +7,10 @@ PREP_RECOMPILE_END;
// private _category = [QUOTE(MOD_NAME), LLSTRING(displayName)]; // private _category = [QUOTE(MOD_NAME), LLSTRING(displayName)];
[QGVAR(requestInitGarage), { [QGVAR(requestInitGarage), {
params [["_uid", "", [""]], ["_garage", createHashMap, [createHashMap]]]; params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Garage] Empty/Invalid UID!" }; if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Garage] Empty/Invalid UID!" };
GVAR(GarageStore) call ["init", [_uid, _garage]]; GVAR(GarageStore) call ["init", [_uid]];
}] call CFUNC(addEventHandler); }] call CFUNC(addEventHandler);
[QGVAR(requestGetGarage), { [QGVAR(requestGetGarage), {
@ -62,12 +62,10 @@ PREP_RECOMPILE_END;
}] call CFUNC(addEventHandler); }] call CFUNC(addEventHandler);
[QGVAR(requestInitVG), { [QGVAR(requestInitVG), {
params [["_uid", "", [""]], ["_vGarage", createHashMap, [createHashMap]]]; params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:VGarage] Empty/Invalid UID!" }; if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:VGarage] Empty/Invalid UID!" };
if (_vGarage isEqualTo createHashMap) exitWith { diag_log "[FORGE:Server:VGarage] Empty/Invalid VGarage data!" }; GVAR(VGarageStore) call ["init", [_uid]];
GVAR(VGarageStore) call ["init", [_uid, _vGarage]];
}] call CFUNC(addEventHandler); }] call CFUNC(addEventHandler);
[QGVAR(requestGetVG), { [QGVAR(requestGetVG), {

View File

@ -4,7 +4,7 @@
* File: fnc_initGarage.sqf * File: fnc_initGarage.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2025-12-17 * Date: 2025-12-17
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -17,7 +17,7 @@
* None * None
* *
* Example: * Example:
* [] call forge_server_garage_fnc_initGarage * call forge_server_garage_fnc_initGarage
*/ */
// TODO: Refactor to read from placed objects and their variables instead of missionConfig entries. // TODO: Refactor to read from placed objects and their variables instead of missionConfig entries.

View File

@ -4,7 +4,7 @@
* File: fnc_initGarageStore.sqf * File: fnc_initGarageStore.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2025-12-17 * Date: 2025-12-17
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -18,7 +18,7 @@
* Garage store object [HASHMAP OBJECT] * Garage store object [HASHMAP OBJECT]
* *
* Example: * Example:
* [] call forge_server_garage_fnc_initGarageStore * call forge_server_garage_fnc_initGarageStore
*/ */
#pragma hemtt ignore_variables ["_self"] #pragma hemtt ignore_variables ["_self"]

View File

@ -4,7 +4,7 @@
* File: fnc_initVGStore.sqf * File: fnc_initVGStore.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2025-12-17 * Date: 2025-12-17
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -18,7 +18,7 @@
* VG store object [HASHMAP OBJECT] * VG store object [HASHMAP OBJECT]
* *
* Example: * Example:
* [] call forge_server_garage_fnc_initVGStore * call forge_server_garage_fnc_initVGStore
*/ */
#pragma hemtt ignore_variables ["_self"] #pragma hemtt ignore_variables ["_self"]

View File

@ -1,3 +1,3 @@
#include "script_component.hpp" #include "script_component.hpp"
[] call FUNC(initLocker); call FUNC(initLocker);

View File

@ -7,10 +7,10 @@ PREP_RECOMPILE_END;
// private _category = [QUOTE(MOD_NAME), LLSTRING(displayName)]; // private _category = [QUOTE(MOD_NAME), LLSTRING(displayName)];
[QGVAR(requestInitLocker), { [QGVAR(requestInitLocker), {
params [["_uid", "", [""]], ["_locker", createHashMap, [createHashMap]]]; params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Locker] Empty/Invalid UID!" }; if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Locker] Empty/Invalid UID!" };
GVAR(LockerStore) call ["init", [_uid, _locker]]; GVAR(LockerStore) call ["init", [_uid]];
}] call CFUNC(addEventHandler); }] call CFUNC(addEventHandler);
[QGVAR(requestGetLocker), { [QGVAR(requestGetLocker), {
@ -54,6 +54,16 @@ PREP_RECOMPILE_END;
[CRPC(locker,responseSyncLocker), [_finalData], _player] call CFUNC(targetEvent); [CRPC(locker,responseSyncLocker), [_finalData], _player] call CFUNC(targetEvent);
}] call CFUNC(addEventHandler); }] call CFUNC(addEventHandler);
[QGVAR(requestOverrideLocker), {
params [["_uid", "", [""]], ["_data", createHashMap, [createHashMap]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Locker] Empty/Invalid UID!" };
GVAR(LockerRegistry) set [_uid, _data];
private _player = [_uid] call EFUNC(common,getPlayer);
[CRPC(locker,responseSyncLocker), [_data], _player] call CFUNC(targetEvent);
}] call CFUNC(addEventHandler);
[QGVAR(requestRemoveLocker), { [QGVAR(requestRemoveLocker), {
params [["_uid", "", [""]]]; params [["_uid", "", [""]]];
@ -62,22 +72,16 @@ PREP_RECOMPILE_END;
}] call CFUNC(addEventHandler); }] call CFUNC(addEventHandler);
[QGVAR(requestInitVA), { [QGVAR(requestInitVA), {
params [["_uid", "", [""]], ["_vArsenal", createHashMap, [createHashMap]]]; params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid UID!" }; if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid UID!" };
if (_vArsenal isEqualTo createHashMap) exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid VArsenal data!" }; GVAR(VArsenalStore) call ["init", [_uid]];
GVAR(VArsenalStore) call ["init", [_uid, _vArsenal]];
}] call CFUNC(addEventHandler); }] call CFUNC(addEventHandler);
[QGVAR(requestGetVA), { [QGVAR(requestGetVA), {
params [["_uid", "", [""]]]; params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid 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]]; GVAR(VArsenalStore) call ["get", [GVAR(VArsenalRegistry), "owned:locker:fetch", _uid]];
}] call CFUNC(addEventHandler); }] call CFUNC(addEventHandler);
@ -86,9 +90,6 @@ PREP_RECOMPILE_END;
if (_uid isEqualTo "" || _key isEqualTo "") exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid UID or Key!" }; if (_uid isEqualTo "" || _key isEqualTo "") exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid UID or Key!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid Session!" };
private _hashMap = GVAR(VArsenalStore) call ["set", [GVAR(VArsenalRegistry), "owned:locker:update", _uid, _key, _value, _sync]]; private _hashMap = GVAR(VArsenalStore) call ["set", [GVAR(VArsenalRegistry), "owned:locker:update", _uid, _key, _value, _sync]];
private _player = [_uid] call EFUNC(common,getPlayer); private _player = [_uid] call EFUNC(common,getPlayer);
@ -101,9 +102,6 @@ PREP_RECOMPILE_END;
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid UID!" }; if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid UID!" };
if ((_fieldValuePairs isEqualTo createHashMap) || !(_fieldValuePairs isEqualType createHashMap)) exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid field pairs!" }; if ((_fieldValuePairs isEqualTo createHashMap) || !(_fieldValuePairs isEqualType createHashMap)) exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid field pairs!" };
private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil];
if (isNil "_session") exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid Session!" };
private _hashMap = GVAR(VArsenalStore) call ["mset", [GVAR(VArsenalRegistry), "owned:locker:update", _uid, _fieldValuePairs, _sync]]; private _hashMap = GVAR(VArsenalStore) call ["mset", [GVAR(VArsenalRegistry), "owned:locker:update", _uid, _fieldValuePairs, _sync]];
private _player = [_uid] call EFUNC(common,getPlayer); private _player = [_uid] call EFUNC(common,getPlayer);
@ -115,9 +113,6 @@ PREP_RECOMPILE_END;
if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid 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]]; private _finalData = GVAR(VArsenalStore) call ["save", [GVAR(VArsenalRegistry), "owned:locker:update", _uid]];
private _player = [_uid] call EFUNC(common,getPlayer); private _player = [_uid] call EFUNC(common,getPlayer);

View File

@ -4,11 +4,12 @@
* File: fnc_initLocker.sqf * File: fnc_initLocker.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2025-12-17 * Date: 2025-12-17
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
* Initializes all lockers defined in the mission configuration. * Initializes lockers by hiding editor-placed global locker objects.
* Each client will create their own local instance.
* *
* Arguments: * Arguments:
* None * None
@ -17,69 +18,20 @@
* None * None
* *
* Example: * Example:
* [] call forge_server_locker_fnc_initLocker * call forge_server_locker_fnc_initLocker
*/ */
// TODO: Refactor to read from placed objects and their variables instead of missionConfig entries. private _lockers = (allVariables missionNamespace) select {
private _var = missionNamespace getVariable _x;
("locker" in _x) && { _var isEqualType objNull } && { !isNull _var } && { _x isNotEqualTo "forge_locker_box" }
};
private _mC = "FORGE_CfgLockers"; if (_lockers isEqualTo []) exitWith { diag_log "[FORGE:Server:Locker] No editor-placed lockers found."; };
private _lockers = "true" configClasses (missionConfigFile >> "FORGE_CfgLockers" >> "lockers"); diag_log format ["[FORGE:Server:Locker] Found %1 editor-placed locker(s), hiding globally", count _lockers];
{ {
private _configName = configName(_x); private _locker = missionNamespace getVariable _x;
private _className = (missionConfigFile >> _mC >> "lockers" >> _configName >> "className") call BFUNC(getCfgData); _locker hideObjectGlobal true;
private _pos = (missionConfigFile >> _mC >> "lockers" >> _configName >> "pos") call BFUNC(getCfgData);
private _dir = (missionConfigFile >> _mC >> "lockers" >> _configName >> "dir") call BFUNC(getCfgData);
private _locker = createVehicle [_className, [0, 0, 0]]; diag_log format ["[FORGE:Server:Locker] Hidden locker: %1 at position %2", _x, getPosASL _locker];
// 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];
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; } forEach _lockers;

View File

@ -4,7 +4,7 @@
* File: fnc_initLockerStore.sqf * File: fnc_initLockerStore.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2025-12-17 * Date: 2025-12-17
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -18,7 +18,7 @@
* Locker store object [HASHMAP OBJECT] * Locker store object [HASHMAP OBJECT]
* *
* Example: * Example:
* [] call forge_server_locker_fnc_initLockerStore * call forge_server_locker_fnc_initLockerStore
*/ */
#pragma hemtt ignore_variables ["_self"] #pragma hemtt ignore_variables ["_self"]

View File

@ -4,7 +4,7 @@
* File: fnc_initVAStore.sqf * File: fnc_initVAStore.sqf
* Author: IDSolutions * Author: IDSolutions
* Date: 2025-12-17 * Date: 2025-12-17
* Last Update: 2026-01-28 * Last Update: 2026-01-30
* Public: No * Public: No
* *
* Description: * Description:
@ -18,7 +18,7 @@
* VA store object [HASHMAP OBJECT] * VA store object [HASHMAP OBJECT]
* *
* Example: * Example:
* [] call forge_server_locker_fnc_initVAStore * call forge_server_locker_fnc_initVAStore
*/ */
#pragma hemtt ignore_variables ["_self"] #pragma hemtt ignore_variables ["_self"]

View File

@ -1,3 +1,3 @@
#include "script_component.hpp" #include "script_component.hpp"
[] call FUNC(initStores); call FUNC(initStores);

View File

@ -11,31 +11,31 @@
* None * None
* *
* Example: * Example:
* [] call forge_server_main_fnc_initStores; * call forge_server_main_fnc_initStores;
* *
* Public: No * Public: No
*/ */
// Base // Base
if (isNil QEGVAR(common,BaseStore)) then { [] call EFUNC(common,baseStore); }; if (isNil QEGVAR(common,BaseStore)) then { call EFUNC(common,baseStore); };
// Actor // Actor
if (isNil QEGVAR(actor,ActorStore)) then { [] call EFUNC(actor,initActorStore); }; if (isNil QEGVAR(actor,ActorStore)) then { call EFUNC(actor,initActorStore); };
// Bank // Bank
if (isNil QEGVAR(bank,BankStore)) then { [] call EFUNC(bank,initBankStore); }; if (isNil QEGVAR(bank,BankStore)) then { call EFUNC(bank,initBankStore); };
// Garage // Garage
if (isNil QEGVAR(garage,GarageStore)) then { [] call EFUNC(garage,initGarageStore); }; if (isNil QEGVAR(garage,GarageStore)) then { call EFUNC(garage,initGarageStore); };
// VGarage // VGarage
if (isNil QEGVAR(garage,VGarageStore)) then { [] call EFUNC(garage,initVGStore); }; if (isNil QEGVAR(garage,VGarageStore)) then { call EFUNC(garage,initVGStore); };
// Locker // Locker
if (isNil QEGVAR(locker,LockerStore)) then { [] call EFUNC(locker,initLockerStore); }; if (isNil QEGVAR(locker,LockerStore)) then { call EFUNC(locker,initLockerStore); };
// VArsenal // VArsenal
if (isNil QEGVAR(locker,VArsenalStore)) then { [] call EFUNC(locker,initVAStore); }; if (isNil QEGVAR(locker,VArsenalStore)) then { call EFUNC(locker,initVAStore); };
// Org // Org
if (isNil QEGVAR(org,OrgStore)) then { [] call EFUNC(org,initOrgStore); }; if (isNil QEGVAR(org,OrgStore)) then { call EFUNC(org,initOrgStore); };

View File

@ -11,7 +11,7 @@
* None * None
* *
* Examples: * Examples:
* [] call forge_server_org_fnc_initOrgStore * call forge_server_org_fnc_initOrgStore
* *
* Public: Yes * Public: Yes
*/ */
@ -63,9 +63,9 @@ GVAR(OrgStore) = createHashMapObject [[
// _finalOrg set ["assets", _assets]; // _finalOrg set ["assets", _assets];
GVAR(OrgRegistry) set [_orgID, _finalOrg, true]; GVAR(OrgRegistry) set [_orgID, _finalOrg, true];
[CRPC(org,responseInitOrg), [_finalOrg], _player] call CFUNC(targetEvent); [CRPC(org,responseInitOrg), [_finalOrg], _player] call CFUNC(targetEvent);
["INFO", format ["Found org for %1", _uid], nil, nil] call EFUNC(common,log);
_finalOrg _finalOrg
}], }],
["default", { ["default", {

View File

@ -23,6 +23,10 @@ pub struct VGarage {
impl VGarage { impl VGarage {
pub fn new() -> Self { pub fn new() -> Self {
Self::default_unlocks()
}
fn default_unlocks() -> Self {
Self { Self {
cars: vec!["B_Quadbike_01_F".to_string()], cars: vec!["B_Quadbike_01_F".to_string()],
armor: Vec::new(), armor: Vec::new(),

View File

@ -19,6 +19,10 @@ pub struct VLocker {
impl VLocker { impl VLocker {
pub fn new() -> Self { pub fn new() -> Self {
Self::default_unlocks()
}
fn default_unlocks() -> Self {
Self { Self {
items: vec![ items: vec![
"FirstAidKit".to_string(), "FirstAidKit".to_string(),