Compare commits
37 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
71438fe393 | ||
![]() |
39d080fca5 | ||
![]() |
b5bd3c6cb8 | ||
![]() |
209b243620 | ||
![]() |
73086cfe97 | ||
![]() |
a106fef2fd | ||
![]() |
0858d9a173 | ||
![]() |
9f672e1795 | ||
![]() |
9936d6ddc3 | ||
![]() |
dfaddaa279 | ||
![]() |
2b5648b303 | ||
![]() |
3ba3fe82d2 | ||
![]() |
201371a411 | ||
![]() |
635460f9d8 | ||
![]() |
86ae5c4248 | ||
![]() |
be8e19a1a7 | ||
![]() |
58eb7bf841 | ||
![]() |
3ab612fad1 | ||
![]() |
d171b02d65 | ||
![]() |
4c9c2bd755 | ||
![]() |
0cbe027b3b | ||
![]() |
48c45731b7 | ||
![]() |
40eccaed69 | ||
![]() |
c822d4e601 | ||
![]() |
af39d7e528 | ||
![]() |
d474b3676a | ||
![]() |
4c33bd9175 | ||
![]() |
f8391463b2 | ||
![]() |
94684cb120 | ||
![]() |
dc17412660 | ||
![]() |
ef3c080556 | ||
![]() |
53905e9b69 | ||
![]() |
0ed1bc3a19 | ||
![]() |
90476345db | ||
![]() |
65d9154c09 | ||
![]() |
1828673c6b | ||
![]() |
643276d4ff |
@ -1,7 +1,7 @@
|
|||||||
# Forge Admin Module
|
# Forge Admin Module
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
The Admin module provides administrative functionality for the Forge client system. It includes features for user management, messaging, and administrative controls.
|
The Admin module provides comprehensive administrative functionality for the Forge client system. It includes features for user management, financial operations, messaging, and administrative controls through both traditional and web-based interfaces.
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
- forge_client_main
|
- forge_client_main
|
||||||
@ -18,9 +18,13 @@ The Admin module provides administrative functionality for the Forge client syst
|
|||||||
- Initializes the admin system
|
- Initializes the admin system
|
||||||
- Sets up necessary permissions and configurations
|
- Sets up necessary permissions and configurations
|
||||||
|
|
||||||
2. **Admin Interface** (`fnc_openAdmin.sqf`)
|
2. **Admin Interface**
|
||||||
|
- **Traditional UI** (`fnc_openAdmin.sqf`)
|
||||||
- Opens the administrative user interface
|
- Opens the administrative user interface
|
||||||
- Provides access to administrative controls
|
- Provides access to administrative controls
|
||||||
|
- **Web-based UI** (`RscWebAdmin.hpp`)
|
||||||
|
- Modern web interface for administrative tasks
|
||||||
|
- Real-time player statistics and management
|
||||||
|
|
||||||
3. **User Management**
|
3. **User Management**
|
||||||
- **Promotion** (`fnc_adminPromote.sqf`)
|
- **Promotion** (`fnc_adminPromote.sqf`)
|
||||||
@ -30,16 +34,36 @@ The Admin module provides administrative functionality for the Forge client syst
|
|||||||
- **Refresh** (`fnc_adminRefresh.sqf`)
|
- **Refresh** (`fnc_adminRefresh.sqf`)
|
||||||
- Updates administrative permissions and states
|
- Updates administrative permissions and states
|
||||||
|
|
||||||
4. **Communication**
|
4. **Financial Operations**
|
||||||
|
- **Payday System**
|
||||||
|
- Distributes funds based on player ranks
|
||||||
|
- Configurable paygrade amounts
|
||||||
|
- **Money Management**
|
||||||
|
- Advance funds to players
|
||||||
|
- Deduct funds from players
|
||||||
|
- Global money distribution
|
||||||
|
- Company account balance tracking
|
||||||
|
|
||||||
|
5. **Communication**
|
||||||
- **Admin Messages** (`fnc_adminMessage.sqf`)
|
- **Admin Messages** (`fnc_adminMessage.sqf`)
|
||||||
- Handles administrative messaging system
|
- Handles administrative messaging system
|
||||||
|
- **Broadcast System**
|
||||||
|
- Send messages to all players
|
||||||
|
- Targeted player messaging
|
||||||
|
|
||||||
### User Interface
|
### User Interface Components
|
||||||
The module includes two main UI components:
|
1. **Traditional UI** (`RscAdmin.hpp`)
|
||||||
1. **RscCommon.hpp**
|
- Player list management
|
||||||
- Common UI elements and definitions
|
- Rank selection and promotion
|
||||||
2. **RscAdmin.hpp**
|
- Financial operations
|
||||||
- Administrative interface specific elements
|
- Messaging system
|
||||||
|
|
||||||
|
2. **Web Interface** (`ui/_site/`)
|
||||||
|
- Modern, responsive design
|
||||||
|
- Real-time statistics
|
||||||
|
- Player management
|
||||||
|
- Financial operations
|
||||||
|
- Messaging system
|
||||||
|
|
||||||
## Event Handlers
|
## Event Handlers
|
||||||
The module uses several event handlers for initialization and execution:
|
The module uses several event handlers for initialization and execution:
|
||||||
@ -50,7 +74,9 @@ The module uses several event handlers for initialization and execution:
|
|||||||
## Usage
|
## Usage
|
||||||
To use the admin module:
|
To use the admin module:
|
||||||
1. Ensure the module is properly loaded in your mission
|
1. Ensure the module is properly loaded in your mission
|
||||||
2. Access administrative functions through the provided UI
|
2. Access administrative functions through either:
|
||||||
|
- Traditional UI: Use the provided dialog interface
|
||||||
|
- Web Interface: Access through the modern web-based panel
|
||||||
3. Use appropriate administrative commands based on your role
|
3. Use appropriate administrative commands based on your role
|
||||||
|
|
||||||
## Debugging
|
## Debugging
|
||||||
@ -61,3 +87,17 @@ Debug mode can be enabled by uncommenting the following in `script_component.hpp
|
|||||||
|
|
||||||
## Version Information
|
## Version Information
|
||||||
Version information is managed through the main Forge client system configuration.
|
Version information is managed through the main Forge client system configuration.
|
||||||
|
|
||||||
|
## Security
|
||||||
|
The module includes built-in security features:
|
||||||
|
- Admin authentication
|
||||||
|
- Permission-based access control
|
||||||
|
- Secure financial transactions
|
||||||
|
- Protected administrative functions
|
||||||
|
|
||||||
|
## Technical Details
|
||||||
|
- Supports both traditional Arma 3 UI and modern web interface
|
||||||
|
- Real-time data updates
|
||||||
|
- Configurable paygrade system
|
||||||
|
- Comprehensive player management
|
||||||
|
- Secure financial operations
|
@ -1,6 +1,5 @@
|
|||||||
PREP(adminRefresh);
|
PREP(adminRefresh);
|
||||||
PREP(handleTransfer);
|
PREP(handleTransfer);
|
||||||
PREP(initAdmin);
|
|
||||||
PREP(openAdmin);
|
PREP(openAdmin);
|
||||||
PREP(sendMessage);
|
PREP(sendMessage);
|
||||||
PREP(updatePaygrade);
|
PREP(updatePaygrade);
|
@ -1,96 +1 @@
|
|||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
[QGVAR(handleEvents), {
|
|
||||||
params ["_control", "_isConfirmDialog", "_message"];
|
|
||||||
|
|
||||||
diag_log format ["[FORGE: Admin] Received event: %1", _message];
|
|
||||||
|
|
||||||
_message = fromJSON _message;
|
|
||||||
private _event = _message get "event";
|
|
||||||
private _data = _message get "data";
|
|
||||||
|
|
||||||
switch (_event) do {
|
|
||||||
case "REQUEST_PLAYER_DATA": {
|
|
||||||
private _playerData = createHashMap;
|
|
||||||
private _playerList = [];
|
|
||||||
|
|
||||||
{
|
|
||||||
private _player = _x;
|
|
||||||
private _uid = getPlayerUID _player;
|
|
||||||
private _name = name _player;
|
|
||||||
private _paygrade = GETVAR(_player,FORGE_PayGrade,QUOTE(E1));
|
|
||||||
private _funds = GETVAR(_player,FORGE_Bank,0);
|
|
||||||
|
|
||||||
private _playerInfo = createHashMapFromArray [
|
|
||||||
["uid", _uid],
|
|
||||||
["name", _name],
|
|
||||||
["paygrade", _paygrade],
|
|
||||||
["funds", _funds],
|
|
||||||
["side", str (side _player)]
|
|
||||||
];
|
|
||||||
|
|
||||||
_playerList pushBack _playerInfo;
|
|
||||||
} forEach allPlayers;
|
|
||||||
|
|
||||||
_playerData set ["players", _playerList];
|
|
||||||
_control ctrlWebBrowserAction ["ExecJS", format ["handlePlayerDataRequest(%1)", (toJSON _playerList)]];
|
|
||||||
};
|
|
||||||
case "REQUEST_PAYGRADE_DATA": {
|
|
||||||
private _payGrades = (missionConfigFile >> "CfgPaygrades" >> "payGrades") call BIS_fnc_getCfgData;
|
|
||||||
private _paygradeData = createHashMap;
|
|
||||||
private _paygradeList = [];
|
|
||||||
|
|
||||||
{
|
|
||||||
private _paygradeInfo = createHashMapFromArray [
|
|
||||||
["paygrade", _x select 0],
|
|
||||||
["bonus", _x select 1]
|
|
||||||
];
|
|
||||||
|
|
||||||
_paygradeList pushBack _paygradeInfo;
|
|
||||||
} forEach _payGrades;
|
|
||||||
|
|
||||||
_paygradeData set ["paygrades", _paygradeList];
|
|
||||||
_control ctrlWebBrowserAction ["ExecJS", format ["handlePaygradeDataRequest(%1)", (toJSON _paygradeList)]];
|
|
||||||
};
|
|
||||||
case "BROADCAST_MESSAGE": {
|
|
||||||
_data params ["_uid", "_message"];
|
|
||||||
|
|
||||||
if ((isNil "_message") || {_message isEqualTo ""}) exitWith { hintSilent "Message cannot be empty!"; };
|
|
||||||
|
|
||||||
["forge_server_admin_handleEvents", ["sendMessage", [_uid, _message]]] call CFUNC(serverEvent);
|
|
||||||
};
|
|
||||||
case "SEND_MESSAGE": {
|
|
||||||
_data params ["_uid", "_message"];
|
|
||||||
|
|
||||||
if ((isNil "_uid") || {_uid isEqualTo ""}) exitWith { hintSilent "You did not select a player!"; };
|
|
||||||
|
|
||||||
["forge_server_admin_handleEvents", ["sendMessage", [_uid, _message]]] call CFUNC(serverEvent);
|
|
||||||
};
|
|
||||||
case "UPDATE_PAYGRADE": {
|
|
||||||
private _uid = _data select 0;
|
|
||||||
private _paygrade = _data select 1;
|
|
||||||
|
|
||||||
if ((isNil "_uid") || {_uid isEqualTo ""}) exitWith { hintSilent "You did not select a player!"; };
|
|
||||||
|
|
||||||
["forge_server_admin_handleEvents", ["updatePaygrade", [_uid, _paygrade]]] call CFUNC(serverEvent);
|
|
||||||
};
|
|
||||||
case "HANDLE_TRANSFER": {
|
|
||||||
private _condition = _data select 0;
|
|
||||||
private _amount = _data select 1;
|
|
||||||
private _uid = _data select 2;
|
|
||||||
|
|
||||||
["forge_server_admin_handleEvents", ["handleTransfer", [_condition, _amount, _uid]]] call CFUNC(serverEvent);
|
|
||||||
};
|
|
||||||
case "ADVANCE_ALL": {
|
|
||||||
private _amount = _data select 0;
|
|
||||||
|
|
||||||
["forge_server_admin_handleEvents", ["advanceAll", [_amount]]] call CFUNC(serverEvent);
|
|
||||||
};
|
|
||||||
case "HANDLE_PAYDAY": {
|
|
||||||
["forge_server_admin_handleEvents", ["handlePayday"]] call CFUNC(serverEvent);
|
|
||||||
};
|
|
||||||
default {
|
|
||||||
diag_log format ["[FORGE: Admin] Unhandled event: %1", _event];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}] call CFUNC(addEventHandler);
|
|
@ -1 +1,93 @@
|
|||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
[QGVAR(handleEvents), {
|
||||||
|
params ["_control", "_isConfirmDialog", "_message"];
|
||||||
|
|
||||||
|
diag_log format ["[FORGE::Client::Admin::XEH_postInit] Received event: %1", _message];
|
||||||
|
|
||||||
|
_message = fromJSON _message;
|
||||||
|
private _event = _message get "event";
|
||||||
|
private _data = _message get "data";
|
||||||
|
|
||||||
|
switch (_event) do {
|
||||||
|
case "REQUEST::PLAYER::DATA": {
|
||||||
|
private _playerData = createHashMap;
|
||||||
|
private _playerList = [];
|
||||||
|
|
||||||
|
{
|
||||||
|
private _player = _x;
|
||||||
|
private _uid = getPlayerUID _player;
|
||||||
|
private _name = name _player;
|
||||||
|
private _paygrade = GETVAR(_player,FORGE_PayGrade,QUOTE(E1)); //TODO: Implement paygrade from server
|
||||||
|
private _funds = GETVAR(_player,FORGE_Bank,0); //TODO: Implement funds from server
|
||||||
|
|
||||||
|
private _playerInfo = createHashMapFromArray [
|
||||||
|
["uid", _uid],
|
||||||
|
["name", _name],
|
||||||
|
["paygrade", _paygrade],
|
||||||
|
["funds", _funds],
|
||||||
|
["side", str (side _player)]
|
||||||
|
];
|
||||||
|
|
||||||
|
_playerList pushBack _playerInfo;
|
||||||
|
} forEach allPlayers;
|
||||||
|
|
||||||
|
_playerData set ["players", _playerList];
|
||||||
|
_control ctrlWebBrowserAction ["ExecJS", format ["handlePlayerDataRequest(%1)", (toJSON _playerList)]];
|
||||||
|
};
|
||||||
|
case "REQUEST::PAYGRADE::DATA": {
|
||||||
|
private _payGrades = (missionConfigFile >> "CfgPaygrades" >> "payGrades") call BIS_fnc_getCfgData;
|
||||||
|
private _paygradeData = createHashMap;
|
||||||
|
private _paygradeList = [];
|
||||||
|
|
||||||
|
{
|
||||||
|
private _paygradeInfo = createHashMapFromArray [
|
||||||
|
["paygrade", _x select 0],
|
||||||
|
["bonus", _x select 1]
|
||||||
|
];
|
||||||
|
|
||||||
|
_paygradeList pushBack _paygradeInfo;
|
||||||
|
} forEach _payGrades;
|
||||||
|
|
||||||
|
_paygradeData set ["paygrades", _paygradeList];
|
||||||
|
_control ctrlWebBrowserAction ["ExecJS", format ["handlePaygradeDataRequest(%1)", (toJSON _paygradeList)]];
|
||||||
|
};
|
||||||
|
case "BROADCAST::MESSAGE": {
|
||||||
|
_data params ["_uid", "_message"];
|
||||||
|
|
||||||
|
if ((isNil "_message") || {_message isEqualTo ""}) exitWith { systemChat "Message cannot be empty!"; };
|
||||||
|
|
||||||
|
["forge_server_admin_handleEvents", ["ADMIN::SEND::MESSAGE", [_uid, _message]]] call CFUNC(serverEvent);
|
||||||
|
};
|
||||||
|
case "SEND::MESSAGE": {
|
||||||
|
_data params ["_uid", "_message"];
|
||||||
|
|
||||||
|
if ((isNil "_uid") || {_uid isEqualTo ""}) exitWith { systemChat "You did not select a player!"; };
|
||||||
|
|
||||||
|
["forge_server_admin_handleEvents", ["ADMIN::SEND::MESSAGE", [_uid, _message]]] call CFUNC(serverEvent);
|
||||||
|
};
|
||||||
|
case "UPDATE::PAYGRADE": {
|
||||||
|
_data params ["_uid", "_paygrade"];
|
||||||
|
|
||||||
|
if ((isNil "_uid") || {_uid isEqualTo ""}) exitWith { systemChat "You did not select a player!"; };
|
||||||
|
|
||||||
|
["forge_server_admin_handleEvents", ["ADMIN::UPDATE::PAYGRADE", [_uid, _paygrade]]] call CFUNC(serverEvent);
|
||||||
|
};
|
||||||
|
case "HANDLE::TRANSFER": {
|
||||||
|
_data params ["_condition", "_amount", "_uid"];
|
||||||
|
|
||||||
|
["forge_server_admin_handleEvents", ["ADMIN::TRANSFER", [_condition, _amount, _uid]]] call CFUNC(serverEvent);
|
||||||
|
};
|
||||||
|
case "ADVANCE::ALL": {
|
||||||
|
_data params ["_amount"];
|
||||||
|
|
||||||
|
["forge_server_admin_handleEvents", ["ADMIN::ADVANCE::ALL", [_amount]]] call CFUNC(serverEvent);
|
||||||
|
};
|
||||||
|
case "HANDLE::PAYDAY": {
|
||||||
|
["forge_server_admin_handleEvents", ["ADMIN::PAYDAY"]] call CFUNC(serverEvent);
|
||||||
|
};
|
||||||
|
default {
|
||||||
|
diag_log format ["[FORGE::Client::Admin::XEH_postInit] Unhandled event: %1", _event];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}] call CFUNC(addEventHandler);
|
@ -1,14 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_admin_fnc_adminRefresh
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Refreshes the admin interface
|
||||||
* [Description]
|
|
||||||
* Refreshes the admin interface player list and resets input fields.
|
|
||||||
* This function populates the player list with names and paygrades,
|
|
||||||
* storing player UIDs as data for each entry. Only shows players
|
|
||||||
* on the same side as the admin.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: Dummy <ANY> - Optional parameter, not used (for compatibility with event handlers)
|
* 0: Dummy <ANY> - Optional parameter, not used (for compatibility with event handlers)
|
||||||
@ -20,10 +14,9 @@
|
|||||||
* [] call forge_client_admin_fnc_adminRefresh;
|
* [] call forge_client_admin_fnc_adminRefresh;
|
||||||
* ["dummy"] call forge_client_admin_fnc_adminRefresh;
|
* ["dummy"] call forge_client_admin_fnc_adminRefresh;
|
||||||
*
|
*
|
||||||
* Public: No - Called from admin dialog controls
|
* Public: No
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
private _dialog = findDisplay 202303;
|
private _dialog = findDisplay 202303;
|
||||||
private _list = _dialog displayCtrl 2023001;
|
private _list = _dialog displayCtrl 2023001;
|
||||||
|
|
||||||
|
@ -1,16 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_admin_fnc_handleTransfer
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Handles fund transfers
|
||||||
* [Description]
|
|
||||||
* Handles fund transfers through the admin interface.
|
|
||||||
* This function retrieves the selected player's UID and amount
|
|
||||||
* from the admin dialog, then sends it to the server-side admin store.
|
|
||||||
* Supports multiple transfer types: advance (to single player),
|
|
||||||
* deduct (from single player), advanceAll (to all players),
|
|
||||||
* and payday (distribute based on paygrade).
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: Condition <STRING> - The type of transfer to perform ("advance", "deduct", "advanceAll", "payday")
|
* 0: Condition <STRING> - The type of transfer to perform ("advance", "deduct", "advanceAll", "payday")
|
||||||
@ -33,8 +25,8 @@ private _index = lbCurSel _list;
|
|||||||
private _uid = _list lbData _index;
|
private _uid = _list lbData _index;
|
||||||
private _amount = round (parseNumber (ctrlText 2023005));
|
private _amount = round (parseNumber (ctrlText 2023005));
|
||||||
|
|
||||||
if (_condition in ["advance", "deduct"] && ((isNil "_uid") || { _uid isEqualTo "" })) exitWith { hint "You did not select a player!"; };
|
if ({_condition in ["advance", "deduct"]} && ((isNil "_uid") || { _uid isEqualTo "" })) exitWith { hint "You did not select a player!"; };
|
||||||
|
|
||||||
["forge_server_admin_handleEvents", ["handleTransfer", [_condition, _amount, _uid]]] call CFUNC(serverEvent);
|
["forge_server_admin_handleEvents", ["ADMIN::TRANSFER", [_condition, _amount, _uid]]] call CFUNC(serverEvent);
|
||||||
|
|
||||||
ctrlSetText [2023005, ""];
|
ctrlSetText [2023005, ""];
|
@ -1,37 +0,0 @@
|
|||||||
#include "..\script_component.hpp"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: forge_client_admin_fnc_initAdmin
|
|
||||||
* Author: IDSolutions
|
|
||||||
*
|
|
||||||
* [Description]
|
|
||||||
* Initializes the admin menu.
|
|
||||||
*
|
|
||||||
* Arguments:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
* Return Value:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
* Examples:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
* Public: No
|
|
||||||
*/
|
|
||||||
|
|
||||||
{
|
|
||||||
private _configName = configName(_x);
|
|
||||||
private _className = (missionConfigFile >> "CfgCpofs" >> "cpofs" >> _configName >> "className") call BFUNC(getCfgData);
|
|
||||||
private _pos = (missionConfigFile >> "CfgCpofs" >> "cpofs" >> _configName >> "pos") call BFUNC(getCfgData);
|
|
||||||
private _dir = (missionConfigFile >> "CfgCpofs" >> "cpofs" >> _configName >> "dir") call BFUNC(getCfgData);
|
|
||||||
|
|
||||||
private _cpof = createSimpleObject [_className, [0, 0, 0]];
|
|
||||||
|
|
||||||
_cpof setPosATL _pos;
|
|
||||||
_cpof setDir _dir;
|
|
||||||
_cpof allowDamage false;
|
|
||||||
_cpof setVariable ["isCPOF", true, true];
|
|
||||||
|
|
||||||
diag_log text format ["[FORGE Admin] ClassName: '%1' Pos: '%2' Dir: '%3'", _className, _pos, _dir];
|
|
||||||
|
|
||||||
} forEach ("true" configClasses (missionConfigFile >> "CfgCpofs" >> "cpofs"));
|
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_admin_fnc_openAdmin
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Opens the admin dialog.
|
||||||
* [Description]
|
|
||||||
* Opens the admin menu.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* None
|
* None
|
||||||
@ -13,8 +10,8 @@
|
|||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Examples:
|
* Example:
|
||||||
* None
|
* [] call forge_client_admin_fnc_openAdmin;
|
||||||
*
|
*
|
||||||
* Public: Yes
|
* Public: Yes
|
||||||
*/
|
*/
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_admin_fnc_sendMessage
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Sends a message to a selected player
|
||||||
* [Description]
|
|
||||||
* Sends a message to a selected player through the admin interface.
|
|
||||||
* This function retrieves the selected player's UID and message content
|
|
||||||
* from the admin dialog, then sends it to the server-side admin store.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* None
|
* None
|
||||||
@ -30,8 +25,6 @@ private _message = ctrlText _control;
|
|||||||
|
|
||||||
if ((isNil "_uid") || {_uid isEqualTo ""}) exitWith { hintSilent "You did not select a player!"; };
|
if ((isNil "_uid") || {_uid isEqualTo ""}) exitWith { hintSilent "You did not select a player!"; };
|
||||||
|
|
||||||
["forge_server_admin_handleEvents", ["sendMessage", [_uid, _message]]] call CFUNC(serverEvent);
|
["forge_server_admin_handleEvents", ["ADMIN::SEND::MESSAGE", [_uid, _message]]] call CFUNC(serverEvent);
|
||||||
|
|
||||||
hintSilent format ["Message sent to UID %1: %2", _uid, _message];
|
|
||||||
|
|
||||||
["dummy"] call FUNC(adminRefresh);
|
["dummy"] call FUNC(adminRefresh);
|
@ -1,13 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_admin_fnc_updatePaygrade
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Updates a player's paygrade
|
||||||
* [Description]
|
|
||||||
* Updates a player's paygrade in the server's admin store.
|
|
||||||
* This function retrieves the selected player's UID and the target paygrade
|
|
||||||
* from the admin dialog, then sends it to the server-side admin store.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* None
|
* None
|
||||||
@ -32,6 +27,6 @@ private _paygrade = _rankData select 0;
|
|||||||
|
|
||||||
if ((isNil "_uid") || {_uid isEqualTo ""}) exitWith { hintSilent "You did not select a player!" };
|
if ((isNil "_uid") || {_uid isEqualTo ""}) exitWith { hintSilent "You did not select a player!" };
|
||||||
|
|
||||||
["forge_server_admin_handleEvents", ["updatePaygrade", [_uid, _paygrade]]] call CFUNC(serverEvent);
|
["forge_server_admin_handleEvents", ["ADMIN::UPDATE::PAYGRADE", [_uid, _paygrade]]] call CFUNC(serverEvent);
|
||||||
|
|
||||||
["dummy"] call FUNC(adminRefresh);
|
["dummy"] call FUNC(adminRefresh);
|
@ -46,7 +46,7 @@ function initializeAdmin() {
|
|||||||
*/
|
*/
|
||||||
function requestPlayerData() {
|
function requestPlayerData() {
|
||||||
const message = {
|
const message = {
|
||||||
event: "REQUEST_PLAYER_DATA",
|
event: "REQUEST::PLAYER::DATA",
|
||||||
data: {}
|
data: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ function requestPlayerData() {
|
|||||||
*/
|
*/
|
||||||
function requestPaygradeData() {
|
function requestPaygradeData() {
|
||||||
const message = {
|
const message = {
|
||||||
event: "REQUEST_PAYGRADE_DATA",
|
event: "REQUEST::PAYGRADE::DATA",
|
||||||
data: {}
|
data: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ function requestPaygradeData() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up a timer to periodically refresh player data
|
* Set up a timer to periodically refresh player data
|
||||||
* Ensures the admin panel shows up-to-date information
|
* Ensures the UI is updated with the latest information
|
||||||
*/
|
*/
|
||||||
function setupRefreshTimer() {
|
function setupRefreshTimer() {
|
||||||
setInterval(requestPlayerData, 30000); // Refresh every 30 seconds
|
setInterval(requestPlayerData, 30000); // Refresh every 30 seconds
|
||||||
@ -286,7 +286,7 @@ function updatePaygrade(uid, isPromotion) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const message = {
|
const message = {
|
||||||
event: "UPDATE_PAYGRADE",
|
event: "UPDATE::PAYGRADE",
|
||||||
data: [uid, newPaygrade]
|
data: [uid, newPaygrade]
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -341,7 +341,7 @@ function giveMoney() {
|
|||||||
function giveAllMoney() {
|
function giveAllMoney() {
|
||||||
const amount = parseInt(document.getElementById('giveAllAmount').value);
|
const amount = parseInt(document.getElementById('giveAllAmount').value);
|
||||||
const message = {
|
const message = {
|
||||||
event: "ADVANCE_ALL",
|
event: "ADVANCE::ALL",
|
||||||
data: [amount]
|
data: [amount]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,7 +371,7 @@ function takeMoney() {
|
|||||||
*/
|
*/
|
||||||
function handleTransferFunds(condition, amount, uid) {
|
function handleTransferFunds(condition, amount, uid) {
|
||||||
const message = {
|
const message = {
|
||||||
event: "HANDLE_TRANSFER",
|
event: "HANDLE::TRANSFER",
|
||||||
data: [condition, amount, uid]
|
data: [condition, amount, uid]
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -425,7 +425,7 @@ function sendPlayerMessage() {
|
|||||||
const message = document.getElementById('messageInput').value;
|
const message = document.getElementById('messageInput').value;
|
||||||
if (message && selectedPlayerId) {
|
if (message && selectedPlayerId) {
|
||||||
const messageData = {
|
const messageData = {
|
||||||
event: "SEND_MESSAGE",
|
event: "SEND::MESSAGE",
|
||||||
data: [selectedPlayerId, message]
|
data: [selectedPlayerId, message]
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -441,7 +441,7 @@ function broadcastMessage() {
|
|||||||
const message = document.getElementById('broadcastMessage').value;
|
const message = document.getElementById('broadcastMessage').value;
|
||||||
if (message) {
|
if (message) {
|
||||||
const messageData = {
|
const messageData = {
|
||||||
event: "BROADCAST_MESSAGE",
|
event: "BROADCAST::MESSAGE",
|
||||||
data: ["", message]
|
data: ["", message]
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -461,7 +461,7 @@ function broadcastMessage() {
|
|||||||
*/
|
*/
|
||||||
function Payday() {
|
function Payday() {
|
||||||
const message = {
|
const message = {
|
||||||
event: "HANDLE_PAYDAY",
|
event: "HANDLE::PAYDAY",
|
||||||
data: []
|
data: []
|
||||||
};
|
};
|
||||||
|
|
||||||
|
74
addons/ambient/README.md
Normal file
74
addons/ambient/README.md
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
# Forge Ambient Module
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
The Ambient module provides environmental sound management for the Forge client system. It enables the creation and management of ambient sound effects in the game environment, enhancing the immersive experience for players.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
- forge_client_main
|
||||||
|
|
||||||
|
## Authors
|
||||||
|
- J. Schmidt
|
||||||
|
- Creedcoder
|
||||||
|
- IDSolutions
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### Sound Management
|
||||||
|
1. **Ambient Sound System** (`fnc_ambientSound.sqf`)
|
||||||
|
- Creates and manages sound sources in the game world
|
||||||
|
- Handles sound effect playback and cleanup
|
||||||
|
- Supports timed and continuous sound effects
|
||||||
|
|
||||||
|
2. **Sound Source Features**
|
||||||
|
- Dynamic sound source creation
|
||||||
|
- Position-based sound placement
|
||||||
|
- Automatic cleanup of sound sources
|
||||||
|
- Support for various sound types and durations
|
||||||
|
|
||||||
|
3. **Sound Control**
|
||||||
|
- Lifecycle management of sound sources
|
||||||
|
- Automatic cleanup when source is destroyed
|
||||||
|
- Configurable sound duration
|
||||||
|
- Position tracking for moving sound sources
|
||||||
|
|
||||||
|
## Event Handlers
|
||||||
|
The module uses several event handlers for initialization and execution:
|
||||||
|
- `XEH_preInit.sqf`: Pre-initialization setup
|
||||||
|
- `XEH_postInit.sqf`: Post-initialization tasks
|
||||||
|
- `XEH_preStart.sqf`: Pre-start configuration
|
||||||
|
- `XEH_postInit_client.sqf`: Client-specific post-initialization
|
||||||
|
- `XEH_preInit_server.sqf`: Server-specific pre-initialization
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
To use the ambient module:
|
||||||
|
1. Ensure the module is properly loaded in your mission
|
||||||
|
2. Create sound sources using the ambient sound function:
|
||||||
|
```sqf
|
||||||
|
[source, "sfx_sound_name"] spawn forge_client_ambient_fnc_ambientSound
|
||||||
|
```
|
||||||
|
3. Optionally specify a duration for temporary sounds:
|
||||||
|
```sqf
|
||||||
|
[source, "sfx_sound_name", duration] spawn forge_client_ambient_fnc_ambientSound
|
||||||
|
```
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
The ambient sound function accepts the following parameters:
|
||||||
|
1. `source`: The object or position where the sound will be played
|
||||||
|
2. `sfx`: The name of the sound effect to play
|
||||||
|
3. `time` (optional): Duration in seconds before the sound is removed
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
Debug mode can be enabled by uncommenting the following in `script_component.hpp`:
|
||||||
|
```cpp
|
||||||
|
#define DEBUG_MODE_FULL
|
||||||
|
```
|
||||||
|
|
||||||
|
## Version Information
|
||||||
|
Version information is managed through the main Forge client system configuration.
|
||||||
|
|
||||||
|
## Technical Details
|
||||||
|
- Supports both object-attached and position-based sound sources
|
||||||
|
- Automatic cleanup of sound sources when source is destroyed
|
||||||
|
- Configurable sound duration for temporary effects
|
||||||
|
- Efficient sound source management
|
||||||
|
- Client-side sound processing
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_ambient_fnc_ambientSound
|
* Author: IDSolutions
|
||||||
* Author: J.Schmidt
|
* Create a sound source and play an ambient sfx sound
|
||||||
*
|
|
||||||
* [Description]
|
|
||||||
* Create a sound source and play an ambient sfx sound.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: The sound source <OBJECT>
|
* 0: The sound source <OBJECT>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Forge Arsenal Module
|
# Forge Arsenal Module
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
The Arsenal module provides a comprehensive weapon and vehicle management system for the Forge client. It includes features for managing armory items, vehicle garages, and unlock systems.
|
The Arsenal module provides a comprehensive weapon and vehicle management system for the Forge client. It includes features for managing armory items, vehicle garages, and unlock systems, with support for both traditional and virtual arsenals.
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
- forge_client_main
|
- forge_client_main
|
||||||
@ -17,27 +17,52 @@ The Arsenal module provides a comprehensive weapon and vehicle management system
|
|||||||
1. **Armory Initialization** (`fnc_initArsenal.sqf`)
|
1. **Armory Initialization** (`fnc_initArsenal.sqf`)
|
||||||
- Initializes the arsenal system
|
- Initializes the arsenal system
|
||||||
- Sets up necessary configurations and permissions
|
- Sets up necessary configurations and permissions
|
||||||
|
- Configures default armory and garage data
|
||||||
|
- Supports both traditional and virtual arsenal types
|
||||||
|
|
||||||
2. **Armory Interface** (`fnc_openArmory.sqf`)
|
2. **Armory Interface** (`fnc_openArmory.sqf`)
|
||||||
- Opens the armory user interface
|
- Opens the armory user interface
|
||||||
- Provides access to weapon and equipment management
|
- Provides access to weapon and equipment management
|
||||||
|
- Supports both traditional and ACE arsenal interfaces
|
||||||
|
|
||||||
3. **Item Management**
|
3. **Item Management**
|
||||||
- **Add Armory Items** (`fnc_addArmoryItem.sqf`)
|
- **Add Armory Items** (`fnc_addArmoryItem.sqf`)
|
||||||
- Handles adding new items to the armory
|
- Handles adding new items to the armory
|
||||||
|
- Supports multiple item types:
|
||||||
|
- Facewear (goggles, masks)
|
||||||
|
- Headgear (helmets, caps)
|
||||||
|
- HMD (night vision devices)
|
||||||
|
- Items (tools, medical supplies)
|
||||||
|
- Uniforms
|
||||||
|
- Vests
|
||||||
|
- Weapons
|
||||||
|
- Magazines
|
||||||
|
- Backpacks
|
||||||
- **Save Unlocks** (`fnc_saveUnlocks.sqf`)
|
- **Save Unlocks** (`fnc_saveUnlocks.sqf`)
|
||||||
- Manages the persistence of unlocked items
|
- Manages the persistence of unlocked items
|
||||||
|
- Integrates with player database system
|
||||||
- **Update Unlocks** (`fnc_updateUnlocks.sqf`)
|
- **Update Unlocks** (`fnc_updateUnlocks.sqf`)
|
||||||
- Updates the unlock status of items
|
- Updates the unlock status of items
|
||||||
|
- Maintains synchronization between client and server
|
||||||
|
|
||||||
### Vehicle Management
|
### Vehicle Management
|
||||||
1. **Garage System**
|
1. **Garage System**
|
||||||
- **Open Garage** (`fnc_openGarage.sqf`)
|
- **Open Garage** (`fnc_openGarage.sqf`)
|
||||||
- Provides access to the vehicle garage interface
|
- Provides access to the vehicle garage interface
|
||||||
|
- Categorizes vehicles by type
|
||||||
- **Add Garage Vehicle** (`fnc_addGarageVehicle.sqf`)
|
- **Add Garage Vehicle** (`fnc_addGarageVehicle.sqf`)
|
||||||
- Handles adding new vehicles to the garage
|
- Handles adding new vehicles to the garage
|
||||||
|
- Supports vehicle categories:
|
||||||
|
- Cars
|
||||||
|
- Armored vehicles
|
||||||
|
- Helicopters
|
||||||
|
- Planes
|
||||||
|
- Naval vessels
|
||||||
|
- Static weapons
|
||||||
- **Add Virtual Vehicles** (`fnc_addVirtualVehicles.sqf`)
|
- **Add Virtual Vehicles** (`fnc_addVirtualVehicles.sqf`)
|
||||||
- Manages virtual vehicle entries in the garage
|
- Manages virtual vehicle entries in the garage
|
||||||
|
- Automatically categorizes vehicles by type
|
||||||
|
- Maintains vehicle model information
|
||||||
|
|
||||||
## Event Handlers
|
## Event Handlers
|
||||||
The module uses several event handlers for initialization and execution:
|
The module uses several event handlers for initialization and execution:
|
||||||
@ -54,6 +79,27 @@ To use the arsenal module:
|
|||||||
3. Use the garage interface for vehicle management
|
3. Use the garage interface for vehicle management
|
||||||
4. Manage unlocks and permissions through the appropriate functions
|
4. Manage unlocks and permissions through the appropriate functions
|
||||||
|
|
||||||
|
## Item Types
|
||||||
|
The module supports various item categories:
|
||||||
|
- Weapons (Primary, Secondary, Handgun)
|
||||||
|
- Magazines
|
||||||
|
- Items (Tools, Medical, etc.)
|
||||||
|
- Uniforms
|
||||||
|
- Vests
|
||||||
|
- Backpacks
|
||||||
|
- Facewear
|
||||||
|
- Headgear
|
||||||
|
- HMD (Night Vision)
|
||||||
|
|
||||||
|
## Vehicle Categories
|
||||||
|
Vehicles are organized into the following categories:
|
||||||
|
1. Cars (Light vehicles, transport)
|
||||||
|
2. Armor (Tanks, APCs)
|
||||||
|
3. Helicopters (All rotary-wing aircraft)
|
||||||
|
4. Planes (Fixed-wing aircraft)
|
||||||
|
5. Naval (Boats, ships)
|
||||||
|
6. Static (Weapons, emplacements)
|
||||||
|
|
||||||
## Debugging
|
## Debugging
|
||||||
Debug mode can be enabled by uncommenting the following in `script_component.hpp`:
|
Debug mode can be enabled by uncommenting the following in `script_component.hpp`:
|
||||||
```cpp
|
```cpp
|
||||||
@ -62,3 +108,12 @@ Debug mode can be enabled by uncommenting the following in `script_component.hpp
|
|||||||
|
|
||||||
## Version Information
|
## Version Information
|
||||||
Version information is managed through the main Forge client system configuration.
|
Version information is managed through the main Forge client system configuration.
|
||||||
|
|
||||||
|
## Technical Details
|
||||||
|
- Supports both traditional Arma 3 arsenal and ACE arsenal systems
|
||||||
|
- Automatic vehicle categorization based on class inheritance
|
||||||
|
- Persistent unlock system with database integration
|
||||||
|
- Efficient item and vehicle management
|
||||||
|
- Client-server synchronization for unlocks
|
||||||
|
- Integration with the locker system for item storage
|
||||||
|
- Support for virtual and physical vehicle spawning
|
@ -1,10 +1,10 @@
|
|||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
[{
|
[{
|
||||||
GETVAR(player,value_loadDone,false)
|
GETVAR(player,EGVAR(player,done),false)
|
||||||
}, {
|
}, {
|
||||||
private _armory_unlocks = player getVariable ["Armory_Unlocks", [[],[],[],[]]];
|
private _armory_unlocks = GETVAR(player,Armory_Unlocks,GVAR(default_armory));
|
||||||
private _garage_unlocks = player getVariable ["Garage_Unlocks", [[],[],[],[],[],[]]];
|
private _garage_unlocks = GETVAR(player,Garage_Unlocks,GVAR(default_garage));
|
||||||
|
|
||||||
[_armory_unlocks, _garage_unlocks] call FUNC(initArsenal);
|
[_armory_unlocks, _garage_unlocks] call FUNC(initArsenal);
|
||||||
}] call CFUNC(waitUntilAndExecute);
|
}] call CFUNC(waitUntilAndExecute);
|
@ -7,6 +7,16 @@ PREP_RECOMPILE_END;
|
|||||||
|
|
||||||
GVAR(armory_unlocks) = [];
|
GVAR(armory_unlocks) = [];
|
||||||
GVAR(garage_unlocks) = [];
|
GVAR(garage_unlocks) = [];
|
||||||
|
|
||||||
|
GVAR(car_unlocks) = [];
|
||||||
|
GVAR(armor_unlocks) = [];
|
||||||
|
GVAR(heli_unlocks) = [];
|
||||||
|
GVAR(plane_unlocks) = [];
|
||||||
|
GVAR(naval_unlocks) = [];
|
||||||
|
GVAR(static_unlocks) = [];
|
||||||
|
|
||||||
|
GVAR(default_armory) = [[],[],[],[]];
|
||||||
|
GVAR(default_garage) = [[],[],[],[],[],[]];
|
||||||
GVAR(pdb_mode) = "PDB_MODE" call BFUNC(getParamValue);
|
GVAR(pdb_mode) = "PDB_MODE" call BFUNC(getParamValue);
|
||||||
GVAR(armory_type) = "ARS_TYPE" call BFUNC(getParamValue);
|
GVAR(armory_type) = "ARS_TYPE" call BFUNC(getParamValue);
|
||||||
GVAR(gear_box) = "ReammoBox_F" createVehicleLocal [0, 0, -999];
|
GVAR(gear_box) = "ReammoBox_F" createVehicleLocal [0, 0, -999];
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_arsenal_fnc_addArmoryItem
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
|
||||||
* [Description]
|
|
||||||
* Adds item to player's armory unlocks and updates virtual arsenal
|
* Adds item to player's armory unlocks and updates virtual arsenal
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
@ -22,9 +19,7 @@
|
|||||||
|
|
||||||
params [["_class", "", [""]], ["_type", "", [""]]];
|
params [["_class", "", [""]], ["_type", "", [""]]];
|
||||||
|
|
||||||
private _default = [[],[],[],[]];
|
private _armory_unlocks = GETVAR(player,Armory_Unlocks,GVAR(default_armory));
|
||||||
private _armory_unlocks = GETVAR(player,Armory_Unlocks,_default);
|
|
||||||
|
|
||||||
private _typeToNumber = switch (_type) do {
|
private _typeToNumber = switch (_type) do {
|
||||||
case "facewear";
|
case "facewear";
|
||||||
case "headgear";
|
case "headgear";
|
||||||
@ -49,7 +44,6 @@ if (_index > -1) then {
|
|||||||
[GVAR(gear_box), [_class]] call AFUNC(arsenal,addVirtualItems);
|
[GVAR(gear_box), [_class]] call AFUNC(arsenal,addVirtualItems);
|
||||||
};
|
};
|
||||||
|
|
||||||
TRACE_2("Item added to armory",_class,_type);
|
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_arsenal_fnc_addGarageVehicle
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
|
||||||
* [Description]
|
|
||||||
* Adds vehicle to player's garage unlocks and updates virtual garage
|
* Adds vehicle to player's garage unlocks and updates virtual garage
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
@ -22,10 +19,7 @@
|
|||||||
|
|
||||||
params [["_class", "", [""]], ["_type", "", [""]]];
|
params [["_class", "", [""]], ["_type", "", [""]]];
|
||||||
|
|
||||||
private _default = [[],[],[],[],[],[]];
|
private _garage_unlocks = GETVAR(player,Garage_Unlocks,GVAR(default_garage));
|
||||||
// private _garage_unlocks = player getVariable ["Garage_Unlocks", _default];
|
|
||||||
private _garage_unlocks = GETVAR(player,Garage_Unlocks,_default);
|
|
||||||
|
|
||||||
private _typeToNumber = switch (_type) do {
|
private _typeToNumber = switch (_type) do {
|
||||||
case "car": {0};
|
case "car": {0};
|
||||||
case "armor": {1};
|
case "armor": {1};
|
||||||
@ -39,11 +33,9 @@ private _typeToNumber = switch (_type) do {
|
|||||||
private _index = (_garage_unlocks select _typeToNumber) pushBackUnique _class;
|
private _index = (_garage_unlocks select _typeToNumber) pushBackUnique _class;
|
||||||
|
|
||||||
if (_index > -1) then {
|
if (_index > -1) then {
|
||||||
// player setVariable ["Garage_Unlocks", _garage_unlocks, true];
|
|
||||||
SETPVAR(player,Garage_Unlocks,_garage_unlocks);
|
SETPVAR(player,Garage_Unlocks,_garage_unlocks);
|
||||||
[[_class]] call FUNC(addVirtualVehicles);
|
[[_class]] call FUNC(addVirtualVehicles);
|
||||||
|
|
||||||
TRACE_2("Vehicle added to garage",_class,_type);
|
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_arsenal_fnc_addVirtualVehicles
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
|
||||||
* [Description]
|
|
||||||
* Adds vehicles to virtual garage and categorizes them by type
|
* Adds vehicles to virtual garage and categorizes them by type
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
@ -21,15 +18,8 @@
|
|||||||
|
|
||||||
params [["_vehicles", [], [[]]]];
|
params [["_vehicles", [], [[]]]];
|
||||||
|
|
||||||
private _default = [[],[],[],[],[],[]];
|
private _garage_unlocks = GETVAR(player,Garage_Unlocks,GVAR(default_garage));
|
||||||
private _garage_unlocks = GETVAR(player,Garage_Unlocks,_default);
|
_garage_unlocks params ["_cars", "_armor", "_helis", "_planes", "_naval", "_static"];
|
||||||
|
|
||||||
private _cars = _garage_unlocks select 0;
|
|
||||||
private _armor = _garage_unlocks select 1;
|
|
||||||
private _helis = _garage_unlocks select 2;
|
|
||||||
private _planes = _garage_unlocks select 3;
|
|
||||||
private _naval = _garage_unlocks select 4;
|
|
||||||
private _static = _garage_unlocks select 5;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
switch true do {
|
switch true do {
|
||||||
@ -37,31 +27,14 @@ private _static = _garage_unlocks select 5;
|
|||||||
if ((_x isKindOf "Tank") || (_x isKindOf "Wheeled_APC_F")) exitWith {};
|
if ((_x isKindOf "Tank") || (_x isKindOf "Wheeled_APC_F")) exitWith {};
|
||||||
_cars pushBackUnique _x;
|
_cars pushBackUnique _x;
|
||||||
};
|
};
|
||||||
case (_x isKindOf "Tank"): {
|
case (_x isKindOf "Tank"): { _armor pushBackUnique _x; };
|
||||||
_armor pushBackUnique _x;
|
case (_x isKindOf "Helicopter"): { _helis pushBackUnique _x; };
|
||||||
};
|
case (_x isKindOf "Plane"): { _planes pushBackUnique _x; };
|
||||||
case (_x isKindOf "Helicopter"): {
|
case (_x isKindOf "Ship"): { _naval pushBackUnique _x; };
|
||||||
_helis pushBackUnique _x;
|
case (_x isKindOf "Static"): { _static pushBackUnique _x; };
|
||||||
};
|
|
||||||
case (_x isKindOf "Plane"): {
|
|
||||||
_planes pushBackUnique _x;
|
|
||||||
};
|
|
||||||
case (_x isKindOf "Ship"): {
|
|
||||||
_naval pushBackUnique _x;
|
|
||||||
};
|
|
||||||
case (_x isKindOf "Static"): {
|
|
||||||
_static pushBackUnique _x;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
} forEach _vehicles;
|
} forEach _vehicles;
|
||||||
|
|
||||||
GVAR(car_unlocks) = [];
|
|
||||||
GVAR(armor_unlocks) = [];
|
|
||||||
GVAR(heli_unlocks) = [];
|
|
||||||
GVAR(plane_unlocks) = [];
|
|
||||||
GVAR(naval_unlocks) = [];
|
|
||||||
GVAR(static_unlocks) = [];
|
|
||||||
|
|
||||||
{
|
{
|
||||||
GVAR(car_unlocks) append [getText(configFile >> "CfgVehicles" >> _x >> "model"),[configFile >> "CfgVehicles" >> _x]];
|
GVAR(car_unlocks) append [getText(configFile >> "CfgVehicles" >> _x >> "model"),[configFile >> "CfgVehicles" >> _x]];
|
||||||
} forEach _cars;
|
} forEach _cars;
|
||||||
@ -85,5 +58,3 @@ GVAR(static_unlocks) = [];
|
|||||||
{
|
{
|
||||||
GVAR(static_unlocks) append [getText(configFile >> "CfgVehicles" >> _x >> "model"),[configFile >> "CfgVehicles" >> _x]];
|
GVAR(static_unlocks) append [getText(configFile >> "CfgVehicles" >> _x >> "model"),[configFile >> "CfgVehicles" >> _x]];
|
||||||
} forEach _static;
|
} forEach _static;
|
||||||
|
|
||||||
TRACE_1("Virtual vehicles updated",count _vehicles);
|
|
@ -1,10 +1,7 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_arsenal_fnc_initArsenal
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
|
||||||
* [Description]
|
|
||||||
* Initializes the arsenal system with armory and garage data
|
* Initializes the arsenal system with armory and garage data
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
@ -20,11 +17,8 @@
|
|||||||
|
|
||||||
params [["_armory_data", [], [[]]], ["_garage_data", [], [[]]]];
|
params [["_armory_data", [], [[]]], ["_garage_data", [], [[]]]];
|
||||||
|
|
||||||
private _defaultArmory = [[],[],[],[]];
|
if (!(_armory_data isEqualTypeArray GVAR(default_armory)) || (count _armory_data != 4)) then { _armory_data = GVAR(default_armory); };
|
||||||
private _defaultGarage = [[],[],[],[],[],[]];
|
if (!(_garage_data isEqualTypeArray GVAR(default_garage)) || (count _garage_data != 6)) then { _garage_data = GVAR(default_garage); };
|
||||||
|
|
||||||
if (!(_armory_data isEqualTypeArray _defaultArmory) || (count _armory_data != 4)) then { _armory_data = _defaultArmory; };
|
|
||||||
if (!(_garage_data isEqualTypeArray _defaultGarage) || (count _garage_data != 6)) then { _garage_data = _defaultGarage; };
|
|
||||||
if (GVAR(armory_type) == 0) then {
|
if (GVAR(armory_type) == 0) then {
|
||||||
{
|
{
|
||||||
[GVAR(gear_box), _x, false, true, 1, _forEachIndex] call BFUNC(addVirtualItemCargo);
|
[GVAR(gear_box), _x, false, true, 1, _forEachIndex] call BFUNC(addVirtualItemCargo);
|
||||||
@ -56,8 +50,3 @@ GVAR(static_unlocks) = _statics;
|
|||||||
{
|
{
|
||||||
[_x] call FUNC(addVirtualVehicles);
|
[_x] call FUNC(addVirtualVehicles);
|
||||||
} forEach GVAR(garage_unlocks);
|
} forEach GVAR(garage_unlocks);
|
||||||
|
|
||||||
private _armoryCount = count (_armory_data select { count _x > 0 });
|
|
||||||
private _garageCount = count (_garage_data select { count _x > 0 });
|
|
||||||
|
|
||||||
TRACE_2("Arsenal System Initialized",_armoryCount,_garageCount);
|
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_arsenal_fnc_openArmory
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Opens the virtual arsenal
|
||||||
* [Description]
|
|
||||||
* Opens the arsenal system
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* None
|
* None
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_arsenal_fnc_openGarage
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Opens the virtual garage
|
||||||
* [Description]
|
|
||||||
* Opens the garage system
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* None
|
* None
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_arsenal_fnc_saveUnlocks
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
|
||||||
* [Description]
|
|
||||||
* Saves arsenal/garage unlocks to appropriate storage based on persistence mode
|
* Saves arsenal/garage unlocks to appropriate storage based on persistence mode
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
@ -23,20 +20,16 @@ params [["_type", "", [""]]];
|
|||||||
|
|
||||||
switch (_type) do {
|
switch (_type) do {
|
||||||
case "armory": {
|
case "armory": {
|
||||||
private _default_armory_data = [[],[],[],[]];
|
private _armory_data = GETVAR(player,Armory_Unlocks,GVAR(default_armory));
|
||||||
// private _armory_data = player getVariable ["Armory_Unlocks", [[],[],[],[]]];
|
|
||||||
private _armory_data = GETVAR(player,Armory_Unlocks,_default_armory_data);
|
|
||||||
|
|
||||||
switch (GVAR(pdb_mode)) do {
|
switch (GVAR(pdb_mode)) do {
|
||||||
case 0: {
|
case 0: {
|
||||||
// profileNamespace setVariable ["Armory_Unlocks", _armory_data];
|
|
||||||
SETVAR(profileNamespace,Armory_Unlocks,_armory_data);
|
SETVAR(profileNamespace,Armory_Unlocks,_armory_data);
|
||||||
};
|
};
|
||||||
case 1: {
|
case 1: {
|
||||||
["hsetid", getPlayerUID player, "armory_unlocks", -1, _armory_data, "", false] remoteExec ["dragonfly_db_fnc_addTask", 2, false];
|
["hsetid", getPlayerUID player, "armory_unlocks", -1, _armory_data, "", false] remoteExec ["dragonfly_db_fnc_addTask", 2, false];
|
||||||
};
|
};
|
||||||
default {
|
default {
|
||||||
// profileNamespace setVariable ["Armory_Unlocks", _armory_data];
|
|
||||||
SETVAR(profileNamespace,Armory_Unlocks,_armory_data);
|
SETVAR(profileNamespace,Armory_Unlocks,_armory_data);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -45,20 +38,16 @@ switch (_type) do {
|
|||||||
};
|
};
|
||||||
|
|
||||||
case "garage": {
|
case "garage": {
|
||||||
private _default_garage_data = [[],[],[],[],[],[]];
|
private _garage_data = GETVAR(player,Garage_Unlocks,GVAR(default_garage));
|
||||||
// private _garage_data = player getVariable ["Garage_Unlocks", [[],[],[],[],[],[]]];
|
|
||||||
private _garage_data = GETVAR(player,Garage_Unlocks,_default_garage_data);
|
|
||||||
|
|
||||||
switch (GVAR(pdb_mode)) do {
|
switch (GVAR(pdb_mode)) do {
|
||||||
case 0: {
|
case 0: {
|
||||||
// profileNamespace setVariable ["Garage_Unlocks", _garage_data];
|
|
||||||
SETVAR(profileNamespace,Garage_Unlocks,_garage_data);
|
SETVAR(profileNamespace,Garage_Unlocks,_garage_data);
|
||||||
};
|
};
|
||||||
case 1: {
|
case 1: {
|
||||||
["hsetid", getPlayerUID player, "garage_unlocks", -1, _garage_data, "", false] remoteExec ["dragonfly_db_fnc_addTask", 2, false];
|
["hsetid", getPlayerUID player, "garage_unlocks", -1, _garage_data, "", false] remoteExec ["dragonfly_db_fnc_addTask", 2, false];
|
||||||
};
|
};
|
||||||
default {
|
default {
|
||||||
// profileNamespace setVariable ["Garage_Unlocks", _garage_data];
|
|
||||||
SETVAR(profileNamespace,Garage_Unlocks,_garage_data);
|
SETVAR(profileNamespace,Garage_Unlocks,_garage_data);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -66,5 +55,3 @@ switch (_type) do {
|
|||||||
[_type, _garage_data] call FUNC(updateUnlocks);
|
[_type, _garage_data] call FUNC(updateUnlocks);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
TRACE_2("Arsenal Unlocks saved",_type,GVAR(pdb_mode));
|
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_arsenal_fnc_updateUnlocks
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
|
||||||
* [Description]
|
|
||||||
* Updates the arsenal system variables when unlocks change
|
* Updates the arsenal system variables when unlocks change
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
@ -24,26 +21,24 @@ params [["_type", "", [""]], ["_data", [], [[]]]];
|
|||||||
|
|
||||||
switch (_type) do {
|
switch (_type) do {
|
||||||
case "armory": {
|
case "armory": {
|
||||||
|
_data params ["_items", "_weapons", "_magazines", "_backpacks"];
|
||||||
|
|
||||||
GVAR(armory_unlocks) = _data;
|
GVAR(armory_unlocks) = _data;
|
||||||
|
GVAR(item_unlocks) = _items;
|
||||||
GVAR(item_unlocks) = _data select 0;
|
GVAR(weapon_unlocks) = _weapons;
|
||||||
GVAR(weapon_unlocks) = _data select 1;
|
GVAR(magazine_unlocks) = _magazines;
|
||||||
GVAR(magazine_unlocks) = _data select 2;
|
GVAR(backpack_unlocks) = _backpacks;
|
||||||
GVAR(backpack_unlocks) = _data select 3;
|
|
||||||
|
|
||||||
TRACE_1("Armory unlocks updated",count GVAR(armory_unlocks));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
case "garage": {
|
case "garage": {
|
||||||
|
_data params ["_cars", "_armor", "_helis", "_planes", "_naval", "_static"];
|
||||||
|
|
||||||
GVAR(garage_unlocks) = _data;
|
GVAR(garage_unlocks) = _data;
|
||||||
|
GVAR(car_unlocks) = _cars;
|
||||||
GVAR(car_unlocks) = _data select 0;
|
GVAR(armor_unlocks) = _armor;
|
||||||
GVAR(armor_unlocks) = _data select 1;
|
GVAR(heli_unlocks) = _helis;
|
||||||
GVAR(heli_unlocks) = _data select 2;
|
GVAR(plane_unlocks) = _planes;
|
||||||
GVAR(plane_unlocks) = _data select 3;
|
GVAR(naval_unlocks) = _naval;
|
||||||
GVAR(naval_unlocks) = _data select 4;
|
GVAR(static_unlocks) = _static;
|
||||||
GVAR(static_unlocks) = _data select 5;
|
|
||||||
|
|
||||||
TRACE_1("Garage unlocks updated",count GVAR(garage_unlocks));
|
|
||||||
};
|
};
|
||||||
};
|
};
|
@ -1,7 +1,7 @@
|
|||||||
# Forge Bank Module
|
# Forge Bank Module
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
The Bank module provides a comprehensive banking system for the Forge client. It includes features for managing player finances, transfers, and timesheet functionality.
|
The Bank module provides a comprehensive banking system for the Forge client. It includes features for managing player finances, transfers, and timesheet functionality, with a modern web-based interface for seamless user experience.
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
- forge_client_main
|
- forge_client_main
|
||||||
@ -17,39 +17,70 @@ The Bank module provides a comprehensive banking system for the Forge client. It
|
|||||||
1. **Bank Initialization** (`fnc_initBank.sqf`)
|
1. **Bank Initialization** (`fnc_initBank.sqf`)
|
||||||
- Initializes the banking system
|
- Initializes the banking system
|
||||||
- Sets up necessary configurations and account structures
|
- Sets up necessary configurations and account structures
|
||||||
|
- Configures player account data and balances
|
||||||
|
- Handles server-side synchronization
|
||||||
|
|
||||||
2. **Bank Interface** (`fnc_openBank.sqf`)
|
2. **Bank Interface** (`fnc_openBank.sqf`)
|
||||||
- Opens the banking user interface
|
- Opens the banking user interface
|
||||||
- Provides access to all banking functions
|
- Provides access to all banking functions
|
||||||
|
- Modern web-based UI with real-time updates
|
||||||
|
- Responsive design for optimal user experience
|
||||||
|
|
||||||
3. **Transaction Management**
|
3. **Transaction Management**
|
||||||
- **Deposit** (`fnc_deposit.sqf`)
|
- **Deposit** (`fnc_deposit.sqf`)
|
||||||
- Handles money deposits into bank accounts
|
- Handles money deposits into bank accounts
|
||||||
|
- Validates transaction amounts
|
||||||
|
- Updates account balances in real-time
|
||||||
- **Withdraw** (`fnc_withdraw.sqf`)
|
- **Withdraw** (`fnc_withdraw.sqf`)
|
||||||
- Manages money withdrawals from bank accounts
|
- Manages money withdrawals from bank accounts
|
||||||
|
- Ensures sufficient funds
|
||||||
|
- Updates wallet balance immediately
|
||||||
- **Transfer** (`fnc_transfer.sqf`)
|
- **Transfer** (`fnc_transfer.sqf`)
|
||||||
- Handles money transfers between players
|
- Handles money transfers between players
|
||||||
|
- Validates recipient and amount
|
||||||
|
- Supports both account-to-account and wallet transfers
|
||||||
- **Submit** (`fnc_submit.sqf`)
|
- **Submit** (`fnc_submit.sqf`)
|
||||||
- Processes transaction submissions
|
- Processes transaction submissions
|
||||||
|
- Handles timesheet submissions
|
||||||
|
- Manages pending payments
|
||||||
- **Refresh** (`fnc_refresh.sqf`)
|
- **Refresh** (`fnc_refresh.sqf`)
|
||||||
- Updates account information and balances
|
- Updates account information and balances
|
||||||
|
- Synchronizes with server data
|
||||||
|
- Updates UI elements
|
||||||
|
|
||||||
### User Interface
|
### User Interface
|
||||||
The module includes several UI components:
|
The module includes a modern web-based interface with:
|
||||||
1. **Base Controls** (`BaseControls.hpp`)
|
1. **Account Overview**
|
||||||
- Common UI elements and definitions
|
- Current wallet balance
|
||||||
2. **Bank Dialog** (`RscBankDialog.hpp`)
|
- Bank account balance
|
||||||
- Banking interface specific elements
|
- Pending payments
|
||||||
|
- Transaction history
|
||||||
|
|
||||||
### Interface Elements
|
2. **Transaction Features**
|
||||||
The module defines several UI control IDs:
|
- Transfer between wallet and account
|
||||||
- Account Information Display
|
- Player-to-player transfers
|
||||||
- Amount Input Fields
|
- Timesheet submission
|
||||||
- Player Selection
|
- Transaction history view
|
||||||
- Transaction Buttons (Deposit, Withdraw, Transfer)
|
|
||||||
- Wallet and Bank Balance Displays
|
3. **UI Components**
|
||||||
- Rating System
|
- Real-time balance updates
|
||||||
- Timesheet Integration
|
- Transaction notifications
|
||||||
|
- Input validation
|
||||||
|
- Error handling
|
||||||
|
- Responsive design
|
||||||
|
|
||||||
|
### Timesheet System
|
||||||
|
1. **Rating Integration**
|
||||||
|
- Tracks player rating
|
||||||
|
- Calculates pending payments
|
||||||
|
- Automatic payment processing
|
||||||
|
- Rating reset after submission
|
||||||
|
|
||||||
|
2. **Payment Processing**
|
||||||
|
- Automatic calculation based on rating
|
||||||
|
- Configurable payment multiplier
|
||||||
|
- Pending payment tracking
|
||||||
|
- Instant payment processing
|
||||||
|
|
||||||
## Event Handlers
|
## Event Handlers
|
||||||
The module uses several event handlers for initialization and execution:
|
The module uses several event handlers for initialization and execution:
|
||||||
@ -63,8 +94,12 @@ The module uses several event handlers for initialization and execution:
|
|||||||
To use the bank module:
|
To use the bank module:
|
||||||
1. Ensure the module is properly loaded in your mission
|
1. Ensure the module is properly loaded in your mission
|
||||||
2. Access the bank through the provided UI
|
2. Access the bank through the provided UI
|
||||||
3. Perform transactions using the appropriate functions
|
3. Perform transactions using the appropriate functions:
|
||||||
4. Monitor account status and transactions
|
- Transfer money between wallet and account
|
||||||
|
- Send money to other players
|
||||||
|
- Submit timesheets for payment
|
||||||
|
- View transaction history
|
||||||
|
4. Monitor account status and transactions in real-time
|
||||||
|
|
||||||
## Debugging
|
## Debugging
|
||||||
Debug mode can be enabled by uncommenting the following in `script_component.hpp`:
|
Debug mode can be enabled by uncommenting the following in `script_component.hpp`:
|
||||||
@ -74,3 +109,15 @@ Debug mode can be enabled by uncommenting the following in `script_component.hpp
|
|||||||
|
|
||||||
## Version Information
|
## Version Information
|
||||||
Version information is managed through the main Forge client system configuration.
|
Version information is managed through the main Forge client system configuration.
|
||||||
|
|
||||||
|
## Technical Details
|
||||||
|
- Web-based interface using HTML5, CSS3, and JavaScript
|
||||||
|
- Real-time data synchronization with server
|
||||||
|
- Secure transaction processing
|
||||||
|
- Client-server event system
|
||||||
|
- Persistent data storage
|
||||||
|
- Rating-based payment system
|
||||||
|
- Transaction history tracking
|
||||||
|
- Input validation and error handling
|
||||||
|
- Responsive UI design
|
||||||
|
- Cross-browser compatibility
|
@ -1,5 +1,4 @@
|
|||||||
PREP(deposit);
|
PREP(deposit);
|
||||||
PREP(initBank);
|
|
||||||
PREP(openBank);
|
PREP(openBank);
|
||||||
PREP(refresh);
|
PREP(refresh);
|
||||||
PREP(submit);
|
PREP(submit);
|
||||||
|
@ -1 +1,12 @@
|
|||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
[{
|
||||||
|
GETVAR(player,value_loadDone,false)
|
||||||
|
}, {
|
||||||
|
private _bank = GETVAR(player,FORGE_Bank,0);
|
||||||
|
private _cash = GETVAR(player,FORGE_Cash,0);
|
||||||
|
private _rating = GETVAR(player,FORGE_Rating,0);
|
||||||
|
private _uid = getPlayerUID player;
|
||||||
|
|
||||||
|
["forge_server_bank_handleEvents", ["BANK::HANDLE::PLAYER::LOAD", [_uid, _bank, _cash, _rating]]] call CFUNC(serverEvent);
|
||||||
|
}] call CFUNC(waitUntilAndExecute);
|
@ -1 +1,97 @@
|
|||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
[QGVAR(handleEvents), {
|
||||||
|
params ["_control", "_isConfirmDialog", "_message"];
|
||||||
|
|
||||||
|
diag_log text format ["[FORGE::Client::Bank::XEH_postInit::handleEvents] Received event: '%1'", _message];
|
||||||
|
|
||||||
|
_message = fromJSON _message;
|
||||||
|
private _event = _message get "event";
|
||||||
|
private _data = _message get "data";
|
||||||
|
|
||||||
|
switch (_event) do {
|
||||||
|
case "REQUEST::PLAYER::DATA": {
|
||||||
|
private _playerData = createHashMap;
|
||||||
|
private _playerList = [];
|
||||||
|
|
||||||
|
{
|
||||||
|
private _uid = getPlayerUID _x;
|
||||||
|
private _name = name _x;
|
||||||
|
private _funds = GETVAR(_x,FORGE_Bank,0); //TODO: Implement funds from server
|
||||||
|
private _cash = GETVAR(_x,FORGE_Cash,0); //TODO: Implement cash from server
|
||||||
|
|
||||||
|
private _playerInfo = createHashMapFromArray [
|
||||||
|
["uid", _uid],
|
||||||
|
["name", _name],
|
||||||
|
["funds", _funds],
|
||||||
|
["cash", _cash]
|
||||||
|
];
|
||||||
|
|
||||||
|
_playerList pushBack _playerInfo;
|
||||||
|
} forEach allPlayers;
|
||||||
|
|
||||||
|
_playerData set ["players", _playerList];
|
||||||
|
_control ctrlWebBrowserAction ["ExecJS", format ["handlePlayerDataRequest(%1)", (toJSON _playerList)]];
|
||||||
|
};
|
||||||
|
case "REQUEST::PLAYER::FUNDS": {
|
||||||
|
private _playerData = createHashMap;
|
||||||
|
private _balance = GETVAR(player,FORGE_Bank,0); //TODO: Implement balance from server
|
||||||
|
private _cash = GETVAR(player,FORGE_Cash,0); //TODO: Implement cash from server
|
||||||
|
|
||||||
|
private _payMultiplier = "MULTIPLYR" call BFUNC(getParamValue);
|
||||||
|
private _rating = rating player; //TODO: Implement rating from server
|
||||||
|
private _pending = _rating * _payMultiplier; //TODO: Implement pending from server
|
||||||
|
|
||||||
|
private _playerData = createHashMapFromArray [
|
||||||
|
["balance", _balance],
|
||||||
|
["cash", _cash],
|
||||||
|
["pending", _pending]
|
||||||
|
];
|
||||||
|
|
||||||
|
_control ctrlWebBrowserAction ["ExecJS", format ["handlePlayerFundsRequest(%1)", (toJSON _playerData)]];
|
||||||
|
};
|
||||||
|
case "REQUEST::TRANSACTION::HISTORY": {
|
||||||
|
private _history = []; //TODO: Implement history from server
|
||||||
|
private _historyData = createHashMapFromArray [["history", _history]];
|
||||||
|
|
||||||
|
_control ctrlWebBrowserAction ["ExecJS", format ["handleTransactionHistoryRequest(%1)", (toJSON _historyData)]];
|
||||||
|
};
|
||||||
|
case "DEPOSIT::FUNDS": {
|
||||||
|
_data params [["_amount", 0, [0]]];
|
||||||
|
|
||||||
|
if (_amount <= 0) exitWith { systemChat "Invalid amount, must be greater than 0!"; false };
|
||||||
|
["forge_server_bank_handleEvents", ["BANK::DEPOSIT", [getPlayerUID player, _amount]]] call CFUNC(serverEvent);
|
||||||
|
|
||||||
|
true
|
||||||
|
};
|
||||||
|
case "SUBMIT::TIMESHEET": {
|
||||||
|
private _rating = rating player;
|
||||||
|
private _uid = getPlayerUID player;
|
||||||
|
|
||||||
|
["forge_server_bank_handleEvents", ["BANK::SUBMIT::TIMESHEET", [_uid, _rating]]] call CFUNC(serverEvent);
|
||||||
|
|
||||||
|
player addRating -_rating;
|
||||||
|
|
||||||
|
true
|
||||||
|
};
|
||||||
|
case "TRANSFER::FUNDS": {
|
||||||
|
_data params [["_uid", "", [""]], ["_amount", 0, [0]]];
|
||||||
|
|
||||||
|
if ({_uid isEqualTo ""} || _amount <= 0) exitWith { systemChat "Invalid UID or amount, UID cannot be empty and amount must be greater than 0!"; false };
|
||||||
|
["forge_server_bank_handleEvents", ["BANK::TRANSFER", [getPlayerUID player, _uid, _amount]]] call CFUNC(serverEvent);
|
||||||
|
|
||||||
|
true
|
||||||
|
};
|
||||||
|
case "WITHDRAW::FUNDS": {
|
||||||
|
_data params [["_amount", 0, [0]]];
|
||||||
|
|
||||||
|
if (_amount <= 0) exitWith { systemChat "Invalid amount, amount must be greater than 0!"; false };
|
||||||
|
["forge_server_bank_handleEvents", ["BANK::WITHDRAW", [getPlayerUID player, _amount]]] call CFUNC(serverEvent);
|
||||||
|
|
||||||
|
true
|
||||||
|
};
|
||||||
|
default {
|
||||||
|
diag_log format ["[FORGE::Client::Bank::XEH_postInit::handleEvents] Unhandled event: %1", _event];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}] call CFUNC(addEventHandler);
|
@ -16,3 +16,4 @@ class CfgPatches {
|
|||||||
#include "CfgEventHandlers.hpp"
|
#include "CfgEventHandlers.hpp"
|
||||||
#include "ui\BaseControls.hpp"
|
#include "ui\BaseControls.hpp"
|
||||||
#include "ui\RscBankDialog.hpp"
|
#include "ui\RscBankDialog.hpp"
|
||||||
|
#include "ui\RscWebBank.hpp"
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_bank_fnc_deposit
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Deposits money into the bank.
|
||||||
* [Description]
|
|
||||||
* Deposits money into the bank
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* None
|
* None
|
||||||
@ -13,25 +10,25 @@
|
|||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Examples:
|
* Example:
|
||||||
* None
|
* [] call forge_client_bank_fnc_deposit;
|
||||||
*
|
*
|
||||||
* Public: Yes
|
* Public: Yes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private _amount = parseNumber (ctrlText IDC_AMOUNTINPUT);
|
private _amount = parseNumber (ctrlText IDC_AMOUNTINPUT);
|
||||||
private _bank = GETVAR(player,FORGE_Bank,0);
|
|
||||||
private _cash = GETVAR(player,FORGE_Cash,0);
|
|
||||||
|
|
||||||
if (_amount > 0 && _amount <= _cash) then {
|
private _messageData = createHashMapFromArray [
|
||||||
_cash = _cash - _amount;
|
["event", "DEPOSIT::FUNDS"],
|
||||||
_bank = _bank + _amount;
|
["data", createHashMapFromArray [
|
||||||
|
["amount", _amount]
|
||||||
|
]]
|
||||||
|
];
|
||||||
|
|
||||||
SETPVAR(player,FORGE_Bank,_bank);
|
private _response = ["forge_client_bank_handleEvents", (toJSON _messageData)] call CFUNC(localEvent);
|
||||||
SETPVAR(player,FORGE_Cash,_cash);
|
|
||||||
|
|
||||||
[] call FUNC(refresh);
|
if (_response) then {
|
||||||
hint "Money deposited successfully";
|
[format ["Deposited $%1", _amount], "info", 3, "right"] call EFUNC(misc,notify);
|
||||||
} else {
|
} else {
|
||||||
hint "Invalid amount";
|
[format ["Deposit failed"], "warning", 3, "right"] call EFUNC(misc,notify);
|
||||||
};
|
};
|
@ -1,49 +0,0 @@
|
|||||||
#include "..\script_component.hpp"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: forge_client_bank_fnc_initBank
|
|
||||||
* Author: IDSolutions
|
|
||||||
*
|
|
||||||
* [Description]
|
|
||||||
* Initializes the bank system
|
|
||||||
*
|
|
||||||
* Arguments:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
* Return Value:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
* Examples:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
* Public: Yes
|
|
||||||
*/
|
|
||||||
|
|
||||||
{
|
|
||||||
private _configName = configName(_x);
|
|
||||||
private _className = (missionConfigFile >> "CfgBanks" >> "banks" >> _configName >> "className") call BFUNC(getCfgData);
|
|
||||||
private _pos = (missionConfigFile >> "CfgBanks" >> "banks" >> _configName >> "pos") call BFUNC(getCfgData);
|
|
||||||
private _dir = (missionConfigFile >> "CfgBanks" >> "banks" >> _configName >> "dir") call BFUNC(getCfgData);
|
|
||||||
private _type = (missionConfigFile >> "CfgBanks" >> "banks" >> _configName >> "type") call BFUNC(getCfgData);
|
|
||||||
|
|
||||||
if (_type == "object") then {
|
|
||||||
private _bank = createSimpleObject [_className, [0, 0, 0]];
|
|
||||||
|
|
||||||
_bank setPosATL _pos;
|
|
||||||
_bank setDir _dir;
|
|
||||||
_bank allowDamage false;
|
|
||||||
_bank setVariable ["isBank", true, true];
|
|
||||||
} else {
|
|
||||||
private _group = createGroup civilian;
|
|
||||||
private _bank = _group createUnit [_className, [0, 0, 0], [], 0, "NONE"];
|
|
||||||
|
|
||||||
_bank disableAI "MOVE";
|
|
||||||
_bank setPosATL _pos;
|
|
||||||
_bank setDir _dir;
|
|
||||||
_bank allowDamage false;
|
|
||||||
_bank setVariable ["isBank", true, true];
|
|
||||||
_bank setVariable ["BIS_enableRandomization", false];
|
|
||||||
};
|
|
||||||
|
|
||||||
diag_log text format ["[FORGE Bank] ClassName: '%1' Pos: '%2' Dir: '%3'", _className, _pos, _dir];
|
|
||||||
} forEach ("true" configClasses (missionConfigFile >> "CfgBanks" >> "banks"));
|
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_bank_fnc_openBank
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Opens the bank dialog.
|
||||||
* [Description]
|
|
||||||
* Opens the bank dialog
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* None
|
* None
|
||||||
@ -13,34 +10,51 @@
|
|||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Examples:
|
* Example:
|
||||||
* None
|
* [] call forge_client_bank_fnc_openBank;
|
||||||
*
|
*
|
||||||
* Public: Yes
|
* Public: Yes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private _bank = GETVAR(player,FORGE_Bank,0);
|
private _productVersion = productVersion;
|
||||||
private _cash = GETVAR(player,FORGE_Cash,0);
|
private _steamBranchName = _productVersion select 8;
|
||||||
private _payMultiplier = "MULTIPLYR" call BFUNC(getParamValue);
|
private _payMultiplier = "MULTIPLYR" call BFUNC(getParamValue);
|
||||||
private _plyscore = rating player;
|
|
||||||
private _pending = _plyscore * _payMultiplier;
|
|
||||||
|
|
||||||
disableSerialization;
|
if (_steamBranchName == "profiling") then {
|
||||||
createDialog "RscBankDialog";
|
private _display = (findDisplay 46) createDisplay "RscWebBank";
|
||||||
|
private _ctrl = _display displayCtrl 2025;
|
||||||
|
|
||||||
private _formattedBank = _bank call EFUNC(misc,formatNumber);
|
_ctrl ctrlAddEventHandler ["JSDialog", {
|
||||||
private _formattedCash = _cash call EFUNC(misc,formatNumber);
|
params ["_control", "_isConfirmDialog", "_message"];
|
||||||
private _formattedPending = _pending call EFUNC(misc,formatNumber);
|
[QGVAR(handleEvents), [_control, _isConfirmDialog, _message]] call CFUNC(localEvent);
|
||||||
|
}];
|
||||||
|
|
||||||
ctrlSetText [IDC_CASHTEXT, format ["Cash: $%1", _formattedCash]];
|
_ctrl ctrlWebBrowserAction ["LoadFile", QUOTE(PATHTOF(ui\_site\index.html))];
|
||||||
ctrlSetText [IDC_BANKTEXT, format ["Bank: $%1", _formattedBank]];
|
// _ctrl ctrlWebBrowserAction ["OpenDevConsole"];
|
||||||
ctrlSetText [IDC_RATINGTEXT, format ["Pending: %1", _formattedPending]];
|
} else {
|
||||||
ctrlSetText [IDC_TIMESHEETTEXT, "Ready for Timesheet"];
|
disableSerialization;
|
||||||
|
createDialog "RscBankDialog";
|
||||||
|
|
||||||
{
|
private _uid = getPlayerUID player;
|
||||||
|
private _bank = GETVAR(player,FORGE_Bank,0); //TODO: Implement balance from server
|
||||||
|
private _cash = GETVAR(player,FORGE_Cash,0); //TODO: Implement cash from server
|
||||||
|
private _plyscore = rating player;
|
||||||
|
private _pending = _plyscore * _payMultiplier;
|
||||||
|
|
||||||
|
private _formattedBank = _bank call EFUNC(misc,formatNumber);
|
||||||
|
private _formattedCash = _cash call EFUNC(misc,formatNumber);
|
||||||
|
private _formattedPending = _pending call EFUNC(misc,formatNumber);
|
||||||
|
|
||||||
|
ctrlSetText [IDC_CASHTEXT, format ["Cash: $%1", _formattedCash]];
|
||||||
|
ctrlSetText [IDC_BANKTEXT, format ["Bank: $%1", _formattedBank]];
|
||||||
|
ctrlSetText [IDC_RATINGTEXT, format ["Pending: %1", _formattedPending]];
|
||||||
|
ctrlSetText [IDC_TIMESHEETTEXT, "Ready for Timesheet"];
|
||||||
|
|
||||||
|
{
|
||||||
lbAdd [IDC_PLAYERINPUT, name _x];
|
lbAdd [IDC_PLAYERINPUT, name _x];
|
||||||
lbSetData [IDC_PLAYERINPUT, _forEachIndex, netId _x];
|
lbSetData [IDC_PLAYERINPUT, _forEachIndex, netId _x];
|
||||||
} forEach allPlayers;
|
} forEach allPlayers;
|
||||||
|
|
||||||
lbSetCurSel [IDC_PLAYERINPUT, 0];
|
lbSetCurSel [IDC_PLAYERINPUT, 0];
|
||||||
ctrlSetText [IDC_AMOUNTINPUT, ""];
|
ctrlSetText [IDC_AMOUNTINPUT, ""];
|
||||||
|
};
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_bank_fnc_refresh
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Refreshes the bank dialog.
|
||||||
* [Description]
|
|
||||||
* Refreshes the bank dialog
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* None
|
* None
|
||||||
@ -13,14 +10,15 @@
|
|||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Examples:
|
* Example:
|
||||||
* None
|
* [] call forge_client_bank_fnc_refresh;
|
||||||
*
|
*
|
||||||
* Public: Yes
|
* Public: Yes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private _bank = GETVAR(player,FORGE_Bank,0);
|
private _bank = GETVAR(player,FORGE_Bank,0); //TODO: Implement balance from server
|
||||||
private _cash = GETVAR(player,FORGE_Cash,0);
|
private _cash = GETVAR(player,FORGE_Cash,0); //TODO: Implement cash from server
|
||||||
|
|
||||||
private _payMultiplier = "MULTIPLYR" call BFUNC(getParamValue);
|
private _payMultiplier = "MULTIPLYR" call BFUNC(getParamValue);
|
||||||
private _plyscore = rating player;
|
private _plyscore = rating player;
|
||||||
private _pending = _plyscore * _payMultiplier;
|
private _pending = _plyscore * _payMultiplier;
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_bank_fnc_submit
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
|
||||||
* [Description]
|
|
||||||
* Submits the timesheet
|
* Submits the timesheet
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
@ -19,19 +16,24 @@
|
|||||||
* Public: Yes
|
* Public: Yes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private _bank = GETVAR(player,FORGE_Bank,0);
|
|
||||||
private _payMultiplyer = "MULTIPLYR" call BFUNC(getParamValue);
|
private _payMultiplyer = "MULTIPLYR" call BFUNC(getParamValue);
|
||||||
private _plyscore = rating player;
|
private _plyscore = rating player; //TODO: Implement rating from server
|
||||||
private _multiplyer = _plyscore * _payMultiplyer;
|
private _multiplyer = _plyscore * _payMultiplyer;
|
||||||
|
|
||||||
_bank = _bank + _multiplyer;
|
_bank = _bank + _multiplyer;
|
||||||
|
|
||||||
player addRating - _plyscore;
|
private _formattedRating = _bank call EFUNC(misc,formatNumber);
|
||||||
SETPVAR(player,FORGE_Bank,_bank);
|
private _messageData = createHashMapFromArray [
|
||||||
SETPVAR(player,FORGE_Rating,0);
|
["event", "SUBMIT::TIMESHEET"],
|
||||||
|
["data", []]
|
||||||
|
];
|
||||||
|
|
||||||
|
private _response = ["forge_client_bank_handleEvents", (toJSON _messageData)] call CFUNC(localEvent);
|
||||||
|
|
||||||
|
if (_response) then {
|
||||||
|
[format ["Submitted timesheet! Received $%1 based on rating of %2", _formattedRating, _plyscore], "info", 3, "right"] call EFUNC(misc,notify);
|
||||||
|
} else {
|
||||||
|
[format ["Timesheet submission failed"], "warning", 3, "right"] call EFUNC(misc,notify);
|
||||||
|
};
|
||||||
|
|
||||||
[] call FUNC(refresh);
|
[] call FUNC(refresh);
|
||||||
|
|
||||||
private _formattedRating = _bank call EFUNC(misc,formatNumber);
|
|
||||||
|
|
||||||
[format ["Timesheet submitted! Received $%1 based on rating of %2", _formattedRating, _plyscore], "info", 3, "right"] call EFUNC(misc,notify);
|
|
@ -1,10 +1,7 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_bank_fnc_transfer
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
|
||||||
* [Description]
|
|
||||||
* Transfers money to a player
|
* Transfers money to a player
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
@ -13,8 +10,8 @@
|
|||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Examples:
|
* Example:
|
||||||
* None
|
* [] call forge_client_bank_fnc_transfer;
|
||||||
*
|
*
|
||||||
* Public: Yes
|
* Public: Yes
|
||||||
*/
|
*/
|
||||||
@ -22,23 +19,25 @@
|
|||||||
private _display = findDisplay IDD_BANKDIALOG;
|
private _display = findDisplay IDD_BANKDIALOG;
|
||||||
private _input = _display displayCtrl IDC_AMOUNTINPUT;
|
private _input = _display displayCtrl IDC_AMOUNTINPUT;
|
||||||
private _dropdown = _display displayCtrl IDC_PLAYERINPUT;
|
private _dropdown = _display displayCtrl IDC_PLAYERINPUT;
|
||||||
|
|
||||||
private _amount = parseNumber (ctrlText _input);
|
private _amount = parseNumber (ctrlText _input);
|
||||||
private _selectedTarget = lbCurSel _dropdown;
|
private _selectedTarget = lbCurSel _dropdown;
|
||||||
private _selectedTargetData = _dropdown lbData _selectedTarget;
|
private _selectedTargetData = _dropdown lbData _selectedTarget;
|
||||||
private _target = objectFromNetId _selectedTargetData;
|
private _target = objectFromNetId _selectedTargetData;
|
||||||
|
private _uid = getPlayerUID _target;
|
||||||
|
|
||||||
private _bank = GETVAR(player,FORGE_Bank,0);
|
private _messageData = createHashMapFromArray [
|
||||||
private _targetBank = GETVAR(_target,FORGE_Bank,0);
|
["event", "TRANSFER::FUNDS"],
|
||||||
|
["data", createHashMapFromArray [
|
||||||
|
["uid", _uid],
|
||||||
|
["amount", _amount]
|
||||||
|
]]
|
||||||
|
];
|
||||||
|
|
||||||
if (!isNull _target && _amount > 0 && _amount <= _bank) then {
|
private _response = [QGVAR(handleEvents), (toJSON _messageData)] call CFUNC(localEvent);
|
||||||
_targetBank = _targetBank + _amount;
|
|
||||||
SETPVAR(_target,FORGE_Bank,_targetBank);
|
|
||||||
|
|
||||||
_bank = _bank - _amount;
|
if (_response) then {
|
||||||
SETPVAR(player,FORGE_Bank,_bank);
|
|
||||||
|
|
||||||
[] call FUNC(refresh);
|
|
||||||
[format ["Transferred $%1", _amount], "info", 3, "right"] call EFUNC(misc,notify);
|
[format ["Transferred $%1", _amount], "info", 3, "right"] call EFUNC(misc,notify);
|
||||||
} else {
|
} else {
|
||||||
[format ["Invalid transfer details"], "warning", 3, "right"] call EFUNC(misc,notify);
|
[format ["Transfer failed"], "warning", 3, "right"] call EFUNC(misc,notify);
|
||||||
};
|
};
|
@ -1,10 +1,7 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_bank_fnc_withdraw
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
|
||||||
* [Description]
|
|
||||||
* Withdraws money from the bank
|
* Withdraws money from the bank
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
@ -13,8 +10,8 @@
|
|||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Examples:
|
* Example:
|
||||||
* None
|
* [] call forge_client_bank_fnc_withdraw;
|
||||||
*
|
*
|
||||||
* Public: Yes
|
* Public: Yes
|
||||||
*/
|
*/
|
||||||
@ -23,18 +20,17 @@ private _display = findDisplay IDD_BANKDIALOG;
|
|||||||
private _input = _display displayCtrl IDC_AMOUNTINPUT;
|
private _input = _display displayCtrl IDC_AMOUNTINPUT;
|
||||||
private _amount = parseNumber (ctrlText _input);
|
private _amount = parseNumber (ctrlText _input);
|
||||||
|
|
||||||
private _bank = GETVAR(player,FORGE_Bank,0);
|
private _messageData = createHashMapFromArray [
|
||||||
private _cash = GETVAR(player,FORGE_Cash,0);
|
["event", "WITHDRAW::FUNDS"],
|
||||||
|
["data", createHashMapFromArray [
|
||||||
|
["amount", _amount]
|
||||||
|
]]
|
||||||
|
];
|
||||||
|
|
||||||
if (_amount > 0 && _amount <= _bank) then {
|
private _response = ["forge_client_bank_handleEvents", (toJSON _messageData)] call CFUNC(localEvent);
|
||||||
_bank = _bank - _amount;
|
|
||||||
_cash = _cash + _amount;
|
|
||||||
|
|
||||||
SETPVAR(player,FORGE_Bank,_bank);
|
if (_response) then {
|
||||||
SETPVAR(player,FORGE_Cash,_cash);
|
[format ["Withdrawn $%1", _amount], "info", 3, "right"] call EFUNC(misc,notify);
|
||||||
|
|
||||||
[] call FUNC(refresh);
|
|
||||||
[format ["Money withdrawn successfully"], "info", 3, "right"] call EFUNC(misc,notify);
|
|
||||||
} else {
|
} else {
|
||||||
[format ["Invalid amount"], "warning", 3, "right"] call EFUNC(misc,notify);
|
[format ["Withdrawal failed"], "warning", 3, "right"] call EFUNC(misc,notify);
|
||||||
};
|
};
|
@ -4,9 +4,6 @@
|
|||||||
<Key ID="STR_forge_client_bank_Amount">
|
<Key ID="STR_forge_client_bank_Amount">
|
||||||
<English>Amount</English>
|
<English>Amount</English>
|
||||||
</Key>
|
</Key>
|
||||||
<Key ID="STR_forge_client_bank_Close">
|
|
||||||
<English>Close</English>
|
|
||||||
</Key>
|
|
||||||
<Key ID="STR_forge_client_bank_Deposit">
|
<Key ID="STR_forge_client_bank_Deposit">
|
||||||
<English>Deposit</English>
|
<English>Deposit</English>
|
||||||
</Key>
|
</Key>
|
||||||
|
17
addons/bank/ui/RscWebBank.hpp
Normal file
17
addons/bank/ui/RscWebBank.hpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
class RscWebBank {
|
||||||
|
idd = 20250502;
|
||||||
|
fadein = 0;
|
||||||
|
fadeout = 0;
|
||||||
|
duration = 1e+011;
|
||||||
|
|
||||||
|
class controls {
|
||||||
|
class Background: RscText {
|
||||||
|
type = 106;
|
||||||
|
idc = 2025;
|
||||||
|
x = "safeZoneY * (pixelW/pixelH) * 2.975";
|
||||||
|
y = "safeZoneY + (safeZoneH * 0.05)";
|
||||||
|
w = "safeZoneW * (pixelW/pixelH) * 1.17";
|
||||||
|
h = "safeZoneH * 0.875";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
@ -1,22 +1,41 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<!--
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
Dynamic Resource Loading
|
||||||
<title>FORGE - FDIC</title>
|
The following script loads CSS and JavaScript files dynamically using the A3API
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
This approach is used instead of static HTML imports to work with Arma 3's file system
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
-->
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
<script>
|
||||||
<link rel="stylesheet" href="styles.css">
|
Promise.all([
|
||||||
<script src="script.js" defer></script>
|
// Load CSS file
|
||||||
|
A3API.RequestFile("z\\forge_client\\addons\\bank\\ui\\_site\\styles.css"),
|
||||||
|
// Load JavaScript file
|
||||||
|
A3API.RequestFile("z\\forge_client\\addons\\bank\\ui\\_site\\script.js")
|
||||||
|
]).then(([css, js]) => {
|
||||||
|
// Apply CSS
|
||||||
|
const style = document.createElement('style');
|
||||||
|
style.textContent = css;
|
||||||
|
document.head.appendChild(style);
|
||||||
|
|
||||||
|
// Load and execute JavaScript
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.text = js;
|
||||||
|
document.head.appendChild(script);
|
||||||
|
|
||||||
|
// Initialize the bank interface
|
||||||
|
initializeBank();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<div class="header-content">
|
<div class="header-content">
|
||||||
<h1>Federal Deposit Insurance Corporation</h1>
|
<h1>Federal Deposit Insurance Corporation</h1>
|
||||||
<div class="balance-display">
|
<div class="balance-display">
|
||||||
<div class="balance-item">
|
<div class="balance-item">
|
||||||
<div class="balance-icon">💰</div>
|
|
||||||
<div class="balance-info">
|
<div class="balance-info">
|
||||||
<span class="balance-label">Wallet Balance</span>
|
<span class="balance-label">Wallet Balance</span>
|
||||||
<span class="balance-amount" id="walletBalance">$0</span>
|
<span class="balance-amount" id="walletBalance">$0</span>
|
||||||
@ -24,7 +43,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="balance-divider"></div>
|
<div class="balance-divider"></div>
|
||||||
<div class="balance-item">
|
<div class="balance-item">
|
||||||
<div class="balance-icon">🏦</div>
|
|
||||||
<div class="balance-info">
|
<div class="balance-info">
|
||||||
<span class="balance-label">Account Balance</span>
|
<span class="balance-label">Account Balance</span>
|
||||||
<span class="balance-amount" id="accountBalance">$0</span>
|
<span class="balance-amount" id="accountBalance">$0</span>
|
||||||
@ -35,10 +53,10 @@
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main class="container">
|
<main class="container">
|
||||||
<div class="actions-grid"> <!-- Transfer Between Accounts -->
|
<div class="actions-grid">
|
||||||
|
<!-- Transfer Between Accounts -->
|
||||||
<div class="action-tile">
|
<div class="action-tile">
|
||||||
<h2>Transfer Money</h2>
|
<h2>Transfer Money</h2>
|
||||||
<form id="transferForm">
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="transferType">Transfer From</label>
|
<label for="transferType">Transfer From</label>
|
||||||
<select id="transferType" required>
|
<select id="transferType" required>
|
||||||
@ -50,14 +68,12 @@
|
|||||||
<label for="transferAmount">Amount</label>
|
<label for="transferAmount">Amount</label>
|
||||||
<input type="number" id="transferAmount" min="1" step="1" required>
|
<input type="number" id="transferAmount" min="1" step="1" required>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="submit-btn">Transfer</button>
|
<button type="button" class="submit-btn" onclick="handleTransfer()">Transfer</button>
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Transfer to Player -->
|
<!-- Transfer to Player -->
|
||||||
<div class="action-tile">
|
<div class="action-tile">
|
||||||
<h2>Transfer to Player</h2>
|
<h2>Transfer to Player</h2>
|
||||||
<form id="transferPlayerForm">
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="playerSelect">Player</label>
|
<label for="playerSelect">Player</label>
|
||||||
<select id="playerSelect" required>
|
<select id="playerSelect" required>
|
||||||
@ -68,24 +84,17 @@
|
|||||||
<label for="playerTransferAmount">Amount</label>
|
<label for="playerTransferAmount">Amount</label>
|
||||||
<input type="number" id="playerTransferAmount" min="1" step="1" required>
|
<input type="number" id="playerTransferAmount" min="1" step="1" required>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="submit-btn">Send Money</button>
|
<button type="button" class="submit-btn" onclick="handlePlayerTransfer()">Send Money</button>
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Submit Timesheet -->
|
<!-- Submit Timesheet -->
|
||||||
<div class="action-tile">
|
<div class="action-tile">
|
||||||
<h2>Submit Timesheet</h2>
|
<h2>Submit Timesheet</h2>
|
||||||
<form id="timesheetForm">
|
<div class="pending-amount">
|
||||||
<div class="form-group">
|
<div class="amount-label">Pending Payment</div>
|
||||||
<label for="hoursWorked">Hours Worked</label>
|
<div class="amount-value" id="pending">$0</div>
|
||||||
<input type="number" id="hoursWorked" min="1" step="0.5" required>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<button type="button" class="submit-btn" onclick="handleTimesheet()">Submit Timesheet</button>
|
||||||
<label for="hourlyRate">Hourly Rate</label>
|
|
||||||
<input type="number" id="hourlyRate" min="1" step="1" required>
|
|
||||||
</div>
|
|
||||||
<button type="submit" class="submit-btn">Submit Timesheet</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -98,4 +107,5 @@
|
|||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
@ -1,79 +1,230 @@
|
|||||||
// Simulated data - this would be replaced with actual game data
|
/**
|
||||||
|
* Bank Management Script
|
||||||
|
* This script handles the bank interface functionality for the Arma 3 game interface.
|
||||||
|
* It provides wallet/account management, transfers, and transaction history.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// #region DATA STRUCTURES AND VARIABLES
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bank state - will be populated from game events
|
||||||
|
*/
|
||||||
let bankState = {
|
let bankState = {
|
||||||
wallet: 1000,
|
wallet: 0,
|
||||||
account: 5000,
|
account: 0,
|
||||||
players: [
|
pending: 0,
|
||||||
{ id: 1, name: "Player 1" },
|
players: [],
|
||||||
{ id: 2, name: "Player 2" },
|
|
||||||
{ id: 3, name: "Player 3" }
|
|
||||||
],
|
|
||||||
transactions: []
|
transactions: []
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initialize the interface
|
// #endregion
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// #region INITIALIZATION AND DATA REQUESTS
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the bank interface
|
||||||
|
* Sets up the UI and requests initial data from the game engine
|
||||||
|
*/
|
||||||
function initializeBank() {
|
function initializeBank() {
|
||||||
updateBalanceDisplays();
|
// Request initial data from the game
|
||||||
|
requestPlayerFunds();
|
||||||
|
requestPlayerData();
|
||||||
|
requestTransactionHistory();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request player funds data from the game engine
|
||||||
|
*/
|
||||||
|
function requestPlayerFunds() {
|
||||||
|
const message = {
|
||||||
|
event: "REQUEST::PLAYER::FUNDS",
|
||||||
|
data: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
A3API.SendAlert(JSON.stringify(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request player data from the game engine
|
||||||
|
*/
|
||||||
|
function requestPlayerData() {
|
||||||
|
const message = {
|
||||||
|
event: "REQUEST::PLAYER::DATA",
|
||||||
|
data: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
A3API.SendAlert(JSON.stringify(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request transaction history from the game engine
|
||||||
|
*/
|
||||||
|
function requestTransactionHistory() {
|
||||||
|
const message = {
|
||||||
|
event: "REQUEST::TRANSACTION::HISTORY",
|
||||||
|
data: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
A3API.SendAlert(JSON.stringify(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up a timer to refresh player data every 30 seconds
|
||||||
|
* Ensures the UI is updated with the latest information
|
||||||
|
*/
|
||||||
|
function setupRefreshTimer() {
|
||||||
|
setInterval(requestPlayerData, 30000); // Refresh every 30 seconds
|
||||||
|
}
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// #region DATA HANDLERS
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle player data received from the game engine
|
||||||
|
* @param {Array} data - List of player objects
|
||||||
|
*/
|
||||||
|
function handlePlayerDataRequest(data) {
|
||||||
|
bankState.players = data;
|
||||||
populatePlayerList();
|
populatePlayerList();
|
||||||
setupEventListeners();
|
|
||||||
loadTransactionHistory();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update balance displays in the header
|
/**
|
||||||
|
* Handle player funds data received from the game engine
|
||||||
|
* @param {Object} data - Object containing cash and balance
|
||||||
|
*/
|
||||||
|
function handlePlayerFundsRequest(data) {
|
||||||
|
console.log('Received funds data:', data);
|
||||||
|
|
||||||
|
// Parse the data if it's a string
|
||||||
|
if (typeof data === 'string') {
|
||||||
|
try {
|
||||||
|
data = JSON.parse(data);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Failed to parse data:', e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure we have valid numbers, default to 0 if null
|
||||||
|
bankState.wallet = data.cash !== null ? Number(data.cash) : 0;
|
||||||
|
bankState.account = data.balance !== null ? Number(data.balance) : 0;
|
||||||
|
bankState.pending = data.pending !== null ? Number(data.pending) : 0;
|
||||||
|
updateBalanceDisplays();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle transaction history data received from the game engine
|
||||||
|
* @param {Object} data - Object containing transaction history
|
||||||
|
*/
|
||||||
|
function handleTransactionHistoryRequest(data) {
|
||||||
|
console.log('Received transaction history:', data);
|
||||||
|
|
||||||
|
// Parse the data if it's a string
|
||||||
|
if (typeof data === 'string') {
|
||||||
|
try {
|
||||||
|
data = JSON.parse(data);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Failed to parse transaction history:', e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize empty array if history is null
|
||||||
|
bankState.transactions = [];
|
||||||
|
updateTransactionHistory();
|
||||||
|
}
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// #region UI UPDATES AND DISPLAY
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update balance displays in the header
|
||||||
|
*/
|
||||||
function updateBalanceDisplays() {
|
function updateBalanceDisplays() {
|
||||||
document.getElementById('walletBalance').textContent = `$${bankState.wallet.toLocaleString()}`;
|
const walletElement = document.getElementById('walletBalance');
|
||||||
document.getElementById('accountBalance').textContent = `$${bankState.account.toLocaleString()}`;
|
const accountElement = document.getElementById('accountBalance');
|
||||||
|
const pendingElement = document.getElementById('pending');
|
||||||
|
|
||||||
|
if (walletElement && accountElement && pendingElement) {
|
||||||
|
walletElement.textContent = `$${(bankState.wallet || 0).toLocaleString()}`;
|
||||||
|
accountElement.textContent = `$${(bankState.account || 0).toLocaleString()}`;
|
||||||
|
pendingElement.textContent = `$${(bankState.pending || 0).toLocaleString()}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populate the player selection dropdown
|
/**
|
||||||
|
* Populate the player selection dropdown
|
||||||
|
*/
|
||||||
function populatePlayerList() {
|
function populatePlayerList() {
|
||||||
const playerSelect = document.getElementById('playerSelect');
|
const playerSelect = document.getElementById('playerSelect');
|
||||||
playerSelect.innerHTML = '<option value="" disabled selected>Select Player</option>';
|
playerSelect.innerHTML = '<option value="" disabled selected>Select Player</option>';
|
||||||
|
|
||||||
bankState.players.forEach(player => {
|
bankState.players.forEach(player => {
|
||||||
const option = document.createElement('option');
|
const option = document.createElement('option');
|
||||||
option.value = player.id;
|
option.value = player.uid;
|
||||||
option.textContent = player.name;
|
option.textContent = player.name;
|
||||||
playerSelect.appendChild(option);
|
playerSelect.appendChild(option);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a new transaction to history
|
/**
|
||||||
function addTransaction(type, amount, details = '') {
|
* Update the transaction history display
|
||||||
const transaction = {
|
*/
|
||||||
type,
|
|
||||||
amount,
|
|
||||||
details,
|
|
||||||
timestamp: new Date().toISOString()
|
|
||||||
};
|
|
||||||
|
|
||||||
bankState.transactions.unshift(transaction);
|
|
||||||
updateTransactionHistory();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the transaction history display
|
|
||||||
function updateTransactionHistory() {
|
function updateTransactionHistory() {
|
||||||
const historyList = document.getElementById('transactionHistory');
|
const historyList = document.getElementById('transactionHistory');
|
||||||
|
if (!historyList) return;
|
||||||
|
|
||||||
historyList.innerHTML = '';
|
historyList.innerHTML = '';
|
||||||
|
|
||||||
|
if (!Array.isArray(bankState.transactions)) {
|
||||||
|
console.error('Transaction history is not an array:', bankState.transactions);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bankState.transactions.length === 0) {
|
||||||
|
const li = document.createElement('li');
|
||||||
|
li.className = 'history-item empty';
|
||||||
|
li.textContent = 'No transactions yet';
|
||||||
|
historyList.appendChild(li);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bankState.transactions.forEach(transaction => {
|
bankState.transactions.forEach(transaction => {
|
||||||
|
if (!transaction) return;
|
||||||
|
|
||||||
const li = document.createElement('li');
|
const li = document.createElement('li');
|
||||||
li.className = 'history-item';
|
li.className = 'history-item';
|
||||||
|
|
||||||
const isNegative = ['transfer_out', 'to_wallet'].includes(transaction.type);
|
const isNegative = ['transfer_out', 'to_wallet'].includes(transaction.type);
|
||||||
const amountClass = isNegative ? 'amount-negative' : 'amount-positive';
|
const amountClass = isNegative ? 'amount-negative' : 'amount-positive';
|
||||||
const amountPrefix = isNegative ? '-' : '+';
|
const amountPrefix = isNegative ? '-' : '+';
|
||||||
|
const amount = Math.abs(Number(transaction.amount) || 0);
|
||||||
|
|
||||||
li.innerHTML = `
|
li.innerHTML = `
|
||||||
<span class="transaction-type">${formatTransactionType(transaction.type)}</span>
|
<span class="transaction-type">${formatTransactionType(transaction.type)}</span>
|
||||||
<span class="transaction-details">${transaction.details}</span>
|
<span class="transaction-details">${transaction.details || ''}</span>
|
||||||
<span class="amount ${amountClass}">${amountPrefix}$${Math.abs(transaction.amount).toLocaleString()}</span>
|
<span class="amount ${amountClass}">${amountPrefix}$${amount.toLocaleString()}</span>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
historyList.appendChild(li);
|
historyList.appendChild(li);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format transaction type for display
|
/**
|
||||||
|
* Format transaction type for display
|
||||||
|
* @param {string} type - Transaction type code
|
||||||
|
* @returns {string} Formatted transaction type
|
||||||
|
*/
|
||||||
function formatTransactionType(type) {
|
function formatTransactionType(type) {
|
||||||
const types = {
|
const types = {
|
||||||
'to_wallet': 'To Wallet',
|
'to_wallet': 'To Wallet',
|
||||||
@ -85,63 +236,70 @@ function formatTransactionType(type) {
|
|||||||
return types[type] || type;
|
return types[type] || type;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up all form event listeners
|
// #endregion
|
||||||
function setupEventListeners() { // Handle transfers between wallet and account
|
|
||||||
document.getElementById('transferForm').addEventListener('submit', (e) => {
|
//=============================================================================
|
||||||
e.preventDefault();
|
// #region ACTION HANDLERS
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle transfer between wallet and account
|
||||||
|
*/
|
||||||
|
function handleTransfer() {
|
||||||
const amount = parseInt(document.getElementById('transferAmount').value);
|
const amount = parseInt(document.getElementById('transferAmount').value);
|
||||||
const transferType = document.getElementById('transferType').value;
|
const transferType = document.getElementById('transferType').value;
|
||||||
|
const event = transferType === 'to_wallet' ? 'WITHDRAW::FUNDS' : 'DEPOSIT::FUNDS';
|
||||||
|
const message = {
|
||||||
|
event: event,
|
||||||
|
data: [amount]
|
||||||
|
};
|
||||||
|
|
||||||
if (transferType === 'to_wallet') {
|
A3API.SendAlert(JSON.stringify(message));
|
||||||
if (amount > bankState.account) {
|
document.getElementById('transferAmount').value = '';
|
||||||
alert('Insufficient funds in account');
|
setTimeout(requestPlayerFunds, 500);
|
||||||
return;
|
|
||||||
}
|
|
||||||
bankState.account -= amount;
|
|
||||||
bankState.wallet += amount;
|
|
||||||
} else {
|
|
||||||
if (amount > bankState.wallet) {
|
|
||||||
alert('Insufficient funds in wallet');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bankState.wallet -= amount;
|
|
||||||
bankState.account += amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
addTransaction(transferType, amount);
|
|
||||||
updateBalanceDisplays();
|
|
||||||
e.target.reset();
|
|
||||||
}); // Transfer to Player
|
|
||||||
document.getElementById('transferPlayerForm').addEventListener('submit', (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
const amount = parseInt(document.getElementById('playerTransferAmount').value);
|
|
||||||
const playerId = document.getElementById('playerSelect').value;
|
|
||||||
const playerName = bankState.players.find(p => p.id.toString() === playerId)?.name;
|
|
||||||
|
|
||||||
if (amount > bankState.account) {
|
|
||||||
alert('Insufficient funds in account');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bankState.account -= amount;
|
|
||||||
addTransaction('transfer_out', amount, `To ${playerName}`);
|
|
||||||
updateBalanceDisplays();
|
|
||||||
e.target.reset();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Submit Timesheet
|
|
||||||
document.getElementById('timesheetForm').addEventListener('submit', (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
const hours = parseFloat(document.getElementById('hoursWorked').value);
|
|
||||||
const rate = parseInt(document.getElementById('hourlyRate').value);
|
|
||||||
const amount = Math.floor(hours * rate);
|
|
||||||
|
|
||||||
bankState.account += amount;
|
|
||||||
addTransaction('timesheet', amount, `${hours} hours @ $${rate}/hr`);
|
|
||||||
updateBalanceDisplays();
|
|
||||||
e.target.reset();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize when DOM is loaded
|
/**
|
||||||
document.addEventListener('DOMContentLoaded', initializeBank);
|
* Handle transfer to another player
|
||||||
|
*/
|
||||||
|
function handlePlayerTransfer() {
|
||||||
|
const amount = parseInt(document.getElementById('playerTransferAmount').value);
|
||||||
|
const playerUid = document.getElementById('playerSelect').value;
|
||||||
|
const message = {
|
||||||
|
event: 'TRANSFER::FUNDS',
|
||||||
|
data: [amount, playerUid]
|
||||||
|
};
|
||||||
|
|
||||||
|
A3API.SendAlert(JSON.stringify(message));
|
||||||
|
document.getElementById('playerTransferAmount').value = '';
|
||||||
|
setTimeout(requestPlayerFunds, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle timesheet submission
|
||||||
|
*/
|
||||||
|
function handleTimesheet() {
|
||||||
|
const message = {
|
||||||
|
event: 'SUBMIT::TIMESHEET',
|
||||||
|
data: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
A3API.SendAlert(JSON.stringify(message));
|
||||||
|
setTimeout(requestPlayerFunds, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// #region INITIALIZATION
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize when DOM is loaded
|
||||||
|
*/
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
initializeBank()
|
||||||
|
setupRefreshTimer();
|
||||||
|
});
|
||||||
|
|
||||||
|
// #endregion
|
@ -30,44 +30,42 @@ body {
|
|||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
|
||||||
max-width: 1280px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 0 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
header {
|
header {
|
||||||
background-color: var(--header-bg);
|
background-color: var(--header-bg);
|
||||||
color: var(--header-text);
|
color: var(--header-text);
|
||||||
padding: 1rem 0;
|
padding: 1rem 0;
|
||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||||
}
|
|
||||||
|
|
||||||
.header-content {
|
h1 {
|
||||||
|
font-size: 1.75rem;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: -0.025em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
max-width: 1280px;
|
max-width: 1280px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0 1rem;
|
padding: 0 1rem;
|
||||||
}
|
|
||||||
|
|
||||||
header h1 {
|
.balance-display {
|
||||||
font-size: 1.75rem;
|
|
||||||
font-weight: 600;
|
|
||||||
letter-spacing: -0.025em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.balance-display {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
background: rgba(255, 255, 255, 0.05);
|
background: rgba(255, 255, 255, 0.05);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
}
|
|
||||||
|
|
||||||
.balance-item {
|
.balance-divider {
|
||||||
|
width: 1px;
|
||||||
|
height: 24px;
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
margin: 0 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.75rem;
|
gap: 0.75rem;
|
||||||
@ -75,46 +73,39 @@ header h1 {
|
|||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
transition: all 0.2s ease-in-out;
|
transition: all 0.2s ease-in-out;
|
||||||
min-width: 140px;
|
min-width: 140px;
|
||||||
}
|
|
||||||
|
|
||||||
.balance-item:hover {
|
&:hover {
|
||||||
background: rgba(255, 255, 255, 0.1);
|
background: rgba(255, 255, 255, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.balance-icon {
|
.balance-info {
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.balance-info {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.125rem;
|
gap: 0.125rem;
|
||||||
}
|
|
||||||
|
|
||||||
.balance-label {
|
.balance-label {
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
color: rgba(255, 255, 255, 0.7);
|
color: rgba(255, 255, 255, 0.7);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.025em;
|
letter-spacing: 0.025em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.balance-amount {
|
.balance-amount {
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: var(--header-text);
|
color: var(--header-text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.balance-divider {
|
.container {
|
||||||
width: 1px;
|
max-width: 1280px;
|
||||||
height: 24px;
|
margin: 0 auto;
|
||||||
background: rgba(255, 255, 255, 0.1);
|
padding: 0 1rem;
|
||||||
margin: 0 0.25rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions-grid {
|
.actions-grid {
|
||||||
@ -122,9 +113,8 @@ header h1 {
|
|||||||
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
||||||
gap: 1.5rem;
|
gap: 1.5rem;
|
||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
}
|
|
||||||
|
|
||||||
.action-tile {
|
.action-tile {
|
||||||
background-color: var(--card-background);
|
background-color: var(--card-background);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -136,38 +126,37 @@ header h1 {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 1.5rem;
|
gap: 1.5rem;
|
||||||
aspect-ratio: 1 / 1;
|
aspect-ratio: 1 / 1;
|
||||||
}
|
|
||||||
|
|
||||||
.action-tile:hover {
|
&:hover {
|
||||||
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
|
||||||
transform: translateY(-4px);
|
transform: translateY(-4px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-tile:active {
|
&:active {
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-tile h2 {
|
h2 {
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-group {
|
.form-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
|
||||||
|
|
||||||
.form-group label {
|
label {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-group input, .form-group select {
|
input,
|
||||||
|
select {
|
||||||
padding: 0.75rem 1rem;
|
padding: 0.75rem 1rem;
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
@ -175,19 +164,39 @@ header h1 {
|
|||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
background-color: var(--card-background);
|
background-color: var(--card-background);
|
||||||
transition: all 0.2s ease-in-out;
|
transition: all 0.2s ease-in-out;
|
||||||
}
|
|
||||||
|
|
||||||
.form-group input:focus, .form-group select:focus {
|
&:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
border-color: var(--primary-color);
|
border-color: var(--primary-color);
|
||||||
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-group input:hover, .form-group select:hover {
|
&:hover {
|
||||||
border-color: var(--primary-color);
|
border-color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.submit-btn {
|
.pending-amount {
|
||||||
|
background: rgba(59, 130, 246, 0.1);
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.amount-label {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.amount-value {
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-btn {
|
||||||
background-color: var(--primary-color);
|
background-color: var(--primary-color);
|
||||||
color: white;
|
color: white;
|
||||||
border: none;
|
border: none;
|
||||||
@ -199,18 +208,20 @@ header h1 {
|
|||||||
transition: all 0.2s ease-in-out;
|
transition: all 0.2s ease-in-out;
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
margin-top: auto;
|
margin-top: auto;
|
||||||
}
|
|
||||||
|
|
||||||
.submit-btn:hover {
|
&:hover {
|
||||||
background-color: var(--primary-hover);
|
background-color: var(--primary-hover);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.submit-btn:active {
|
&:active {
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.history-section {
|
.history-section {
|
||||||
@ -227,26 +238,25 @@ header h1 {
|
|||||||
height: auto;
|
height: auto;
|
||||||
max-height: calc(100vw / 3);
|
max-height: calc(100vw / 3);
|
||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
}
|
|
||||||
|
|
||||||
.history-section:hover {
|
&:hover {
|
||||||
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
|
||||||
transform: translateY(-4px);
|
transform: translateY(-4px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.history-section:active {
|
&:active {
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.history-section h2 {
|
h2 {
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.history-list {
|
.history-list {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@ -255,28 +265,26 @@ header h1 {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
}
|
|
||||||
|
|
||||||
/* Customize scrollbar for webkit browsers */
|
&::-webkit-scrollbar {
|
||||||
.history-list::-webkit-scrollbar {
|
|
||||||
width: 6px;
|
width: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.history-list::-webkit-scrollbar-track {
|
&::-webkit-scrollbar-track {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
margin: 0.5rem;
|
margin: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.history-list::-webkit-scrollbar-thumb {
|
&::-webkit-scrollbar-thumb {
|
||||||
background-color: rgba(0, 0, 0, 0.1);
|
background-color: rgba(0, 0, 0, 0.1);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
|
||||||
|
|
||||||
.history-list::-webkit-scrollbar-thumb:hover {
|
&:hover {
|
||||||
background-color: rgba(0, 0, 0, 0.2);
|
background-color: rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.history-item {
|
.history-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -286,51 +294,43 @@ header h1 {
|
|||||||
transition: all 0.2s ease-in-out;
|
transition: all 0.2s ease-in-out;
|
||||||
border: none;
|
border: none;
|
||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
||||||
}
|
|
||||||
|
|
||||||
.history-item:last-child {
|
.transaction-type {
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.transaction-details {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.amount {
|
||||||
|
&.amount-positive {
|
||||||
|
color: var(--success-color);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.amount-negative {
|
||||||
|
color: var(--error-color);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.history-item:hover {
|
&:hover {
|
||||||
background-color: var(--tile-hover);
|
background-color: var(--tile-hover);
|
||||||
box-shadow: 0 4px 6px var(--shadow-color);
|
box-shadow: 0 4px 6px var(--shadow-color);
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.history-item:active {
|
&:active {
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
box-shadow: 0 2px 4px var(--shadow-color);
|
box-shadow: 0 2px 4px var(--shadow-color);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
.transaction-type {
|
}
|
||||||
font-weight: 500;
|
|
||||||
color: var(--text-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.transaction-details {
|
|
||||||
color: var(--text-secondary);
|
|
||||||
font-size: 0.875rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.amount-positive {
|
|
||||||
color: var(--success-color);
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.amount-negative {
|
|
||||||
color: var(--error-color);
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error-message {
|
|
||||||
color: var(--error-color);
|
|
||||||
font-size: 0.875rem;
|
|
||||||
margin-top: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.success-message {
|
|
||||||
color: var(--success-color);
|
|
||||||
font-size: 0.875rem;
|
|
||||||
margin-top: 0.25rem;
|
|
||||||
}
|
}
|
114
addons/briefing/README.md
Normal file
114
addons/briefing/README.md
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
# Forge Briefing Module
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
The Briefing module provides a comprehensive presentation and lecture system for the Forge client. It includes features for creating interactive slideshows, managing presentations, and delivering lectures with synchronized audio and visual elements.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
- forge_client_main
|
||||||
|
|
||||||
|
## Authors
|
||||||
|
- J. Schmidt
|
||||||
|
- Creedcoder
|
||||||
|
- IDSolutions
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### Presentation System
|
||||||
|
1. **Slide Show Management** (`fnc_initSlideShow.sqf`)
|
||||||
|
- Initializes interactive slide shows
|
||||||
|
- Configures display screens and controllers
|
||||||
|
- Sets up image sequences and timing
|
||||||
|
- Manages presentation flow and transitions
|
||||||
|
|
||||||
|
2. **Presentation Controls**
|
||||||
|
- **Start Slide Show** (`fnc_startSlideShow.sqf`)
|
||||||
|
- Initiates the presentation sequence
|
||||||
|
- Synchronizes audio and visual elements
|
||||||
|
- Manages presentation state
|
||||||
|
- **Next Image** (`fnc_nextImage.sqf`)
|
||||||
|
- Advances to the next slide
|
||||||
|
- Updates display screens
|
||||||
|
- Maintains presentation state
|
||||||
|
- **Previous Image** (`fnc_prevImage.sqf`)
|
||||||
|
- Returns to the previous slide
|
||||||
|
- Updates display screens
|
||||||
|
- Maintains presentation state
|
||||||
|
- **End Slide Show** (`fnc_endSlideShow.sqf`)
|
||||||
|
- Terminates the presentation
|
||||||
|
- Cleans up resources
|
||||||
|
- Resets presentation state
|
||||||
|
|
||||||
|
3. **Lecture System**
|
||||||
|
- **Spawn Lecture** (`fnc_spawnLecture.sqf`)
|
||||||
|
- Initiates AI-driven lectures
|
||||||
|
- Manages speaker animations
|
||||||
|
- Controls presentation timing
|
||||||
|
- **Spawn Presentation** (`fnc_spawnPresentation.sqf`)
|
||||||
|
- Creates automated presentations
|
||||||
|
- Manages slide timing
|
||||||
|
- Controls visual transitions
|
||||||
|
|
||||||
|
### Presentation Features
|
||||||
|
1. **Interactive Controls**
|
||||||
|
- Manual slide navigation
|
||||||
|
- Auto-scroll capability
|
||||||
|
- Presentation state management
|
||||||
|
- Speaker control integration
|
||||||
|
|
||||||
|
2. **Visual Elements**
|
||||||
|
- Multiple display screen support
|
||||||
|
- Synchronized image transitions
|
||||||
|
- Customizable timing
|
||||||
|
- Power-of-2 image optimization
|
||||||
|
|
||||||
|
3. **Audio Integration**
|
||||||
|
- Speaker synchronization
|
||||||
|
- Topic-based conversations
|
||||||
|
- Sentence-specific playback
|
||||||
|
- Multi-speaker support
|
||||||
|
|
||||||
|
## Event Handlers
|
||||||
|
The module uses several event handlers for initialization and execution:
|
||||||
|
- `XEH_preInit.sqf`: Pre-initialization setup
|
||||||
|
- `XEH_postInit.sqf`: Post-initialization tasks
|
||||||
|
- `XEH_preStart.sqf`: Pre-start configuration
|
||||||
|
- `XEH_postInit_client.sqf`: Client-specific post-initialization
|
||||||
|
- `XEH_preInit_server.sqf`: Server-specific pre-initialization
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
To use the briefing module:
|
||||||
|
1. Ensure the module is properly loaded in your mission
|
||||||
|
2. Set up presentation screens and controllers
|
||||||
|
3. Configure slide shows or lectures:
|
||||||
|
```sqf
|
||||||
|
// Initialize a slide show
|
||||||
|
[Screen01, [Controller01], ["images/folder/image.paa"]] call forge_client_briefing_fnc_initSlideShow;
|
||||||
|
|
||||||
|
// Start a lecture
|
||||||
|
[player, "topic", "sentence"] call forge_client_briefing_fnc_spawnLecture;
|
||||||
|
|
||||||
|
// Create a presentation
|
||||||
|
[screen, [["texture.paa", 5]]] call forge_client_briefing_fnc_spawnPresentation;
|
||||||
|
```
|
||||||
|
4. Control the presentation using the provided functions
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
Debug mode can be enabled by uncommenting the following in `script_component.hpp`:
|
||||||
|
```cpp
|
||||||
|
#define DEBUG_MODE_FULL
|
||||||
|
```
|
||||||
|
|
||||||
|
## Version Information
|
||||||
|
Version information is managed through the main Forge client system configuration.
|
||||||
|
|
||||||
|
## Technical Details
|
||||||
|
- Support for multiple display screens
|
||||||
|
- Synchronized audio-visual presentations
|
||||||
|
- Interactive control system
|
||||||
|
- AI-driven lecture capabilities
|
||||||
|
- Power-of-2 image optimization
|
||||||
|
- State management for presentations
|
||||||
|
- Multi-speaker support
|
||||||
|
- Customizable timing controls
|
||||||
|
- Resource cleanup on completion
|
||||||
|
- Error handling and validation
|
@ -1,15 +1,20 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Author: PDT for J. Schmidt
|
* Author: IDSolutions
|
||||||
ends the slide show
|
* Ends the slide show
|
||||||
|
*
|
||||||
Arguments:
|
* Arguments:
|
||||||
0: _controller <OBJECT> - object that controls the slide show
|
* 0: Controller <OBJECT> - object that controls the slide show
|
||||||
|
*
|
||||||
Return Value:
|
* Return Value:
|
||||||
<BOOL> - true if the slide show was ended; false if not
|
* Boolean - true if the slide show was ended; false if not
|
||||||
*/
|
*
|
||||||
|
* Example:
|
||||||
|
* [controller] call ace_briefing_fnc_endSlideShow
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
|
||||||
params [["_controller", objNull]];
|
params [["_controller", objNull]];
|
||||||
|
|
||||||
|
@ -1,24 +1,26 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Author: PDT for J. Schmidt
|
* Author: IDSolutions
|
||||||
sets up a slide show
|
* Sets up a slide show
|
||||||
|
*
|
||||||
Arguments:
|
* Arguments:
|
||||||
0: _screen <ARRAY> - array of objects to display images on
|
* 0: _screen <ARRAY> - array of objects to display images on
|
||||||
1: _controllers <ARRAY> - array of objects to use are controlers
|
* 1: _controllers <ARRAY> - array of objects to use are controlers
|
||||||
2: _images <ARRAY> - array of image paths; images should be powers of 2
|
* 2: _images <ARRAY> - array of image paths; images should be powers of 2
|
||||||
3: _autoScroll <BOOL> - should the image auto-scroll
|
* 3: _autoScroll <BOOL> - should the image auto-scroll
|
||||||
4: _units <ARRAY> - unit(s) that should speak
|
* 4: _units <ARRAY> - unit(s) that should speak
|
||||||
5: _topic <STRING> - conversation topic
|
* 5: _topic <STRING> - conversation topic
|
||||||
6: _sentence <STRING> - conversation sentence, "" = play all
|
* 6: _sentence <STRING> - conversation sentence, "" = play all
|
||||||
|
*
|
||||||
Return Value:
|
* Return Value:
|
||||||
<BOOL> - true if slide show was setup; false if not
|
* <BOOL> - true if slide show was setup; false if not
|
||||||
|
*
|
||||||
Example:
|
* Example:
|
||||||
[Screen01, [Controler01], ["images/folder/image.paa"]] call forge_client_briefing_fnc_initSlideShow;
|
* [Screen01, [Controler01], ["images/folder/image.paa"]] call forge_client_briefing_fnc_initSlideShow;
|
||||||
*/
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
|
||||||
params [["_screens", []], ["_controllers", []], ["_images", []], ["_autoScroll", false], ["_units", []], ["_topic", ""], ["_sentence", ""]];
|
params [["_screens", []], ["_controllers", []], ["_images", []], ["_autoScroll", false], ["_units", []], ["_topic", ""], ["_sentence", ""]];
|
||||||
|
|
||||||
|
@ -1,15 +1,20 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Author: PDT for J. Schmidt
|
* Author: IDSolutions
|
||||||
displays the next image
|
* Displays the next image
|
||||||
|
*
|
||||||
Arguments:
|
* Arguments:
|
||||||
0: _controller <OBJECT> - object that controls the slide show
|
* 0: _controller <OBJECT> - object that controls the slide show
|
||||||
|
*
|
||||||
Return Value:
|
* Return Value:
|
||||||
<BOOL> - true if the next image was displayed; false if not
|
* 0: _return <BOOL> - true if the next image was displayed; false if not
|
||||||
*/
|
*
|
||||||
|
* Example:
|
||||||
|
* [controller] call ace_briefing_fnc_nextImage
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
|
||||||
params [["_controller", objNull]];
|
params [["_controller", objNull]];
|
||||||
|
|
||||||
|
@ -1,15 +1,20 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Author: PDT for J. Schmidt
|
* Author: IDSolutions
|
||||||
displays the previous image
|
* Displays the previous image
|
||||||
|
*
|
||||||
Arguments:
|
* Arguments:
|
||||||
0: _controller <OBJECT> - object that controls the slide show
|
* 0: _controller <OBJECT> - object that controls the slide show
|
||||||
|
*
|
||||||
Return Value:
|
* Return Value:
|
||||||
<BOOL> - true if the previous image was displayed; false if not
|
* 0: _return <BOOL> - true if the previous image was displayed; false if not
|
||||||
*/
|
*
|
||||||
|
* Example:
|
||||||
|
* [controller] call forge_briefing_fnc_prevImage
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
|
||||||
params [["_controller", objNull]];
|
params [["_controller", objNull]];
|
||||||
|
|
||||||
|
@ -1,21 +1,25 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Name: forge_client_briefing_fnc_spawnLecture
|
* Author: IDSolutions
|
||||||
Date: 8/6/2022
|
* AI plays a given sentence/conversation
|
||||||
Version: 1.0
|
*
|
||||||
Author: J. Schmidt
|
* Arguments:
|
||||||
|
* 0: Unit that is playing the given sentence/conversation <OBJECT>
|
||||||
Description:
|
* 1: Topic that is being talked about <STRING>
|
||||||
AI plays a given sentence/conversation.
|
* 2: Sentence partaining to the topic at hand <STRING>
|
||||||
|
*
|
||||||
Parameter(s):
|
* Return Value:
|
||||||
0: Unit that is playing the given sentence/conversation. <OBJECT>
|
* None
|
||||||
1: Topic that is being talked about. <STRING>
|
*
|
||||||
2: Sentence partaining to the topic at hand. <STRING>
|
* Example:
|
||||||
*/
|
* [player, "topic", "sentence"] call forge_client_briefing_fnc_spawnLecture
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
|
||||||
params ["_unit", "_topic", "_sentence"];
|
params ["_unit", "_topic", "_sentence"];
|
||||||
|
|
||||||
FORGE_Briefing_inProgress = true;
|
FORGE_Briefing_inProgress = true;
|
||||||
publicVariable "FORGE_Briefing_inProgress";
|
publicVariable "FORGE_Briefing_inProgress";
|
||||||
|
|
||||||
|
@ -1,20 +1,23 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Name: forge_client_briefing_fnc_spawnLecture
|
* Author: IDSolutions
|
||||||
Date: 8/6/2022
|
* Object displays a slideshow presentation
|
||||||
Version: 1.0
|
*
|
||||||
Author: J. Schmidt
|
* Arguments:
|
||||||
|
* 0: Object that will display the presentation <OBJECT>
|
||||||
Description:
|
* 1: Slides that will be used for the presentation <ARRAY>
|
||||||
Object displays a slideshow presentation.
|
* - 0: Texture used for the Slide <STRING>
|
||||||
|
* - 1: Amount of Time the Slide will display <NUMBER>
|
||||||
Parameter(s):
|
*
|
||||||
0: Object that will display the presentation. <OBJECT>
|
* Return Value:
|
||||||
1: Slides that will be used for the presentation. <ARRAY>
|
* None
|
||||||
1-0: Texture used for the Slide. <STRING>
|
*
|
||||||
1-1: Amount of Time the Slide will display. <NUMBER>
|
* Example:
|
||||||
*/
|
* [screen, [["texture.paa", 5]]] call forge_client_briefing_fnc_spawnLecture
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
|
||||||
params ["_object", "_slides"];
|
params ["_object", "_slides"];
|
||||||
|
|
||||||
|
@ -1,15 +1,20 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Author: PDT for J. Schmidt
|
* Author: IDSolutions
|
||||||
starts the slideshow
|
* Starts the slideshow
|
||||||
|
*
|
||||||
Arguments:
|
* Arguments:
|
||||||
0: _controller <OBJECT> - object that controls the slide show
|
* 0: Controller <OBJECT> - object that controls the slide show
|
||||||
|
*
|
||||||
Return Value:
|
* Return Value:
|
||||||
<BOOL> - true if slide show was started
|
* Boolean - true if slide show was started
|
||||||
*/
|
*
|
||||||
|
* Example:
|
||||||
|
* [controller] call ace_fnc_startSlideShow
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
|
||||||
params [["_controller", objNull], ["_units", []], ["_topic", ""], ["_sentence", ""]];
|
params [["_controller", objNull], ["_units", []], ["_topic", ""], ["_sentence", ""]];
|
||||||
|
|
||||||
|
1
addons/common/$PBOPREFIX$
Normal file
1
addons/common/$PBOPREFIX$
Normal file
@ -0,0 +1 @@
|
|||||||
|
z\forge_client\addons\common
|
19
addons/common/CfgEventHandlers.hpp
Normal file
19
addons/common/CfgEventHandlers.hpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
class Extended_PreStart_EventHandlers {
|
||||||
|
class ADDON {
|
||||||
|
init = QUOTE(call COMPILE_FILE(XEH_preStart));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Extended_PreInit_EventHandlers {
|
||||||
|
class ADDON {
|
||||||
|
init = QUOTE(call COMPILE_FILE(XEH_preInit));
|
||||||
|
serverInit = QUOTE(call COMPILE_FILE(XEH_preInit_server));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Extended_PostInit_EventHandlers {
|
||||||
|
class ADDON {
|
||||||
|
init = QUOTE(call COMPILE_FILE(XEH_postInit));
|
||||||
|
clientInit = QUOTE(call COMPILE_FILE(XEH_postInit_client));
|
||||||
|
};
|
||||||
|
};
|
3
addons/common/XEH_PREP.hpp
Normal file
3
addons/common/XEH_PREP.hpp
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
PREP(actorStateGet);
|
||||||
|
PREP(actorStateSet);
|
||||||
|
PREP(getPlayer);
|
1
addons/common/XEH_postInit.sqf
Normal file
1
addons/common/XEH_postInit.sqf
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "script_component.hpp"
|
1
addons/common/XEH_postInit_client.sqf
Normal file
1
addons/common/XEH_postInit_client.sqf
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "script_component.hpp"
|
8
addons/common/XEH_preInit.sqf
Normal file
8
addons/common/XEH_preInit.sqf
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
|
ADDON = false;
|
||||||
|
|
||||||
|
PREP_RECOMPILE_START;
|
||||||
|
#include "XEH_PREP.hpp"
|
||||||
|
PREP_RECOMPILE_END;
|
||||||
|
|
||||||
|
ADDON = true;
|
1
addons/common/XEH_preInit_server.sqf
Normal file
1
addons/common/XEH_preInit_server.sqf
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "script_component.hpp"
|
2
addons/common/XEH_preStart.sqf
Normal file
2
addons/common/XEH_preStart.sqf
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
|
#include "XEH_PREP.hpp"
|
16
addons/common/config.cpp
Normal file
16
addons/common/config.cpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
class CfgPatches {
|
||||||
|
class ADDON {
|
||||||
|
name = COMPONENT_NAME;
|
||||||
|
units[] = {};
|
||||||
|
weapons[] = {};
|
||||||
|
requiredVersion = REQUIRED_VERSION;
|
||||||
|
requiredAddons[] = {"forge_client_main"};
|
||||||
|
authors[] = {"J. Schmidt", "Creedcoder"};
|
||||||
|
author = "IDSolutions";
|
||||||
|
VERSION_CONFIG;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "CfgEventHandlers.hpp"
|
43
addons/common/functions/fnc_actorStateGet.sqf
Normal file
43
addons/common/functions/fnc_actorStateGet.sqf
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Author: IDSolutions
|
||||||
|
* Gets the current state of a player
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: Player <OBJECT>
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* Player State <HASHMAP>
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* _state = [player] call forge_client_common_fnc_actorStateGet
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
|
||||||
|
params [["_player", objNull, [objNull]]];
|
||||||
|
|
||||||
|
private _loadout = getUnitLoadout _player;
|
||||||
|
private _pos = getPosASL _player;
|
||||||
|
private _dir = getDir _player;
|
||||||
|
private _stance = stance _player;
|
||||||
|
private _phone = GETVAR(_player,FORGE_Phone,QUOTE(000-000-0000));
|
||||||
|
private _email = GETVAR(_player,FORGE_Email,QUOTE(player@example.com));
|
||||||
|
private _bank = GETVAR(_player,FORGE_Bank,0);
|
||||||
|
private _cash = GETVAR(_player,FORGE_Cash,0);
|
||||||
|
private _state = lifeState _player;
|
||||||
|
|
||||||
|
private _hash = createHashMap;
|
||||||
|
|
||||||
|
_hash set ["loadout", _loadout];
|
||||||
|
_hash set ["position", _pos];
|
||||||
|
_hash set ["direction", _dir];
|
||||||
|
_hash set ["stance", _stance];
|
||||||
|
_hash set ["phone", _phone];
|
||||||
|
_hash set ["email", _email];
|
||||||
|
_hash set ["bank", _bank];
|
||||||
|
_hash set ["cash", _cash];
|
||||||
|
_hash set ["state", _state];
|
||||||
|
|
||||||
|
_hash
|
65
addons/common/functions/fnc_actorStateSet.sqf
Normal file
65
addons/common/functions/fnc_actorStateSet.sqf
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Author: IDSolutions
|
||||||
|
* Sets the state of a player
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: Player <OBJECT>
|
||||||
|
* 1: Data <STRING>
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* Unit State <HASHMAP>
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [player, _data] call forge_client_common_fnc_actorStateSet
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
|
||||||
|
params [["_player", objNull, [objNull]], ["_data", "", [""]]];
|
||||||
|
private _hash = createHashMap;
|
||||||
|
|
||||||
|
if (isNull _player || _data isEqualTo "") exitWith {
|
||||||
|
diag_log text format ["[FORGE:Player:Actor] Invalid player or data: %1", _player];
|
||||||
|
};
|
||||||
|
|
||||||
|
(parseSimpleArray _data) params ["_uid", "_loadout", "_pos", "_dir", "_stance", "_email", "_phone", "_bank", "_cash", "_state"];
|
||||||
|
|
||||||
|
_player setUnitLoadout _loadout;
|
||||||
|
|
||||||
|
if !(isNil "_pos") then {
|
||||||
|
_player setPosASL _pos;
|
||||||
|
|
||||||
|
private _pAlt = ((getPosATLVisual player) select 2);
|
||||||
|
private _pVelZ = ((velocity player) select 2);
|
||||||
|
if (_pAlt > 5 && _pVelZ < 0) then {
|
||||||
|
player setVelocity [0, 0, 0];
|
||||||
|
player setPosATL [((getPosATLVisual player) select 0), ((getPosATLVisual player) select 1), 1];
|
||||||
|
hint "You logged off mid air. You were moved to a safe position on the ground.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
if !(isNil "_dir") then {
|
||||||
|
_player setDir _dir;
|
||||||
|
};
|
||||||
|
|
||||||
|
_player playAction _stance;
|
||||||
|
SETPVAR(_player,FORGE_Phone,_phone);
|
||||||
|
SETPVAR(_player,FORGE_Email,_email);
|
||||||
|
SETPVAR(_player,FORGE_Bank,_bank);
|
||||||
|
SETPVAR(_player,FORGE_Cash,_cash);
|
||||||
|
SETPVAR(_player,FORGE_State,_state);
|
||||||
|
|
||||||
|
_hash set ["uid", _uid];
|
||||||
|
_hash set ["loadout", _loadout];
|
||||||
|
_hash set ["position", _pos];
|
||||||
|
_hash set ["direction", _dir];
|
||||||
|
_hash set ["stance", _stance];
|
||||||
|
_hash set ["phone", _phone];
|
||||||
|
_hash set ["email", _email];
|
||||||
|
_hash set ["bank", _bank];
|
||||||
|
_hash set ["cash", _cash];
|
||||||
|
_hash set ["state", _state];
|
||||||
|
|
||||||
|
_hash
|
27
addons/common/functions/fnc_getPlayer.sqf
Normal file
27
addons/common/functions/fnc_getPlayer.sqf
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Author: IDSolutions
|
||||||
|
* Gets a player object by UID.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: Player UID <STRING>
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* Player object or objNull if not found <OBJECT>
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* ["76561198012345678"] call forge_client_common_fnc_getPlayer
|
||||||
|
*
|
||||||
|
* Public: Yes
|
||||||
|
*/
|
||||||
|
|
||||||
|
params ["_uid"];
|
||||||
|
|
||||||
|
private _player = objNull;
|
||||||
|
|
||||||
|
{
|
||||||
|
if ((getPlayerUID _x) isEqualTo _uid) exitWith { _player = _x; };
|
||||||
|
} forEach allPlayers;
|
||||||
|
|
||||||
|
_player
|
0
addons/common/functions/fnc_vehicleStateGet.sqf
Normal file
0
addons/common/functions/fnc_vehicleStateGet.sqf
Normal file
0
addons/common/functions/fnc_vehicleStateSet.sqf
Normal file
0
addons/common/functions/fnc_vehicleStateSet.sqf
Normal file
16
addons/common/script_component.hpp
Normal file
16
addons/common/script_component.hpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#define COMPONENT common
|
||||||
|
#define COMPONENT_BEAUTIFIED Common
|
||||||
|
#include "\z\forge_client\addons\main\script_mod.hpp"
|
||||||
|
|
||||||
|
// #define DEBUG_MODE_FULL
|
||||||
|
// #define DISABLE_COMPILE_CACHE
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED_COMMON
|
||||||
|
#define DEBUG_MODE_FULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_SETTINGS_COMMON
|
||||||
|
#define DEBUG_SETTINGS DEBUG_SETTINGS_COMMON
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "\z\forge_client\addons\main\script_macros.hpp"
|
125
addons/db/README.md
Normal file
125
addons/db/README.md
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
# Forge Database Module
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
The Database module provides a comprehensive data persistence system for the Forge client. It includes features for managing player data, organization information, and game state persistence using the ArmaDragonflyClient database system.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
- forge_client_main
|
||||||
|
- ArmaDragonflyClient
|
||||||
|
|
||||||
|
## Authors
|
||||||
|
- J. Schmidt
|
||||||
|
- Creedcoder
|
||||||
|
- IDSolutions
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### Database System
|
||||||
|
1. **Server Communication** (`fnc_requestServerDB.sqf`)
|
||||||
|
- Handles client-server database communication
|
||||||
|
- Manages asynchronous database operations
|
||||||
|
- Provides callback support for data retrieval
|
||||||
|
- Ensures data consistency across clients
|
||||||
|
|
||||||
|
2. **Data Management**
|
||||||
|
- **Player Data**
|
||||||
|
- Armory unlocks
|
||||||
|
- Garage unlocks
|
||||||
|
- Locker contents
|
||||||
|
- Vehicle inventory
|
||||||
|
- Financial information
|
||||||
|
- Contact details
|
||||||
|
- Organization membership
|
||||||
|
- Player statistics
|
||||||
|
- Equipment loadouts
|
||||||
|
- Position and state
|
||||||
|
|
||||||
|
- **Organization Data**
|
||||||
|
- Member information
|
||||||
|
- Asset tracking
|
||||||
|
- Financial records
|
||||||
|
- Reputation system
|
||||||
|
- Activity logs
|
||||||
|
- Creation timestamps
|
||||||
|
- Modification history
|
||||||
|
|
||||||
|
3. **Persistence Features**
|
||||||
|
- Automatic data saving
|
||||||
|
- Periodic state synchronization
|
||||||
|
- Data validation and sanitization
|
||||||
|
- Error recovery mechanisms
|
||||||
|
- Transaction logging
|
||||||
|
- Data versioning
|
||||||
|
|
||||||
|
### Data Operations
|
||||||
|
1. **Storage Operations**
|
||||||
|
- Hash-based storage (HSET)
|
||||||
|
- Bulk data operations
|
||||||
|
- Atomic transactions
|
||||||
|
- Data serialization
|
||||||
|
- String normalization
|
||||||
|
|
||||||
|
2. **Retrieval Operations**
|
||||||
|
- Hash-based retrieval (HGET)
|
||||||
|
- Bulk data loading
|
||||||
|
- Data deserialization
|
||||||
|
- Error handling
|
||||||
|
- Default value management
|
||||||
|
|
||||||
|
3. **Synchronization**
|
||||||
|
- Client-server sync
|
||||||
|
- Real-time updates
|
||||||
|
- Conflict resolution
|
||||||
|
- State verification
|
||||||
|
- Data integrity checks
|
||||||
|
|
||||||
|
## Event Handlers
|
||||||
|
The module uses several event handlers for initialization and execution:
|
||||||
|
- `XEH_preInit.sqf`: Pre-initialization setup
|
||||||
|
- `XEH_postInit.sqf`: Post-initialization tasks
|
||||||
|
- `XEH_preStart.sqf`: Pre-start configuration
|
||||||
|
- `XEH_postInit_client.sqf`: Client-specific post-initialization
|
||||||
|
- `XEH_preInit_server.sqf`: Server-specific pre-initialization
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
To use the database module:
|
||||||
|
1. Ensure the module is properly loaded in your mission
|
||||||
|
2. Initialize database connections
|
||||||
|
3. Perform database operations:
|
||||||
|
```sqf
|
||||||
|
// Request data from server
|
||||||
|
["hgetall", "Hello World!", {
|
||||||
|
systemChat format ["Message: %1", _this];
|
||||||
|
}] call forge_db_fnc_requestServerDB;
|
||||||
|
|
||||||
|
// Save player data
|
||||||
|
[] call forge_client_init_fnc_playerDBSave;
|
||||||
|
|
||||||
|
// Load player data
|
||||||
|
[] call forge_client_init_fnc_playerDBLoad;
|
||||||
|
```
|
||||||
|
4. Handle database callbacks and responses
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
Debug mode can be enabled by uncommenting the following in `script_component.hpp`:
|
||||||
|
```cpp
|
||||||
|
#define DEBUG_MODE_FULL
|
||||||
|
```
|
||||||
|
|
||||||
|
## Version Information
|
||||||
|
Version information is managed through the main Forge client system configuration.
|
||||||
|
|
||||||
|
## Technical Details
|
||||||
|
- Asynchronous database operations
|
||||||
|
- Callback-based response handling
|
||||||
|
- Data serialization and normalization
|
||||||
|
- Error handling and recovery
|
||||||
|
- Transaction logging
|
||||||
|
- State management
|
||||||
|
- Data validation
|
||||||
|
- Conflict resolution
|
||||||
|
- Real-time synchronization
|
||||||
|
- Bulk operation support
|
||||||
|
- Atomic transactions
|
||||||
|
- Data versioning
|
||||||
|
- Integrity verification
|
@ -1,10 +1,7 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_db_fnc_requestServerDB
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Sends database requests to the server using CBA events
|
* Sends database requests to the server using CBA events
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
@ -14,6 +11,11 @@
|
|||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* Request ID <STRING>
|
* Request ID <STRING>
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* ["hgetall", "Hello World!", { systemChat format ["Message: %1", _this]; }] call forge_db_fnc_requestServerDB;
|
||||||
|
*
|
||||||
|
* Public: Yes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
params [
|
params [
|
||||||
|
90
addons/dialogue/README.md
Normal file
90
addons/dialogue/README.md
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
# Forge Dialogue Module
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
The Dialogue module provides a comprehensive AI conversation system for the Forge client. It enables dynamic interactions between players and AI units, supporting topic-based conversations, sentence management, and AI behavior control.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
- forge_client_main
|
||||||
|
|
||||||
|
## Authors
|
||||||
|
- J. Schmidt
|
||||||
|
- Creedcoder
|
||||||
|
- IDSolutions
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### AI Dialogue System
|
||||||
|
1. **AI Selection** (`fnc_selectAI.sqf`)
|
||||||
|
- Manages AI unit selection for dialogue
|
||||||
|
- Controls AI behavior during conversations
|
||||||
|
- Handles unit state management
|
||||||
|
- Disables AI actions during dialogue
|
||||||
|
|
||||||
|
2. **Dialogue Management** (`fnc_selectDialogue.sqf`)
|
||||||
|
- Topic-based conversation system
|
||||||
|
- Sentence management and playback
|
||||||
|
- AI unit synchronization
|
||||||
|
- Conversation flow control
|
||||||
|
|
||||||
|
3. **Conversation Features**
|
||||||
|
- **Topic Management**
|
||||||
|
- Dynamic topic selection
|
||||||
|
- Context-aware conversations
|
||||||
|
- Topic-based responses
|
||||||
|
- Conversation branching
|
||||||
|
|
||||||
|
- **Sentence Control**
|
||||||
|
- Sentence playback
|
||||||
|
- Timing management
|
||||||
|
- Response coordination
|
||||||
|
- Conversation state tracking
|
||||||
|
|
||||||
|
- **AI Behavior**
|
||||||
|
- Animation control
|
||||||
|
- Movement management
|
||||||
|
- State synchronization
|
||||||
|
- Interaction handling
|
||||||
|
|
||||||
|
## Event Handlers
|
||||||
|
The module uses several event handlers for initialization and execution:
|
||||||
|
- `XEH_preInit.sqf`: Pre-initialization setup
|
||||||
|
- `XEH_postInit.sqf`: Post-initialization tasks
|
||||||
|
- `XEH_preStart.sqf`: Pre-start configuration
|
||||||
|
- `XEH_postInit_client.sqf`: Client-specific post-initialization
|
||||||
|
- `XEH_preInit_server.sqf`: Server-specific pre-initialization
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
To use the dialogue module:
|
||||||
|
1. Ensure the module is properly loaded in your mission
|
||||||
|
2. Select AI units for dialogue:
|
||||||
|
```sqf
|
||||||
|
// Select AI units for dialogue
|
||||||
|
[units group player] call forge_client_dialogue_fnc_selectAI;
|
||||||
|
|
||||||
|
// Select specific dialogue for AI
|
||||||
|
[units, [["topic", "sentence"]]] call forge_client_dialogue_fnc_selectDialogue;
|
||||||
|
```
|
||||||
|
3. Manage conversation flow and AI behavior
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
Debug mode can be enabled by uncommenting the following in `script_component.hpp`:
|
||||||
|
```cpp
|
||||||
|
#define DEBUG_MODE_FULL
|
||||||
|
```
|
||||||
|
|
||||||
|
## Version Information
|
||||||
|
Version information is managed through the main Forge client system configuration.
|
||||||
|
|
||||||
|
## Technical Details
|
||||||
|
- Topic-based conversation system
|
||||||
|
- AI behavior control
|
||||||
|
- Sentence management
|
||||||
|
- State synchronization
|
||||||
|
- Animation handling
|
||||||
|
- Movement control
|
||||||
|
- Interaction management
|
||||||
|
- Conversation flow control
|
||||||
|
- Response coordination
|
||||||
|
- Error handling
|
||||||
|
- Debug support
|
||||||
|
- Event system integration
|
@ -1,10 +1,7 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_dialogue_fnc_selectAI
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Selects AI for dialogue
|
* Selects AI for dialogue
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
@ -12,6 +9,11 @@
|
|||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [units group player] call FUNC(selectAI);
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
*/
|
*/
|
||||||
|
|
||||||
params [["_units", [], [[]]]];
|
params [["_units", [], [[]]]];
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Forge Garage Module
|
# Forge Garage Module
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
The Garage module provides a comprehensive vehicle management system for the Forge client. It includes features for storing, spawning, and managing vehicles in a garage environment.
|
The Garage module provides a comprehensive vehicle management system for the Forge client. It includes features for storing, spawning, and managing vehicles in a garage environment, with support for various vehicle types and states.
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
- forge_client_main
|
- forge_client_main
|
||||||
@ -16,21 +16,72 @@ The Garage module provides a comprehensive vehicle management system for the For
|
|||||||
### Garage System
|
### Garage System
|
||||||
1. **Garage Initialization** (`fnc_initGarage.sqf`)
|
1. **Garage Initialization** (`fnc_initGarage.sqf`)
|
||||||
- Initializes the garage system
|
- Initializes the garage system
|
||||||
- Sets up necessary configurations and vehicle storage
|
- Sets up vehicle storage and management
|
||||||
|
- Configures garage locations and spawn points
|
||||||
|
- Manages vehicle state persistence
|
||||||
|
|
||||||
2. **Garage Interface** (`fnc_openGarage.sqf`)
|
2. **Vehicle Management**
|
||||||
- Opens the garage user interface
|
|
||||||
- Provides access to vehicle management functions
|
|
||||||
|
|
||||||
3. **Vehicle Management**
|
|
||||||
- **Spawn Vehicle** (`fnc_spawnVehicle.sqf`)
|
- **Spawn Vehicle** (`fnc_spawnVehicle.sqf`)
|
||||||
- Handles vehicle spawning from garage
|
- Handles vehicle spawning from garage
|
||||||
|
- Manages spawn locations and orientations
|
||||||
|
- Preserves vehicle type information
|
||||||
|
- Updates garage inventory
|
||||||
|
|
||||||
- **Store Vehicle** (`fnc_storeVehicle.sqf`)
|
- **Store Vehicle** (`fnc_storeVehicle.sqf`)
|
||||||
- Manages vehicle storage in garage
|
- Manages vehicle storage in garage
|
||||||
|
- Handles vehicle cleanup
|
||||||
|
- Updates garage inventory
|
||||||
|
- Preserves vehicle data
|
||||||
|
|
||||||
- **Fetch Garage** (`fnc_fetchGarage.sqf`)
|
- **Fetch Garage** (`fnc_fetchGarage.sqf`)
|
||||||
- Retrieves garage vehicle information
|
- Retrieves garage vehicle information
|
||||||
|
- Updates garage interface
|
||||||
|
- Manages vehicle listings
|
||||||
|
- Handles vehicle categorization
|
||||||
|
|
||||||
- **Fetch Nearby** (`fnc_fetchNearby.sqf`)
|
- **Fetch Nearby** (`fnc_fetchNearby.sqf`)
|
||||||
- Locates and manages nearby vehicles
|
- Locates and manages nearby vehicles
|
||||||
|
- Validates vehicle ownership
|
||||||
|
- Handles vehicle state checks
|
||||||
|
- Updates interface with nearby vehicles
|
||||||
|
|
||||||
|
3. **Vehicle Categories**
|
||||||
|
- Cars (Light vehicles, transport)
|
||||||
|
- Armor (Tanks, APCs)
|
||||||
|
- Helicopters (All rotary-wing aircraft)
|
||||||
|
- Planes (Fixed-wing aircraft)
|
||||||
|
- Naval (Boats, ships)
|
||||||
|
- Static (Weapons, emplacements)
|
||||||
|
|
||||||
|
4. **Vehicle States**
|
||||||
|
- Available
|
||||||
|
- In Use
|
||||||
|
- Maintenance
|
||||||
|
- Damaged
|
||||||
|
- Fuel Status
|
||||||
|
- Condition Tracking
|
||||||
|
|
||||||
|
### User Interface
|
||||||
|
1. **Garage Dialog**
|
||||||
|
- Vehicle listing and management
|
||||||
|
- Category filtering
|
||||||
|
- Status indicators
|
||||||
|
- Action buttons (Spawn/Store)
|
||||||
|
- Vehicle details display
|
||||||
|
|
||||||
|
2. **Vehicle Information**
|
||||||
|
- Vehicle name and type
|
||||||
|
- Status indicators
|
||||||
|
- Fuel level
|
||||||
|
- Damage state
|
||||||
|
- Maintenance status
|
||||||
|
- Last used timestamp
|
||||||
|
|
||||||
|
3. **Controls**
|
||||||
|
- Category filters
|
||||||
|
- Vehicle actions
|
||||||
|
- Status management
|
||||||
|
- Quick access buttons
|
||||||
|
|
||||||
## Event Handlers
|
## Event Handlers
|
||||||
The module uses several event handlers for initialization and execution:
|
The module uses several event handlers for initialization and execution:
|
||||||
@ -44,7 +95,17 @@ The module uses several event handlers for initialization and execution:
|
|||||||
To use the garage module:
|
To use the garage module:
|
||||||
1. Ensure the module is properly loaded in your mission
|
1. Ensure the module is properly loaded in your mission
|
||||||
2. Access the garage through the provided UI
|
2. Access the garage through the provided UI
|
||||||
3. Manage vehicles using the appropriate functions
|
3. Manage vehicles using the appropriate functions:
|
||||||
|
```sqf
|
||||||
|
// Open garage interface
|
||||||
|
[] call forge_client_garage_fnc_openGarage;
|
||||||
|
|
||||||
|
// Store a vehicle
|
||||||
|
[] call forge_client_garage_fnc_storeVehicle;
|
||||||
|
|
||||||
|
// Spawn a vehicle
|
||||||
|
[] call forge_client_garage_fnc_spawnVehicle;
|
||||||
|
```
|
||||||
4. Monitor vehicle status and location
|
4. Monitor vehicle status and location
|
||||||
|
|
||||||
## Debugging
|
## Debugging
|
||||||
@ -55,3 +116,17 @@ Debug mode can be enabled by uncommenting the following in `script_component.hpp
|
|||||||
|
|
||||||
## Version Information
|
## Version Information
|
||||||
Version information is managed through the main Forge client system configuration.
|
Version information is managed through the main Forge client system configuration.
|
||||||
|
|
||||||
|
## Technical Details
|
||||||
|
- Vehicle state persistence
|
||||||
|
- Category-based organization
|
||||||
|
- Status tracking system
|
||||||
|
- Location management
|
||||||
|
- Spawn point configuration
|
||||||
|
- Vehicle cleanup handling
|
||||||
|
- Interface synchronization
|
||||||
|
- Event system integration
|
||||||
|
- Error handling
|
||||||
|
- Debug support
|
||||||
|
- Data validation
|
||||||
|
- State management
|
@ -1 +1,48 @@
|
|||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
[QGVAR(handleEvents), {
|
||||||
|
params ["_control", "_isConfirmDialog", "_message"];
|
||||||
|
|
||||||
|
diag_log text format ["[FORGE::Client::Garage::XEH_postInit] Received event: '%1'", _message];
|
||||||
|
|
||||||
|
_message = fromJSON _message;
|
||||||
|
private _event = _message get "event";
|
||||||
|
private _data = _message get "data";
|
||||||
|
|
||||||
|
private _vehicles = GETVAR(player,FORGE_Garage,[]); //TODO: Implement garage from server
|
||||||
|
|
||||||
|
switch (_event) do {
|
||||||
|
case "REQUEST::GARAGE::DATA": {
|
||||||
|
private _garageData = createHashMap;
|
||||||
|
private _vehicleList = [];
|
||||||
|
|
||||||
|
{
|
||||||
|
private _vehicle = _x;
|
||||||
|
if (isNull _vehicle || { !alive _vehicle }) exitWith {};
|
||||||
|
|
||||||
|
private _vehicleInfo = createHashMapFromArray [
|
||||||
|
["classname", typeOf _vehicle],
|
||||||
|
["damage", damage _vehicle],
|
||||||
|
["fuel", fuel _vehicle],
|
||||||
|
["hitpoints", getAllHitPointsDamage _vehicle]
|
||||||
|
];
|
||||||
|
|
||||||
|
_vehicleList pushBack _vehicleInfo;
|
||||||
|
} forEach _vehicles;
|
||||||
|
|
||||||
|
_garageData set ["vehicles", _vehicleList];
|
||||||
|
_control ctrlWebBrowserAction ["ExecJS", format ["handleGarageDataRequest(%1)", (toJSON _vehicleList)]];
|
||||||
|
};
|
||||||
|
case "STORE::VEHICLE": {
|
||||||
|
// Logic to store vehicle in garage
|
||||||
|
// This would typically involve saving the vehicle's state to a database or similar
|
||||||
|
};
|
||||||
|
case "RETRIEVE::VEHICLE": {
|
||||||
|
// Logic to retrieve vehicle from garage
|
||||||
|
// This would typically involve loading the vehicle's state from a database or similar
|
||||||
|
};
|
||||||
|
default {
|
||||||
|
diag_log text format ["[FORGE::Client::Garage::XEH_postInit] Unknown event: '%1'", _event];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}] call CFUNC(addEventHandler);
|
@ -1,10 +1,7 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_garage_fnc_fetchGarage
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Fetches the vehicles in the garage
|
* Fetches the vehicles in the garage
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
@ -12,6 +9,11 @@
|
|||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private _display = findDisplay IDD_GARAGEDIALOG;
|
private _display = findDisplay IDD_GARAGEDIALOG;
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_garage_fnc_fetchNearby
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Fetches the nearby vehicles
|
* Fetches the nearby vehicles
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
@ -12,6 +9,11 @@
|
|||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private _display = findDisplay IDD_GARAGEDIALOG;
|
private _display = findDisplay IDD_GARAGEDIALOG;
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_garage_fnc_initGarage
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Initializes the garages
|
* Initializes the garages
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
@ -12,6 +9,11 @@
|
|||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
*/
|
*/
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_garage_fnc_openGarage
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Opens the garage dialog
|
* Opens the garage dialog
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
@ -12,6 +9,11 @@
|
|||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
*/
|
*/
|
||||||
|
|
||||||
disableSerialization;
|
disableSerialization;
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_garage_fnc_spawnVehicle
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Spawns a vehicle from the garage
|
* Spawns a vehicle from the garage
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
@ -12,6 +9,11 @@
|
|||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
*/
|
*/
|
||||||
|
|
||||||
disableSerialization;
|
disableSerialization;
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_garage_fnc_storeVehicle
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Stores a vehicle in the garage
|
* Stores a vehicle in the garage
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
@ -12,6 +9,11 @@
|
|||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private _display = findDisplay IDD_GARAGEDIALOG;
|
private _display = findDisplay IDD_GARAGEDIALOG;
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project name="forge_client">
|
<Project name="forge_client">
|
||||||
<Package name="Garage">
|
<Package name="Garage">
|
||||||
<Key ID="STR_forge_client_garage_Close">
|
|
||||||
<English>Close</English>
|
|
||||||
</Key>
|
|
||||||
<Key ID="STR_forge_client_garage_Name">
|
<Key ID="STR_forge_client_garage_Name">
|
||||||
<English>Garage</English>
|
<English>Garage</English>
|
||||||
</Key>
|
</Key>
|
||||||
|
118
addons/init/README.md
Normal file
118
addons/init/README.md
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
# Forge Initialization Module
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
The Initialization module provides a comprehensive player initialization and data persistence system for the Forge client. It handles player data loading, saving, and synchronization with the database, ensuring a seamless experience across sessions.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
- forge_client_main
|
||||||
|
- ArmaDragonflyClient
|
||||||
|
|
||||||
|
## Authors
|
||||||
|
- J. Schmidt
|
||||||
|
- Creedcoder
|
||||||
|
- IDSolutions
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### Player Initialization
|
||||||
|
1. **Player Setup** (`fnc_initPlayer.sqf`)
|
||||||
|
- Initializes player state
|
||||||
|
- Clears default equipment
|
||||||
|
- Sets up player variables
|
||||||
|
- Configures initial loadout
|
||||||
|
- Manages loading screen
|
||||||
|
|
||||||
|
2. **Data Management**
|
||||||
|
- **Player Load** (`fnc_playerDBLoad.sqf`)
|
||||||
|
- Loads player data from database
|
||||||
|
- Handles first-time login
|
||||||
|
- Restores player state
|
||||||
|
- Manages data synchronization
|
||||||
|
|
||||||
|
- **Player Save** (`fnc_playerDBSave.sqf`)
|
||||||
|
- Saves player data to database
|
||||||
|
- Manages data persistence
|
||||||
|
- Handles state synchronization
|
||||||
|
- Preserves player information
|
||||||
|
|
||||||
|
- **Save Loop** (`fnc_playerSaveLoop.sqf`)
|
||||||
|
- Periodic data saving
|
||||||
|
- Configurable save intervals
|
||||||
|
- Automatic state persistence
|
||||||
|
- Error handling
|
||||||
|
|
||||||
|
3. **Data Handling** (`fnc_handlePlayerLoad.sqf`)
|
||||||
|
- Processes loaded data
|
||||||
|
- Restores player state
|
||||||
|
- Manages default values
|
||||||
|
- Handles data validation
|
||||||
|
|
||||||
|
### Persisted Data
|
||||||
|
1. **Player Information**
|
||||||
|
- Armory unlocks
|
||||||
|
- Garage unlocks
|
||||||
|
- Locker contents
|
||||||
|
- Vehicle inventory
|
||||||
|
- Financial data (cash/bank)
|
||||||
|
- Contact details
|
||||||
|
- Organization membership
|
||||||
|
- Player statistics
|
||||||
|
- Equipment loadouts
|
||||||
|
- Position and state
|
||||||
|
|
||||||
|
2. **State Management**
|
||||||
|
- Player position
|
||||||
|
- Player direction
|
||||||
|
- Weapon state
|
||||||
|
- Stance information
|
||||||
|
- Rating/reputation
|
||||||
|
- Paygrade
|
||||||
|
- Organization status
|
||||||
|
|
||||||
|
## Event Handlers
|
||||||
|
The module uses several event handlers for initialization and execution:
|
||||||
|
- `XEH_preInit.sqf`: Pre-initialization setup
|
||||||
|
- `XEH_postInit.sqf`: Post-initialization tasks
|
||||||
|
- `XEH_preStart.sqf`: Pre-start configuration
|
||||||
|
- `XEH_postInit_client.sqf`: Client-specific post-initialization
|
||||||
|
- `XEH_preInit_server.sqf`: Server-specific pre-initialization
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
To use the initialization module:
|
||||||
|
1. Ensure the module is properly loaded in your mission
|
||||||
|
2. The module automatically handles player initialization
|
||||||
|
3. Access player data using the appropriate functions:
|
||||||
|
```sqf
|
||||||
|
// Initialize player
|
||||||
|
[] call forge_client_init_fnc_initPlayer;
|
||||||
|
|
||||||
|
// Load player data
|
||||||
|
[] call forge_client_init_fnc_playerDBLoad;
|
||||||
|
|
||||||
|
// Save player data
|
||||||
|
[] call forge_client_init_fnc_playerDBSave;
|
||||||
|
```
|
||||||
|
4. Monitor player state and data persistence
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
Debug mode can be enabled by uncommenting the following in `script_component.hpp`:
|
||||||
|
```cpp
|
||||||
|
#define DEBUG_MODE_FULL
|
||||||
|
```
|
||||||
|
|
||||||
|
## Version Information
|
||||||
|
Version information is managed through the main Forge client system configuration.
|
||||||
|
|
||||||
|
## Technical Details
|
||||||
|
- Automatic player initialization
|
||||||
|
- Database integration
|
||||||
|
- Periodic data saving
|
||||||
|
- State persistence
|
||||||
|
- Error handling
|
||||||
|
- Data validation
|
||||||
|
- First-time login handling
|
||||||
|
- Default value management
|
||||||
|
- Position tracking
|
||||||
|
- Equipment management
|
||||||
|
- Financial synchronization
|
||||||
|
- Organization integration
|
@ -5,4 +5,6 @@ PREP_RECOMPILE_START;
|
|||||||
#include "XEH_PREP.hpp"
|
#include "XEH_PREP.hpp"
|
||||||
PREP_RECOMPILE_END;
|
PREP_RECOMPILE_END;
|
||||||
|
|
||||||
|
GVAR(done) = false;
|
||||||
|
|
||||||
ADDON = true;
|
ADDON = true;
|
@ -1,19 +1,16 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_init_fnc_handlePlayerLoad
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
|
||||||
* [Description]
|
|
||||||
* Handle player load from DB.
|
* Handle player load from DB.
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: Data from key [<ARRAY|STRING|NUMBER|BOOL>] (default: [])
|
* 0: Data from key <ARRAY|STRING|NUMBER|BOOL> (default: [])
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* N/A
|
* None
|
||||||
*
|
*
|
||||||
* Examples:
|
* Example:
|
||||||
* [[_data]] call forge_client_init_fnc_handlePlayerLoad (Server or Singleplayer Only)
|
* [[_data]] call forge_client_init_fnc_handlePlayerLoad (Server or Singleplayer Only)
|
||||||
* [[_data]] remoteExecCall ["forge_client_init_fnc_handlePlayerLoad", 2, false] (Multiplayer Only)
|
* [[_data]] remoteExecCall ["forge_client_init_fnc_handlePlayerLoad", 2, false] (Multiplayer Only)
|
||||||
*
|
*
|
||||||
@ -40,7 +37,7 @@ if (_data isEqualTo [""]) then {
|
|||||||
|
|
||||||
switch (_key) do {
|
switch (_key) do {
|
||||||
case "reputation": {
|
case "reputation": {
|
||||||
SETPVAR(player,Reputation,_value);
|
SETPVAR(player,FORGE_Rating,_value);
|
||||||
player addRating _value;
|
player addRating _value;
|
||||||
};
|
};
|
||||||
case "loadout": {
|
case "loadout": {
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_init_fnc_initPlayer
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Initialize player
|
||||||
* [Description]
|
|
||||||
* Initialize player.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* N/A
|
* N/A
|
||||||
@ -32,7 +29,7 @@ removeBackpack player;
|
|||||||
removeGoggles player;
|
removeGoggles player;
|
||||||
removeHeadgear player;
|
removeHeadgear player;
|
||||||
|
|
||||||
SETPVAR(player,value_loadDone,false);
|
SETPVAR(player,GVAR(done),false);
|
||||||
cutText ["Loading In...", "BLACK", 1];
|
cutText ["Loading In...", "BLACK", 1];
|
||||||
|
|
||||||
// ["hgetall", "", "", -1, [], "forge_client_init_fnc_handlePlayerLoad", true] spawn dragonfly_db_fnc_addTask;
|
// ["hgetall", "", "", -1, [], "forge_client_init_fnc_handlePlayerLoad", true] spawn dragonfly_db_fnc_addTask;
|
||||||
@ -41,7 +38,7 @@ cutText ["Loading In...", "BLACK", 1];
|
|||||||
[] spawn FUNC(playerSaveLoop);
|
[] spawn FUNC(playerSaveLoop);
|
||||||
[] spawn EFUNC(interaction,initInteraction);
|
[] spawn EFUNC(interaction,initInteraction);
|
||||||
|
|
||||||
waitUntil { GETVAR(player,value_loadDone,false) };
|
waitUntil { GETVAR(player,GVAR(done),false) };
|
||||||
cutText ["", "PLAIN", 1];
|
cutText ["", "PLAIN", 1];
|
||||||
|
|
||||||
waitUntil { !(isNull (findDisplay 46)) };
|
waitUntil { !(isNull (findDisplay 46)) };
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_init_fnc_playerDBLoad
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Load player from DB
|
||||||
* [Description]
|
|
||||||
* Load player from DB.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* N/A
|
* N/A
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_init_fnc_playerDBSave
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Save player to DB
|
||||||
* [Description]
|
|
||||||
* Save player to DB.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* N/A
|
* N/A
|
||||||
@ -20,13 +17,10 @@
|
|||||||
* Public: Yes
|
* Public: Yes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private _default_armory_unlocks = [[],[],[],[]];
|
|
||||||
private _default_garage_unlocks = [[],[],[],[],[],[]];
|
|
||||||
|
|
||||||
private _data = [
|
private _data = [
|
||||||
getPlayerUID player,
|
getPlayerUID player,
|
||||||
"armory_unlocks", [GETVAR(player,Armory_Unlocks,_default_armory_unlocks)],
|
"armory_unlocks", [GETVAR(player,Armory_Unlocks,EGVAR(arsenal,default_armory))],
|
||||||
"garage_unlocks", [GETVAR(player,Garage_Unlocks,_default_garage_unlocks)],
|
"garage_unlocks", [GETVAR(player,Garage_Unlocks,EGVAR(arsenal,default_garage))],
|
||||||
"locker", [GETVAR(player,FORGE_Locker,[])],
|
"locker", [GETVAR(player,FORGE_Locker,[])],
|
||||||
"garage", [GETVAR(player,FORGE_Garage,[])],
|
"garage", [GETVAR(player,FORGE_Garage,[])],
|
||||||
"cash", [GETVAR(player,FORGE_Cash,0)],
|
"cash", [GETVAR(player,FORGE_Cash,0)],
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_init_fnc_playerSaveLoop
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Initialize player save loop
|
||||||
* [Description]
|
|
||||||
* Initialize player save loop.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* N/A
|
* N/A
|
||||||
|
@ -1,4 +1,124 @@
|
|||||||
forge_interaction
|
# Forge Interaction Module
|
||||||
===============
|
|
||||||
|
|
||||||
Core interaction addon that handles all player interactions with the game world. This system manages how players engage with objects, NPCs, items and other interactive elements in the environment.
|
## Overview
|
||||||
|
The Interaction module provides a comprehensive player interaction system for the Forge client. It manages how players engage with objects, NPCs, items, and other interactive elements in the environment through a dynamic and context-sensitive interface.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
- forge_client_main
|
||||||
|
|
||||||
|
## Authors
|
||||||
|
- J. Schmidt
|
||||||
|
- Creedcoder
|
||||||
|
- IDSolutions
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### Interaction System
|
||||||
|
1. **Interaction Initialization** (`fnc_initInteraction.sqf`)
|
||||||
|
- Initializes the interaction system
|
||||||
|
- Sets up interaction buttons and items
|
||||||
|
- Configures team coordination settings
|
||||||
|
- Manages virtual arsenal integration
|
||||||
|
|
||||||
|
2. **Interaction Interface**
|
||||||
|
- **Open Interaction** (`fnc_openInteraction.sqf`)
|
||||||
|
- Opens the interaction menu
|
||||||
|
- Displays available actions
|
||||||
|
- Manages button visibility
|
||||||
|
- Handles action execution
|
||||||
|
|
||||||
|
- **Interaction Action** (`fnc_interactionAction.sqf`)
|
||||||
|
- Processes selected actions
|
||||||
|
- Executes interaction commands
|
||||||
|
- Manages action feedback
|
||||||
|
- Handles interface updates
|
||||||
|
|
||||||
|
3. **Available Interactions**
|
||||||
|
- **Player Interactions**
|
||||||
|
- Give Cash
|
||||||
|
- Add Contact
|
||||||
|
- Access ATM
|
||||||
|
- Access CPOF (Company Point of Finance)
|
||||||
|
- Take Cash
|
||||||
|
- Open Locker
|
||||||
|
- Access Store
|
||||||
|
- Open Garage
|
||||||
|
- Virtual Armory (if enabled)
|
||||||
|
- Virtual Garage (if enabled)
|
||||||
|
|
||||||
|
4. **Team Coordination**
|
||||||
|
- Company garage access
|
||||||
|
- Team-specific interactions
|
||||||
|
- Permission-based actions
|
||||||
|
- Organization integration
|
||||||
|
|
||||||
|
### User Interface
|
||||||
|
1. **Interaction Menu**
|
||||||
|
- Dynamic button display
|
||||||
|
- Context-sensitive actions
|
||||||
|
- Distance-based availability
|
||||||
|
- Permission-based options
|
||||||
|
|
||||||
|
2. **Control Elements**
|
||||||
|
- Action buttons
|
||||||
|
- Status indicators
|
||||||
|
- Feedback messages
|
||||||
|
- Error handling
|
||||||
|
|
||||||
|
## Event Handlers
|
||||||
|
The module uses several event handlers for initialization and execution:
|
||||||
|
- `XEH_preInit.sqf`: Pre-initialization setup
|
||||||
|
- `XEH_postInit.sqf`: Post-initialization tasks
|
||||||
|
- `XEH_preStart.sqf`: Pre-start configuration
|
||||||
|
- `XEH_postInit_client.sqf`: Client-specific post-initialization
|
||||||
|
- `XEH_preInit_server.sqf`: Server-specific pre-initialization
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
To use the interaction module:
|
||||||
|
1. Ensure the module is properly loaded in your mission
|
||||||
|
2. Access interactions using the configured key (default: TAB)
|
||||||
|
3. Interact with objects and players:
|
||||||
|
```sqf
|
||||||
|
// Open interaction menu
|
||||||
|
[] call forge_client_interaction_fnc_openInteraction;
|
||||||
|
|
||||||
|
// Initialize interaction system
|
||||||
|
[] call forge_client_interaction_fnc_initInteraction;
|
||||||
|
```
|
||||||
|
4. Monitor interaction feedback and results
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
The module can be configured through the main Forge client configuration:
|
||||||
|
```cpp
|
||||||
|
// Interaction key (default: TAB)
|
||||||
|
interactionKey = 15;
|
||||||
|
|
||||||
|
// Team coordination mode
|
||||||
|
FORGE_Team_Coord = 1;
|
||||||
|
|
||||||
|
// Virtual arsenal enable
|
||||||
|
FORGE_VA_Enable = 1;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
Debug mode can be enabled by uncommenting the following in `script_component.hpp`:
|
||||||
|
```cpp
|
||||||
|
#define DEBUG_MODE_FULL
|
||||||
|
```
|
||||||
|
|
||||||
|
## Version Information
|
||||||
|
Version information is managed through the main Forge client system configuration.
|
||||||
|
|
||||||
|
## Technical Details
|
||||||
|
- Dynamic interaction system
|
||||||
|
- Context-sensitive actions
|
||||||
|
- Distance-based availability
|
||||||
|
- Permission management
|
||||||
|
- Team coordination
|
||||||
|
- Virtual arsenal integration
|
||||||
|
- Error handling
|
||||||
|
- User feedback
|
||||||
|
- Interface management
|
||||||
|
- Action validation
|
||||||
|
- State tracking
|
||||||
|
- Event system integration
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_interaction_fnc_initInteraction
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Initialize player interaction
|
||||||
* [Description]
|
|
||||||
* Initialize player interaction.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* N/A
|
* N/A
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_interaction_fnc_interactionAction
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Initialize player interaction
|
||||||
* [Description]
|
|
||||||
* Initialize player interaction.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: Index of current action array <NUMBER>
|
* 0: Index of current action array <NUMBER>
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_interaction_fnc_openInteraction
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Open player interaction
|
||||||
* [Description]
|
|
||||||
* Open player interaction.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* N/A
|
* N/A
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Forge Locker Module
|
# Forge Locker Module
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
The Locker module provides a comprehensive equipment management system for the Forge client. It includes features for storing, equipping, and managing player gear in a secure locker system.
|
The Locker module provides a comprehensive equipment management system for the Forge client. It includes features for storing, equipping, and managing player gear in a secure locker system with a modern web-based interface.
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
- forge_client_main
|
- forge_client_main
|
||||||
@ -16,21 +16,76 @@ The Locker module provides a comprehensive equipment management system for the F
|
|||||||
### Locker System
|
### Locker System
|
||||||
1. **Locker Initialization** (`fnc_initLocker.sqf`)
|
1. **Locker Initialization** (`fnc_initLocker.sqf`)
|
||||||
- Initializes the locker system
|
- Initializes the locker system
|
||||||
- Sets up necessary configurations and storage structures
|
- Sets up storage structures
|
||||||
|
- Configures player variables
|
||||||
|
- Manages equipment tracking
|
||||||
|
|
||||||
2. **Locker Interface** (`fnc_openLocker.sqf`)
|
2. **Equipment Management**
|
||||||
- Opens the locker user interface
|
|
||||||
- Provides access to equipment management functions
|
|
||||||
|
|
||||||
3. **Equipment Management**
|
|
||||||
- **Store Gear** (`fnc_storeGear.sqf`)
|
- **Store Gear** (`fnc_storeGear.sqf`)
|
||||||
- Handles equipment storage in locker
|
- Stores equipment in locker
|
||||||
|
- Handles different item types:
|
||||||
|
- Backpacks (with contents)
|
||||||
|
- Facewear (goggles)
|
||||||
|
- Headgear
|
||||||
|
- HMD (Head Mounted Display)
|
||||||
|
- Uniforms
|
||||||
|
- Vests
|
||||||
|
- Weapons (with attachments)
|
||||||
|
- Items
|
||||||
|
- Magazines (with ammo count)
|
||||||
|
- Manages storage space
|
||||||
|
- Preserves item condition
|
||||||
|
|
||||||
- **Equip Gear** (`fnc_equipGear.sqf`)
|
- **Equip Gear** (`fnc_equipGear.sqf`)
|
||||||
- Manages equipment equipping from locker
|
- Equips items from locker
|
||||||
|
- Handles equipment compatibility
|
||||||
|
- Manages inventory space
|
||||||
|
- Preserves attachments and magazines
|
||||||
|
- Provides feedback on actions
|
||||||
|
|
||||||
|
3. **Data Management**
|
||||||
- **Fetch Locker** (`fnc_fetchLocker.sqf`)
|
- **Fetch Locker** (`fnc_fetchLocker.sqf`)
|
||||||
- Retrieves locker contents and information
|
- Retrieves locker contents
|
||||||
|
- Updates UI display
|
||||||
|
- Manages item categorization
|
||||||
|
- Handles item metadata
|
||||||
|
|
||||||
- **Fetch Player** (`fnc_fetchPlayer.sqf`)
|
- **Fetch Player** (`fnc_fetchPlayer.sqf`)
|
||||||
- Retrieves player equipment information
|
- Retrieves player equipment
|
||||||
|
- Updates UI display
|
||||||
|
- Manages equipment lists
|
||||||
|
- Handles item metadata
|
||||||
|
|
||||||
|
### User Interface
|
||||||
|
1. **Modern Web Interface**
|
||||||
|
- Responsive design
|
||||||
|
- Category filtering
|
||||||
|
- Item categorization
|
||||||
|
- Storage statistics
|
||||||
|
- Equipment details view
|
||||||
|
|
||||||
|
2. **Interface Features**
|
||||||
|
- Storage space tracking
|
||||||
|
- Item count display
|
||||||
|
- Category filters:
|
||||||
|
- All Items
|
||||||
|
- Weapons
|
||||||
|
- Clothing
|
||||||
|
- Equipment
|
||||||
|
- Magazines
|
||||||
|
- Item details:
|
||||||
|
- Name
|
||||||
|
- Category
|
||||||
|
- Condition
|
||||||
|
- Quantity
|
||||||
|
- Attachments
|
||||||
|
|
||||||
|
3. **Control Elements**
|
||||||
|
- Store button
|
||||||
|
- Equip button
|
||||||
|
- Category filters
|
||||||
|
- Item lists
|
||||||
|
- Status indicators
|
||||||
|
|
||||||
## Event Handlers
|
## Event Handlers
|
||||||
The module uses several event handlers for initialization and execution:
|
The module uses several event handlers for initialization and execution:
|
||||||
@ -43,9 +98,30 @@ The module uses several event handlers for initialization and execution:
|
|||||||
## Usage
|
## Usage
|
||||||
To use the locker module:
|
To use the locker module:
|
||||||
1. Ensure the module is properly loaded in your mission
|
1. Ensure the module is properly loaded in your mission
|
||||||
2. Access the locker through the provided UI
|
2. Access the locker through the interaction menu
|
||||||
3. Manage equipment using the appropriate functions
|
3. Manage equipment using the interface:
|
||||||
4. Monitor equipment status and storage
|
```sqf
|
||||||
|
// Open locker interface
|
||||||
|
[] call forge_client_locker_fnc_openLocker;
|
||||||
|
|
||||||
|
// Store equipment
|
||||||
|
[] call forge_client_locker_fnc_storeGear;
|
||||||
|
|
||||||
|
// Equip items
|
||||||
|
[] call forge_client_locker_fnc_equipGear;
|
||||||
|
```
|
||||||
|
4. Monitor storage space and item status
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
The module can be configured through the main Forge client configuration:
|
||||||
|
```cpp
|
||||||
|
// Locker storage space (default: 100)
|
||||||
|
FORGE_Locker_Space = 100;
|
||||||
|
|
||||||
|
// Enable/disable features
|
||||||
|
FORGE_Locker_EnableAttachments = 1;
|
||||||
|
FORGE_Locker_EnableMagazines = 1;
|
||||||
|
```
|
||||||
|
|
||||||
## Debugging
|
## Debugging
|
||||||
Debug mode can be enabled by uncommenting the following in `script_component.hpp`:
|
Debug mode can be enabled by uncommenting the following in `script_component.hpp`:
|
||||||
@ -55,3 +131,19 @@ Debug mode can be enabled by uncommenting the following in `script_component.hpp
|
|||||||
|
|
||||||
## Version Information
|
## Version Information
|
||||||
Version information is managed through the main Forge client system configuration.
|
Version information is managed through the main Forge client system configuration.
|
||||||
|
|
||||||
|
## Technical Details
|
||||||
|
- Modern web-based interface
|
||||||
|
- Real-time storage tracking
|
||||||
|
- Equipment condition preservation
|
||||||
|
- Attachment management
|
||||||
|
- Magazine ammo tracking
|
||||||
|
- Category-based filtering
|
||||||
|
- Responsive UI design
|
||||||
|
- Error handling
|
||||||
|
- User feedback
|
||||||
|
- State management
|
||||||
|
- Event system integration
|
||||||
|
- Database persistence
|
||||||
|
- Inventory validation
|
||||||
|
- Space management
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_locker_fnc_equipGear
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Equips gear from the locker
|
||||||
* [Description]
|
|
||||||
* Equips gear from the locker.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* N/A
|
* N/A
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_locker_fnc_fetchLocker
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Fetches the locker
|
||||||
* [Description]
|
|
||||||
* Fetches the locker.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* N/A
|
* N/A
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_locker_fnc_fetchPlayer
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Fetches the player's gear
|
||||||
* [Description]
|
|
||||||
* Fetches the player's gear.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* N/A
|
* N/A
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_locker_fnc_initLocker
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Initializes the lockers
|
||||||
* [Description]
|
|
||||||
* Initializes the lockers.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* N/A
|
* N/A
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_locker_fnc_openLocker
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Opens the locker dialog
|
||||||
* [Description]
|
|
||||||
* Opens the locker dialog.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* N/A
|
* N/A
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_locker_fnc_storeGear
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Stores gear in the locker
|
||||||
* [Description]
|
|
||||||
* Stores gear in the locker.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* N/A
|
* N/A
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project name="forge_client">
|
<Project name="forge_client">
|
||||||
<Package name="Locker">
|
<Package name="Locker">
|
||||||
<Key ID="STR_forge_client_locker_Close">
|
|
||||||
<English>Close</English>
|
|
||||||
</Key>
|
|
||||||
<Key ID="STR_forge_client_locker_Equip">
|
<Key ID="STR_forge_client_locker_Equip">
|
||||||
<English>Equip</English>
|
<English>Equip</English>
|
||||||
</Key>
|
</Key>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#define MAJOR 1
|
#define MAJOR 1
|
||||||
#define MINOR 0
|
#define MINOR 0
|
||||||
#define PATCH 0
|
#define PATCH 0
|
||||||
#define BUILD 18
|
#define BUILD 32
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Forge Medical Module
|
# Forge Medical Module
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
The Medical module provides a comprehensive medical system for the Forge client. It includes features for handling player health, death, respawn, and medical costs.
|
The Medical module provides a comprehensive medical system for the Forge client. It includes features for handling player health, death, respawn, medical costs, and inventory management during medical events.
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
- forge_client_main
|
- forge_client_main
|
||||||
@ -16,25 +16,85 @@ The Medical module provides a comprehensive medical system for the Forge client.
|
|||||||
### Medical System
|
### Medical System
|
||||||
1. **Medical Initialization** (`fnc_initMedical.sqf`)
|
1. **Medical Initialization** (`fnc_initMedical.sqf`)
|
||||||
- Initializes the medical system
|
- Initializes the medical system
|
||||||
- Sets up necessary configurations and health monitoring
|
- Sets up stretcher detection and triggers
|
||||||
|
- Configures medical service points
|
||||||
|
- Manages occupancy tracking
|
||||||
|
- Handles system variables
|
||||||
|
|
||||||
2. **Health Management**
|
2. **Health Management**
|
||||||
- **Heart Beat** (`fnc_heartBeat.sqf`)
|
- **Heart Beat** (`fnc_heartBeat.sqf`)
|
||||||
- Monitors player vital signs
|
- Monitors player vital signs
|
||||||
|
- Tracks medical costs
|
||||||
|
- Manages respawn conditions
|
||||||
|
- Handles payment verification
|
||||||
|
- Controls spectator mode
|
||||||
|
|
||||||
- **On Killed** (`fnc_onKilled.sqf`)
|
- **On Killed** (`fnc_onKilled.sqf`)
|
||||||
- Handles player death events
|
- Handles player death events
|
||||||
|
- Creates body bag
|
||||||
|
- Saves dropped weapons
|
||||||
|
- Manages inventory transfer
|
||||||
|
- Triggers respawn process
|
||||||
|
|
||||||
- **On Respawn** (`fnc_onRespawn.sqf`)
|
- **On Respawn** (`fnc_onRespawn.sqf`)
|
||||||
- Manages player respawn process
|
- Manages player respawn process
|
||||||
|
- Handles medical costs
|
||||||
|
- Sets default loadout
|
||||||
|
- Manages stretcher placement
|
||||||
|
- Controls spectator mode
|
||||||
|
- Processes payment verification
|
||||||
|
|
||||||
3. **Inventory Management**
|
3. **Inventory Management**
|
||||||
- **Move Inventory** (`fnc_moveInventory.sqf`)
|
- **Move Inventory** (`fnc_moveInventory.sqf`)
|
||||||
- Handles inventory transfers during medical events
|
- Transfers player inventory to body bag
|
||||||
|
- Handles all equipment types:
|
||||||
|
- Headgear
|
||||||
|
- Uniforms and items
|
||||||
|
- Vests and contents
|
||||||
|
- Backpacks and contents
|
||||||
|
- Weapons and attachments
|
||||||
|
- Magazines and ammo
|
||||||
|
- Assigned items
|
||||||
|
- Dropped equipment
|
||||||
|
- Manages weapon holders
|
||||||
|
- Preserves item condition
|
||||||
|
|
||||||
- **Save Dropped Weapons** (`fnc_saveDroppedWeapons.sqf`)
|
- **Save Dropped Weapons** (`fnc_saveDroppedWeapons.sqf`)
|
||||||
- Manages weapon preservation on death
|
- Tracks dropped weapons
|
||||||
|
- Manages weapon attachments
|
||||||
|
- Preserves magazine data
|
||||||
|
- Handles handgun equipment
|
||||||
|
- Stores item information
|
||||||
|
|
||||||
4. **Medical Costs**
|
4. **Medical Costs**
|
||||||
- **Deduct Medical Cost** (`fnc_deductMedicalCost.sqf`)
|
- **Deduct Medical Cost** (`fnc_deductMedicalCost.sqf`)
|
||||||
- Handles medical service payments
|
- Handles medical service payments
|
||||||
|
- Manages account selection
|
||||||
|
- Processes payment deduction
|
||||||
|
- Provides payment feedback
|
||||||
|
- Updates account balances
|
||||||
|
|
||||||
|
### Medical Features
|
||||||
|
1. **Stretcher System**
|
||||||
|
- Automatic stretcher detection
|
||||||
|
- Occupancy tracking
|
||||||
|
- Position management
|
||||||
|
- Respawn placement
|
||||||
|
- Trigger-based activation
|
||||||
|
|
||||||
|
2. **Body Bag System**
|
||||||
|
- Custom body bag class
|
||||||
|
- Increased storage capacity
|
||||||
|
- ACE dragging support
|
||||||
|
- Inventory preservation
|
||||||
|
- Equipment management
|
||||||
|
|
||||||
|
3. **Payment System**
|
||||||
|
- Insurance deductible
|
||||||
|
- Medical service costs
|
||||||
|
- Account balance checking
|
||||||
|
- Payment processing
|
||||||
|
- Transaction feedback
|
||||||
|
|
||||||
## Event Handlers
|
## Event Handlers
|
||||||
The module uses several event handlers for initialization and execution:
|
The module uses several event handlers for initialization and execution:
|
||||||
@ -48,9 +108,36 @@ The module uses several event handlers for initialization and execution:
|
|||||||
To use the medical module:
|
To use the medical module:
|
||||||
1. Ensure the module is properly loaded in your mission
|
1. Ensure the module is properly loaded in your mission
|
||||||
2. Monitor player health through the medical system
|
2. Monitor player health through the medical system
|
||||||
3. Handle medical events using the appropriate functions
|
3. Handle medical events using the appropriate functions:
|
||||||
|
```sqf
|
||||||
|
// Initialize medical system
|
||||||
|
[] call forge_client_medical_fnc_initMedical;
|
||||||
|
|
||||||
|
// Handle player death
|
||||||
|
[player, killer, instigator, true] call forge_client_medical_fnc_onKilled;
|
||||||
|
|
||||||
|
// Process respawn
|
||||||
|
[player, corpse] call forge_client_medical_fnc_onRespawn;
|
||||||
|
```
|
||||||
4. Manage medical costs and inventory during medical events
|
4. Manage medical costs and inventory during medical events
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
The module can be configured through the main Forge client configuration:
|
||||||
|
```cpp
|
||||||
|
// Medical cost (default: 1000)
|
||||||
|
MED_COST = 1000;
|
||||||
|
|
||||||
|
// Insurance deductible (default: 200)
|
||||||
|
INS_DEDUCT = 200;
|
||||||
|
|
||||||
|
// Stretcher types
|
||||||
|
FORGE_Medical_StretcherTypes = [
|
||||||
|
"Land_Stretcher_01_F",
|
||||||
|
"Land_Stretcher_01_olive_F",
|
||||||
|
"Land_Stretcher_01_sand_F"
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
## Debugging
|
## Debugging
|
||||||
Debug mode can be enabled by uncommenting the following in `script_component.hpp`:
|
Debug mode can be enabled by uncommenting the following in `script_component.hpp`:
|
||||||
```cpp
|
```cpp
|
||||||
@ -59,3 +146,19 @@ Debug mode can be enabled by uncommenting the following in `script_component.hpp
|
|||||||
|
|
||||||
## Version Information
|
## Version Information
|
||||||
Version information is managed through the main Forge client system configuration.
|
Version information is managed through the main Forge client system configuration.
|
||||||
|
|
||||||
|
## Technical Details
|
||||||
|
- Stretcher-based respawn system
|
||||||
|
- Body bag inventory management
|
||||||
|
- Medical cost processing
|
||||||
|
- Insurance system integration
|
||||||
|
- Inventory preservation
|
||||||
|
- Equipment tracking
|
||||||
|
- Payment verification
|
||||||
|
- Spectator mode control
|
||||||
|
- Trigger-based activation
|
||||||
|
- Event system integration
|
||||||
|
- State management
|
||||||
|
- Error handling
|
||||||
|
- User feedback
|
||||||
|
- Database persistence
|
@ -1,11 +1,8 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_medical_fnc_deductMedicalCost
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
* Deducts the medical cost from the player's account
|
||||||
* [Description]
|
|
||||||
* Deducts the medical cost from the player's account.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: Unit <OBJECT>
|
* 0: Unit <OBJECT>
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: forge_client_medical_fnc_deductMedicalCost
|
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
*
|
|
||||||
* [Description]
|
|
||||||
* Deducts the medical cost from the player's account.
|
* Deducts the medical cost from the player's account.
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user