diff --git a/.gitea/CONTRIBUTING.md b/.gitea/CONTRIBUTING.md
index b7b4679..a378b46 100644
--- a/.gitea/CONTRIBUTING.md
+++ b/.gitea/CONTRIBUTING.md
@@ -1,12 +1,17 @@
# Contributing Setup & Guidelines
## Setting up the Development Environment
+
### 1. Clone the repository from GitHub
+
### 2. Install HEMTT
+
The latest version of HEMTT can be installed by running:
+
```cmd
winget install hemtt
```
## Coding Guidelines
+
This mod follows the same coding guidelines as the ACE3 mod, which can be found [here](https://ace3.acemod.org/wiki/development/coding-guidelines).
diff --git a/.gitea/ISSUE_TEMPLATE/bug-report.md b/.gitea/ISSUE_TEMPLATE/bug-report.md
index d4c384f..2e818b5 100644
--- a/.gitea/ISSUE_TEMPLATE/bug-report.md
+++ b/.gitea/ISSUE_TEMPLATE/bug-report.md
@@ -1,25 +1,31 @@
---
name: Bug report
about: Create a bug report to help us improve
-title: ''
+title: ""
labels: kind/bug
---
## Describe the bug
+
A clear and concise description of what the bug is.
## To reproduce
+
Steps to reproduce the behavior:
+
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
## Expected behavior
+
A clear and concise description of what you expected to happen.
## Attachments
+
If applicable, add screenshots or RPT logs to help explain your problem.
## Additional context
+
Add any other context about the problem here.
diff --git a/.gitea/ISSUE_TEMPLATE/feature-request.md b/.gitea/ISSUE_TEMPLATE/feature-request.md
index 709ee6c..7bd655d 100644
--- a/.gitea/ISSUE_TEMPLATE/feature-request.md
+++ b/.gitea/ISSUE_TEMPLATE/feature-request.md
@@ -1,15 +1,18 @@
---
name: Feature Request
about: Suggest a feature to be added
-title: ''
+title: ""
labels: kind/feature-request
---
## Describe the feature that you would like
+
A clear and concise description of the feature you'd want.
## Possible alternatives
+
Possible alternatives to your suggestion.
## Additional context
+
Add any other context about the feature here.
diff --git a/.gitea/PULL_REQUEST_TEMPLATE.md b/.gitea/PULL_REQUEST_TEMPLATE.md
index 6f72c35..1721684 100644
--- a/.gitea/PULL_REQUEST_TEMPLATE.md
+++ b/.gitea/PULL_REQUEST_TEMPLATE.md
@@ -1,12 +1,16 @@
**When merged this pull request will:**
+
- Describe what this pull request will do
- Each change in a separate line
### Important
+
- [ ] If the contribution affects [the documentation](../docs), please include your changes in this pull request.
- [ ] [Development Guidelines](https://github.com/IDSolutions/MOD_REPO/blob/main/.github/CONTRIBUTING.md) are read, understood and applied.
- [ ] Title of this PR uses our standard template `Component - Add|Fix|Improve|Change|Make|Remove {changes}`.
+
### Known Issues
+
- [ ] Issue
diff --git a/.gitignore b/.gitignore
index ced595b..65107c9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,6 +21,12 @@ target/
*.swo
*~
+# Misc
+node_modules/
+
# OS
.DS_Store
Thumbs.db
+
+# Arma
+arma/ui/map-viewer/
diff --git a/Architecture_Diagram.md b/Architecture_Diagram.md
index 686faf6..85521aa 100644
--- a/Architecture_Diagram.md
+++ b/Architecture_Diagram.md
@@ -20,7 +20,7 @@ graph TD
end
subgraph Server [ArmA 3 SERVER #40;Hot Cache#41;]
- ActorRegistry["GVAR(ActorRegistry)
In-Memory HashMap
UID -> {loadout, position, stats...}"]
+ Registry["GVAR(Registry)
In-Memory HashMap
UID -> {loadout, position, stats...}"]
SessionMgmt[Session Management
- Token Generation
- UID Resolution
- Player State]
end
@@ -105,15 +105,18 @@ sequenceDiagram
## 🚀 **Performance Characteristics**
### **Access Times**
+
- **Hot Cache (Server)**: `< 1ms` (HashMap lookup)
- **Cold Storage (Redis)**: `1-5ms` (Network + Redis)
- **Client Cache**: `< 0.1ms` (Local object access)
### **Cache Hit Ratios**
+
- **Hot Cache**: `~95%` (Active players)
- **Cold Storage**: `~5%` (New connections, cache misses)
### **Memory Usage**
+
- **Server Registry**: `~1KB per active player`
- **Client Cache**: `~500B per player object`
- **Redis**: `~2KB per player (persistent)`
@@ -125,7 +128,7 @@ flowchart TD
subgraph SessionMgmt [SERVER-SIDE #40;Session MGT#41;]
Conn[Player Connection] --> Token[Session Token Generation
#40;Generated on server#41;]
Token --> UID[UID Resolution
#40;Steam UID mapping#41;]
- UID --> State[Player State Tracking
#40;Tracked in ActorRegistry#41;]
+ UID --> State[Player State Tracking
#40;Tracked in Registry#41;]
State --> Access[Data Access Authorized
#40;Authorized via session#41;]
end
```
diff --git a/LICENSE.md b/LICENSE.md
index 659cbdc..0cb1a9b 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -6,10 +6,10 @@ PLEASE, NOTE THAT THIS SUMMARY HAS NO LEGAL EFFECT AND IS ONLY OF AN INFORMATORY
With this licence you are free to adapt (i.e. modify, rework or update) and share (i.e. copy, distribute or transmit) the material under the following conditions:
-* **Attribution** - You must attribute the material in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the material).
-* **Noncommercial** - You may not use this material for any commercial purposes.
-* **Arma Only** - You may not convert or adapt this material to be used in other games than Arma.
-* **Share Alike** - If you adapt, or build upon this material, you may distribute the resulting material only under the same license.
+- **Attribution** - You must attribute the material in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the material).
+- **Noncommercial** - You may not use this material for any commercial purposes.
+- **Arma Only** - You may not convert or adapt this material to be used in other games than Arma.
+- **Share Alike** - If you adapt, or build upon this material, you may distribute the resulting material only under the same license.
---
@@ -97,7 +97,7 @@ For the avoidance of doubt, this Section 4 supplements and does not replace Your
2. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
2. upon express reinstatement by the Licensor.
- For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
+ For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
3. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
4. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
@@ -116,4 +116,4 @@ For the avoidance of doubt, this Section 4 supplements and does not replace Your
### Bohemia Interactive Notices
1. Bohemia Interactive a.s. is not a party to this License, and makes no warranty whatsoever in connection with the Licensed Material. Bohemia Interactive a.s. will not be liable to You or any party on any legal theory for any damages whatsoever, including without limitation any general, special, incidental or consequential damages arising in connection to this license. Notwithstanding the foregoing two (2) sentences, Bohemia Interactive a.s. may elect to apply the Public License to material it publishes and in those instances it becomes the "Licensor".
-2. Except for the limited purpose of indicating to the public that the Licensed Material is shared under this Public License, Bohemia Interactive a.s. does not authorize the use by either party of the trademarks "Arma", "Bohemia Interactive" or any related trademark or logo of Arma or Bohemia Interactive without the prior written consent of Bohemia Interactive a.s.
\ No newline at end of file
+2. Except for the limited purpose of indicating to the public that the Licensed Material is shared under this Public License, Bohemia Interactive a.s. does not authorize the use by either party of the trademarks "Arma", "Bohemia Interactive" or any related trademark or logo of Arma or Bohemia Interactive without the prior written consent of Bohemia Interactive a.s.
diff --git a/README.md b/README.md
index 7d1392a..c97d5c2 100644
--- a/README.md
+++ b/README.md
@@ -33,6 +33,7 @@ graph TD
```
**Communication Flow**:
+
- **Clients** → Use events (`CBA_Events`) to communicate with server
- **Server** → Calls Rust extension via `callExtension`
- **Extension** → Manages Redis connection pool and data operations
@@ -87,12 +88,14 @@ forge/
1. Clone the repository from Gitea
2. Install HEMTT
-The latest version of HEMTT can be installed by running:
+ The latest version of HEMTT can be installed by running:
+
```cmd
winget install hemtt
```
### Coding Guidelines
+
This mod follows the same coding guidelines as the ACE3 mod, which can be found [here](https://ace3.acemod.org/wiki/development/coding-guidelines).
### Building the Extension
@@ -143,14 +146,18 @@ private _update = createHashMapFromArray [["bank", 1500]];
## Core Modules
### Models
+
Defines strict data structures with built-in validation:
+
- `Actor`: Player data (stats, inventory, position)
- `Org`: Organization/clan data (members, roles, metadata)
[Documentation](lib/models/README.md)
### Repositories
+
Manages data persistence with Redis:
+
- Hash-based storage for structured data
- Set-based storage for collections
- Generic over Redis client implementations
@@ -158,7 +165,9 @@ Manages data persistence with Redis:
[Documentation](lib/repositories/README.md)
### Services
+
Implements business logic and orchestration:
+
- Get-or-create patterns
- Data validation and transformation
- Complex workflows
@@ -166,7 +175,9 @@ Implements business logic and orchestration:
[Documentation](lib/services/README.md)
### Extension
+
Arma 3 interface layer:
+
- Command routing and parsing
- Session management
- Error handling and logging
@@ -174,7 +185,9 @@ Arma 3 interface layer:
[Documentation](arma/server/extension/README.md)
### Client Mod
+
Client-side SQF addon that provides:
+
- **UI Components**: Player interfaces for inventory, organizations, banking
- **Event Handlers**: CBA event listeners for server communication
- **Optimistic Caching**: Local data caching for instant UI updates
@@ -182,6 +195,7 @@ Client-side SQF addon that provides:
- **Input Validation**: Client-side validation before server requests
The client mod communicates with the server using **CBA Events**, ensuring:
+
- No direct extension calls from clients (security)
- Event-driven architecture for scalability
- Automatic state synchronization across all clients
@@ -190,28 +204,32 @@ The client mod communicates with the server using **CBA Events**, ensuring:
## Available Commands
### Actor Commands
-| Command | Description |
-|---------|-------------|
-| `actor:get` | Retrieve actor data by UID |
-| `actor:create` | Create a new actor |
-| `actor:update` | Update actor fields |
-| `actor:exists` | Check if actor exists |
-| `actor:delete` | Delete actor data |
+
+| Command | Description |
+| -------------- | -------------------------- |
+| `actor:get` | Retrieve actor data by UID |
+| `actor:create` | Create a new actor |
+| `actor:update` | Update actor fields |
+| `actor:exists` | Check if actor exists |
+| `actor:delete` | Delete actor data |
### Organization Commands
-| Command | Description |
-|---------|-------------|
-| `org:get` | Retrieve organization data |
-| `org:create` | Create a new organization |
-| `org:update` | Update organization fields |
-| `org:exists` | Check if organization exists |
-| `org:delete` | Delete organization |
-| `org:add_member` | Add member to organization |
+
+| Command | Description |
+| ------------------- | ------------------------------- |
+| `org:get` | Retrieve organization data |
+| `org:create` | Create a new organization |
+| `org:update` | Update organization fields |
+| `org:exists` | Check if organization exists |
+| `org:delete` | Delete organization |
+| `org:add_member` | Add member to organization |
| `org:remove_member` | Remove member from organization |
-| `org:get_members` | Get all organization members |
+| `org:get_members` | Get all organization members |
### Redis Operations
+
Direct Redis operations for advanced use cases:
+
- **Common**: Key-value operations (set, get, incr, decr, del)
- **Hash**: Structured data (hset, hget, hgetall, hdel)
- **List**: Ordered collections (lpush, rpush, lrange, lpop, rpop)
@@ -264,6 +282,7 @@ if (_response find "Error:" == 0) then {
## Logging
Logs are automatically created in `@forge_server/logs/`:
+
- `actor.log` - Actor operations
- `org.log` - Organization operations
- `redis.log` - Redis connection and operations
diff --git a/arma/client/.github/CONTRIBUTING.md b/arma/client/.github/CONTRIBUTING.md
index b7b4679..a378b46 100644
--- a/arma/client/.github/CONTRIBUTING.md
+++ b/arma/client/.github/CONTRIBUTING.md
@@ -1,12 +1,17 @@
# Contributing Setup & Guidelines
## Setting up the Development Environment
+
### 1. Clone the repository from GitHub
+
### 2. Install HEMTT
+
The latest version of HEMTT can be installed by running:
+
```cmd
winget install hemtt
```
## Coding Guidelines
+
This mod follows the same coding guidelines as the ACE3 mod, which can be found [here](https://ace3.acemod.org/wiki/development/coding-guidelines).
diff --git a/arma/client/.github/ISSUE_TEMPLATE/bug-report.md b/arma/client/.github/ISSUE_TEMPLATE/bug-report.md
index d4c384f..2e818b5 100644
--- a/arma/client/.github/ISSUE_TEMPLATE/bug-report.md
+++ b/arma/client/.github/ISSUE_TEMPLATE/bug-report.md
@@ -1,25 +1,31 @@
---
name: Bug report
about: Create a bug report to help us improve
-title: ''
+title: ""
labels: kind/bug
---
## Describe the bug
+
A clear and concise description of what the bug is.
## To reproduce
+
Steps to reproduce the behavior:
+
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
## Expected behavior
+
A clear and concise description of what you expected to happen.
## Attachments
+
If applicable, add screenshots or RPT logs to help explain your problem.
## Additional context
+
Add any other context about the problem here.
diff --git a/arma/client/.github/ISSUE_TEMPLATE/feature-request.md b/arma/client/.github/ISSUE_TEMPLATE/feature-request.md
index 709ee6c..7bd655d 100644
--- a/arma/client/.github/ISSUE_TEMPLATE/feature-request.md
+++ b/arma/client/.github/ISSUE_TEMPLATE/feature-request.md
@@ -1,15 +1,18 @@
---
name: Feature Request
about: Suggest a feature to be added
-title: ''
+title: ""
labels: kind/feature-request
---
## Describe the feature that you would like
+
A clear and concise description of the feature you'd want.
## Possible alternatives
+
Possible alternatives to your suggestion.
## Additional context
+
Add any other context about the feature here.
diff --git a/arma/client/.github/PULL_REQUEST_TEMPLATE.md b/arma/client/.github/PULL_REQUEST_TEMPLATE.md
index 6f72c35..1721684 100644
--- a/arma/client/.github/PULL_REQUEST_TEMPLATE.md
+++ b/arma/client/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,12 +1,16 @@
**When merged this pull request will:**
+
- Describe what this pull request will do
- Each change in a separate line
### Important
+
- [ ] If the contribution affects [the documentation](../docs), please include your changes in this pull request.
- [ ] [Development Guidelines](https://github.com/IDSolutions/MOD_REPO/blob/main/.github/CONTRIBUTING.md) are read, understood and applied.
- [ ] Title of this PR uses our standard template `Component - Add|Fix|Improve|Change|Make|Remove {changes}`.
+
### Known Issues
+
- [ ] Issue
diff --git a/arma/client/.github/workflows/check.yml b/arma/client/.github/workflows/check.yml
index 9d2f654..abb328f 100644
--- a/arma/client/.github/workflows/check.yml
+++ b/arma/client/.github/workflows/check.yml
@@ -12,17 +12,17 @@ jobs:
validate:
runs-on: ubuntu-latest
steps:
- - name: Checkout the source code
- uses: actions/checkout@v4
+ - name: Checkout the source code
+ uses: actions/checkout@v4
- - name: Validate Config
- run: python tools/config_style_checker.py
- - name: Check for BOM
- uses: arma-actions/bom-check@master
- with:
- path: "addons"
+ - name: Validate Config
+ run: python tools/config_style_checker.py
+ - name: Check for BOM
+ uses: arma-actions/bom-check@master
+ with:
+ path: "addons"
- - name: Setup HEMTT
- uses: arma-actions/hemtt@v1
- - name: Run HEMTT check
- run: hemtt check --pedantic
+ - name: Setup HEMTT
+ uses: arma-actions/hemtt@v1
+ - name: Run HEMTT check
+ run: hemtt check --pedantic
diff --git a/arma/client/.gitignore b/arma/client/.gitignore
index b786b16..41f642f 100644
--- a/arma/client/.gitignore
+++ b/arma/client/.gitignore
@@ -3,6 +3,7 @@ hemtt.exe
.hemtt/missions/~*
.hemttout/
releases/
+.hemttprivatekey
# Textures
Exports/
diff --git a/arma/client/LICENSE.md b/arma/client/LICENSE.md
index 659cbdc..0cb1a9b 100644
--- a/arma/client/LICENSE.md
+++ b/arma/client/LICENSE.md
@@ -6,10 +6,10 @@ PLEASE, NOTE THAT THIS SUMMARY HAS NO LEGAL EFFECT AND IS ONLY OF AN INFORMATORY
With this licence you are free to adapt (i.e. modify, rework or update) and share (i.e. copy, distribute or transmit) the material under the following conditions:
-* **Attribution** - You must attribute the material in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the material).
-* **Noncommercial** - You may not use this material for any commercial purposes.
-* **Arma Only** - You may not convert or adapt this material to be used in other games than Arma.
-* **Share Alike** - If you adapt, or build upon this material, you may distribute the resulting material only under the same license.
+- **Attribution** - You must attribute the material in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the material).
+- **Noncommercial** - You may not use this material for any commercial purposes.
+- **Arma Only** - You may not convert or adapt this material to be used in other games than Arma.
+- **Share Alike** - If you adapt, or build upon this material, you may distribute the resulting material only under the same license.
---
@@ -97,7 +97,7 @@ For the avoidance of doubt, this Section 4 supplements and does not replace Your
2. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
2. upon express reinstatement by the Licensor.
- For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
+ For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
3. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
4. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
@@ -116,4 +116,4 @@ For the avoidance of doubt, this Section 4 supplements and does not replace Your
### Bohemia Interactive Notices
1. Bohemia Interactive a.s. is not a party to this License, and makes no warranty whatsoever in connection with the Licensed Material. Bohemia Interactive a.s. will not be liable to You or any party on any legal theory for any damages whatsoever, including without limitation any general, special, incidental or consequential damages arising in connection to this license. Notwithstanding the foregoing two (2) sentences, Bohemia Interactive a.s. may elect to apply the Public License to material it publishes and in those instances it becomes the "Licensor".
-2. Except for the limited purpose of indicating to the public that the Licensed Material is shared under this Public License, Bohemia Interactive a.s. does not authorize the use by either party of the trademarks "Arma", "Bohemia Interactive" or any related trademark or logo of Arma or Bohemia Interactive without the prior written consent of Bohemia Interactive a.s.
\ No newline at end of file
+2. Except for the limited purpose of indicating to the public that the Licensed Material is shared under this Public License, Bohemia Interactive a.s. does not authorize the use by either party of the trademarks "Arma", "Bohemia Interactive" or any related trademark or logo of Arma or Bohemia Interactive without the prior written consent of Bohemia Interactive a.s.
diff --git a/arma/client/README.md b/arma/client/README.md
index f65d2bd..7d8932d 100644
--- a/arma/client/README.md
+++ b/arma/client/README.md
@@ -18,10 +18,13 @@
The project is entirely **open-source** and any contributions are welcome.
## Core Features
+
- Feature
## Contributing
+
For new contributers, see the [Contributing Setup & Guidelines](./.github/CONTRIBUTING.md).
## License
+
Forge Client is licensed under [APL-SA](./LICENSE.md).
diff --git a/arma/client/addons/actor/README.md b/arma/client/addons/actor/README.md
index 9dcb48a..e83012b 100644
--- a/arma/client/addons/actor/README.md
+++ b/arma/client/addons/actor/README.md
@@ -1,4 +1,3 @@
-forge_client_actor
-===================
+# forge_client_actor
Description for this addon
diff --git a/arma/client/addons/actor/XEH_postInitClient.sqf b/arma/client/addons/actor/XEH_postInitClient.sqf
index df53600..12c69b1 100644
--- a/arma/client/addons/actor/XEH_postInitClient.sqf
+++ b/arma/client/addons/actor/XEH_postInitClient.sqf
@@ -23,7 +23,7 @@ player addEventHandler ["Respawn", {
[SRPC(economy,onRespawn), [_unit, _corpse, _uid]] call CFUNC(serverEvent);
}];
-if (isNil QGVAR(ActorClass)) then { [] call FUNC(initActorClass); };
+if (isNil QGVAR(ActorClass)) then { call FUNC(initActorClass); };
[QGVAR(initActor), {
GVAR(ActorClass) call ["init", []];
diff --git a/arma/client/addons/actor/functions/fnc_handleUIEvents.sqf b/arma/client/addons/actor/functions/fnc_handleUIEvents.sqf
index 415a5f2..869b624 100644
--- a/arma/client/addons/actor/functions/fnc_handleUIEvents.sqf
+++ b/arma/client/addons/actor/functions/fnc_handleUIEvents.sqf
@@ -1,19 +1,25 @@
#include "..\script_component.hpp"
/*
+ * File: fnc_handleUIEvents.sqf
* Author: IDSolutions
+ * Date: 2026-01-28
+ * Last Update: 2026-02-17
+ * Public: No
+ *
+ * Description:
* Handles the UI events.
*
* Arguments:
- * None
+ * 0: [CONTROL] - The control that triggered the event
+ * 1: [BOOL] - Whether the event is from a confirm dialog
+ * 2: [STRING] - The message containing the event data
*
* Return Value:
- * None
+ * UI events handled [BOOL]
*
* Example:
- * [] call forge_client_actor_fnc_handleUIEvents;
- *
- * Public: No
+ * call forge_client_actor_fnc_handleUIEvents;
*/
params ["_control", "_isConfirmDialog", "_message"];
@@ -21,27 +27,25 @@ params ["_control", "_isConfirmDialog", "_message"];
private _alert = fromJSON _message;
private _event = _alert get "event";
private _data = _alert get "data";
-private _display = displayChild findDisplay 46;
diag_log format ["[FORGE:Client:Actor] Handling UI event: %1 with data: %2", _event, _data];
switch (_event) do {
case "actor::get::actions": { GVAR(ActorClass) call ["getNearbyActions", [_control]]; };
+ case "actor::close::menu": { closeDialog 1; };
case "actor::open::atm": { [true] spawn EFUNC(bank,openUI); };
case "actor::open::bank": { [] spawn EFUNC(bank,openUI); };
- case "actor::open::device": { hint "Device interaction is not yet implemented."; }; // TODO: Implement device interaction
- case "actor::open::garage": { hint "Garage interaction is not yet implemented."; }; // TODO: Implement garage interaction
+ case "actor::open::device": { hint "Device interaction is not yet implemented."; };
+ case "actor::open::garage": { [] spawn EFUNC(garage,openUI); };
case "actor::open::vgarage": { [] spawn EFUNC(garage,openVG); };
case "actor::open::org": { [] spawn EFUNC(org,openUI); };
- case "actor::open::locker": { hint "Locker interaction is not yet implemented."; }; // TODO: Implement locker interaction
- case "actor::open::vlocker": { ["Open", [false, FORGE_Locker_Box, player]] spawn BFUNC(arsenal) };
- // case "actor::open::phone": { [] spawn EFUNC(phone,openUI) };
- case "actor::open::phone": { hint "Phone interaction is not yet implemented."; }; // TODO: Implement phone interaction
- case "actor::open::iplayer": { hint "Player interaction is not yet implemented." }; // TODO: Implement player interaction
- case "actor::open::store": { hint "Store interaction is not yet implemented."; }; // TODO: Implement store interaction
+ case "actor::open::vlocker": { [FORGE_Locker_Box, player, false] spawn AFUNC(arsenal,openBox) };
+ case "actor::open::phone": { hint "Phone interaction is not yet implemented."; };
+ case "actor::open::iplayer": { hint "Player interaction is not yet implemented." };
+ case "actor::open::store": { [] spawn EFUNC(store,openUI); };
default { hint format ["Unhandled UI event: %1", _event]; };
};
-if (_event isNotEqualTo "actor::get::actions") then { _display closeDisplay 1; };
+if (_event isNotEqualTo "actor::get::actions") then { closeDialog 1; };
true;
diff --git a/arma/client/addons/actor/functions/fnc_initActorClass.sqf b/arma/client/addons/actor/functions/fnc_initActorClass.sqf
index 1e008cc..729b790 100644
--- a/arma/client/addons/actor/functions/fnc_initActorClass.sqf
+++ b/arma/client/addons/actor/functions/fnc_initActorClass.sqf
@@ -1,56 +1,43 @@
#include "..\script_component.hpp"
/*
+ * File: fnc_initActorClass.sqf
* Author: IDSolutions
- * Initializes the actor class.
+ * Date: 2026-01-28
+ * Last Update: 2026-02-17
+ * Public: Yes
+ *
+ * Description:
+ * Initializes the actor class for managing player data.
+ * Provides methods for saving, loading, and applying actor data.
*
* Arguments:
* None
*
* Return Value:
- * None
+ * Actor class object [HASHMAP OBJECT]
*
- * Examples:
- * [] call forge_client_actor_fnc_initActorClass
- *
- * Public: Yes
+ * Example:
+ * call forge_client_actor_fnc_initActorClass
*/
#pragma hemtt ignore_variables ["_self"]
-GVAR(ActorClass) = createHashMapObject [[
- ["#type", "IActorClass"],
- ["#create", {
+GVAR(ActorBaseClass) = compileFinal createHashMapFromArray [
+ ["#type", "ActorBaseClass"],
+ ["#create", compileFinal {
_self set ["uid", getPlayerUID player];
_self set ["actor", createHashMap];
_self set ["isLoaded", false];
_self set ["lastSave", time];
-
- private _actor = createHashMap;
- _actor set ["uid", (getPlayerUID player)];
- _actor set ["name", (name player)];
- _actor set ["loadout", [[],[],[],["U_BG_Guerrilla_6_1",[]],[],[],"H_Cap_blk_ION","",[],["ItemMap","ItemGPS","ItemRadio","ItemCompass","ItemWatch",""]]];
- _actor set ["position", (getPosASL player)];
- _actor set ["direction", (getDir player)];
- _actor set ["stance", (stance player)];
- _actor set ["rank", (rank player)];
- _actor set ["state", (lifeState player)];
- _actor set ["phone_number", ""];
- _actor set ["email", ""];
- _actor set ["organization", ""];
- _actor set ["holster", true];
-
- _self set ["actor", _actor];
}],
- ["init", {
+ ["init", compileFinal {
private _uid = _self get "uid";
- private _actor = _self get "actor";
-
- [SRPC(actor,requestInitActor), [_uid, _actor]] call CFUNC(serverEvent);
+ [SRPC(actor,requestInitActor), [_uid]] call CFUNC(serverEvent);
systemChat format ["Actor loaded for %1", (name player)];
diag_log "[FORGE:Client:Actor] Actor Class Initialized!";
}],
- ["save", {
+ ["save", compileFinal {
params [["_sync", false, [false]]];
private _uid = _self get "uid";
@@ -58,16 +45,12 @@ GVAR(ActorClass) = createHashMapObject [[
_self set ["lastSave", time];
}],
- ["sync", {
+ ["sync", compileFinal {
params [["_data", createHashMap, [createHashMap]], ["_jip", false, [false]]];
private _actor = _self get "actor";
private _isLoaded = _self get "isLoaded";
- if (_data isEqualTo createHashMap) exitWith {
- diag_log "[FORGE:Client:Actor] Empty data received for sync, skipping.";
- };
-
{
_actor set [_x, _y];
@@ -89,13 +72,13 @@ GVAR(ActorClass) = createHashMapObject [[
if !(_isLoaded) then { _self set ["isLoaded", true]; };
diag_log "[FORGE:Client:Actor] Sync completed";
}],
- ["get", {
+ ["get", compileFinal {
params [["_key", "", [""]], ["_default", nil, [[], "", 0, false, createHashMap]]];
private _actor = _self get "actor";
_actor getOrDefault [_key, _default];
}],
- ["applyPosition", {
+ ["applyPosition", compileFinal {
private _position = _self call ["get", ["position", [0, 0, 0]]];
if (GVAR(enableLoc)) then {
@@ -112,33 +95,30 @@ GVAR(ActorClass) = createHashMapObject [[
};
};
}],
- ["applyDirection", {
+ ["applyDirection", compileFinal {
private _direction = _self call ["get", ["direction", 0]];
-
if (GVAR(enableLoc)) then { player setDir _direction; };
}],
- ["applyStance", {
+ ["applyStance", compileFinal {
private _stance = _self call ["get", ["stance", "STAND"]];
-
if (GVAR(enableLoc)) then { player playAction _stance; };
}],
- ["applyRank", {
+ ["applyRank", compileFinal {
private _rank = _self call ["get", ["rank", "PRIVATE"]];
-
player setUnitRank _rank;
}],
- ["applyLoadout", {
+ ["applyLoadout", compileFinal {
private _loadout = _self call ["get", ["loadout", []]];
-
if (GVAR(enableGear) && count _loadout > 0) then { player setUnitLoadout _loadout; };
}],
- ["getNearbyActions", {
+ ["getNearbyActions", compileFinal {
params [["_control", controlNull, [controlNull]]];
private _nearbyActions = [];
{
private _storeType = _x getVariable ["storeType", ""];
+ private _isAtm = _x getVariable ["isAtm", false];
private _isBank = _x getVariable ["isBank", false];
private _isGarage = _x getVariable ["isGarage", false];
private _isLocker = _x getVariable ["isLocker", false];
@@ -147,18 +127,18 @@ GVAR(ActorClass) = createHashMapObject [[
private _isPlayer = _x isKindOf "Man" && isPlayer _x;
if (_storeType isNotEqualTo "") then { _nearbyActions pushBack ["store", _storeType]; };
+ if (_isAtm) then { _nearbyActions pushBack ["atm", true]; };
if (_isBank) then { _nearbyActions pushBack ["bank", true]; };
- if (_isLocker) then { _nearbyActions pushBack ["locker", true]; };
if (_isLocker && GVAR(enableVA)) then { _nearbyActions pushBack ["va", true]; };
if (_isGarage) then { _nearbyActions pushBack ["garage", _garageType]; };
if (_isGarage && GVAR(enableVG)) then { _nearbyActions pushBack ["vg", true]; };
if (_deviceType isNotEqualTo "") then { _nearbyActions pushBack ["device", _deviceType]; };
- if (_isPlayer) then { _nearbyActions pushBack ["player", name _x]; };
+ if (_isPlayer && { _x isNotEqualTo player }) then { _nearbyActions pushBack ["player", name _x]; };
} forEach (player nearObjects 5);
_control ctrlWebBrowserAction ["ExecJS", format ["updateAvailableActions(%1)", (toJSON _nearbyActions)]];
}]
-]];
+];
-SETVAR(player,FORGE_ActorClass,GVAR(ActorClass));
+GVAR(ActorClass) = createHashMapObject [GVAR(ActorBaseClass)];
GVAR(ActorClass)
diff --git a/arma/client/addons/actor/functions/fnc_openUI.sqf b/arma/client/addons/actor/functions/fnc_openUI.sqf
index 3517f5c..ad36acf 100644
--- a/arma/client/addons/actor/functions/fnc_openUI.sqf
+++ b/arma/client/addons/actor/functions/fnc_openUI.sqf
@@ -1,23 +1,27 @@
#include "..\script_component.hpp"
/*
+ * File: fnc_openUI.sqf
* Author: IDSolutions
+ * Date: 2026-01-28
+ * Last Update: 2026-01-30
+ * Public: No
+ *
+ * Description:
* Opens the player interaction interface.
*
* Arguments:
* None
*
* Return Value:
- * None
+ * UI opened [BOOL]
*
* Example:
- * [] call forge_client_actor_fnc_openUI;
- *
- * Public: No
+ * call forge_client_actor_fnc_openUI;
*/
-private _display = (findDisplay 46) createDisplay "RscActorMenu";
-private _ctrl = (_display displayCtrl 1001);
+private _display = createDialog ["RscActorMenu", true];
+private _ctrl = _display displayCtrl 1001;
_ctrl ctrlAddEventHandler ["JSDialog", {
params ["_control", "_isConfirmDialog", "_message"];
diff --git a/arma/client/addons/actor/ui/_site/index.html b/arma/client/addons/actor/ui/_site/index.html
index 8b482e8..381988c 100644
--- a/arma/client/addons/actor/ui/_site/index.html
+++ b/arma/client/addons/actor/ui/_site/index.html
@@ -1,70 +1,37 @@
-
-